@anuma/sdk 6.34.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 +858 -52
- package/dist/expo/index.d.mts +134 -8
- package/dist/expo/index.d.ts +134 -8
- package/dist/expo/index.mjs +848 -52
- package/dist/memory/context.d.mts +21 -1
- package/dist/memory/context.d.ts +21 -1
- package/dist/react/index.cjs +848 -42
- package/dist/react/index.d.mts +134 -8
- package/dist/react/index.d.ts +134 -8
- package/dist/react/index.mjs +838 -42
- package/dist/server/index.cjs +201 -13
- package/dist/server/index.d.mts +61 -8
- package/dist/server/index.d.ts +61 -8
- package/dist/server/index.mjs +198 -13
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -1389,6 +1389,10 @@ __export(index_exports, {
|
|
|
1389
1389
|
LoggerProvider: () => LoggerProvider,
|
|
1390
1390
|
MAX_HOPS: () => MAX_HOPS,
|
|
1391
1391
|
MEDIUM_TTL_MS: () => MEDIUM_TTL_MS,
|
|
1392
|
+
MEMORY_KINDS: () => MEMORY_KINDS,
|
|
1393
|
+
MEMORY_LEVELS: () => MEMORY_LEVELS,
|
|
1394
|
+
MemoryKeyError: () => MemoryKeyError,
|
|
1395
|
+
MemoryLevelError: () => MemoryLevelError,
|
|
1392
1396
|
NEVER_TTL_MS: () => NEVER_TTL_MS,
|
|
1393
1397
|
NODE_BUDGET: () => NODE_BUDGET,
|
|
1394
1398
|
NOTION_OAUTH_CONFIG: () => NOTION_OAUTH_CONFIG,
|
|
@@ -1400,6 +1404,7 @@ __export(index_exports, {
|
|
|
1400
1404
|
RECALL_MAX_LIMIT: () => RECALL_MAX_LIMIT,
|
|
1401
1405
|
RECALL_TOOL_NAME: () => RECALL_TOOL_NAME,
|
|
1402
1406
|
RemoteMemoryError: () => RemoteMemoryError,
|
|
1407
|
+
RemoteMemoryPartialCreateError: () => RemoteMemoryPartialCreateError,
|
|
1403
1408
|
RerankerUnavailableError: () => RerankerUnavailableError,
|
|
1404
1409
|
SDK_SCHEMA_VERSION: () => SDK_SCHEMA_VERSION,
|
|
1405
1410
|
SHORT_TTL_MS: () => SHORT_TTL_MS,
|
|
@@ -1465,6 +1470,7 @@ __export(index_exports, {
|
|
|
1465
1470
|
createRecallTool: () => createRecallTool,
|
|
1466
1471
|
createRemoteMemoryPersistence: () => createRemoteMemoryPersistence,
|
|
1467
1472
|
createRemoteMemoryPipeline: () => createRemoteMemoryPipeline,
|
|
1473
|
+
createRemoteMemoryStore: () => createRemoteMemoryStore,
|
|
1468
1474
|
createStockPricePreProcessor: () => createStockPricePreProcessor,
|
|
1469
1475
|
createStreamingDeAnonymizer: () => createStreamingDeAnonymizer,
|
|
1470
1476
|
createVaultEmbeddingCache: () => createVaultEmbeddingCache,
|
|
@@ -1481,6 +1487,7 @@ __export(index_exports, {
|
|
|
1481
1487
|
deleteVaultMemoryOp: () => deleteVaultMemoryOp,
|
|
1482
1488
|
dequantizeEmbedding: () => dequantizeEmbedding,
|
|
1483
1489
|
deriveKeyFromSignatureBytes: () => deriveKeyFromSignatureBytes,
|
|
1490
|
+
deriveMemoryKeyRing: () => deriveMemoryKeyRing,
|
|
1484
1491
|
discoverNotionOAuthEndpoints: () => discoverNotionOAuthEndpoints,
|
|
1485
1492
|
eagerEmbedContent: () => eagerEmbedContent,
|
|
1486
1493
|
embedAllMessages: () => embedAllMessages,
|
|
@@ -1524,6 +1531,7 @@ __export(index_exports, {
|
|
|
1524
1531
|
isPiiRedactor: () => isPiiRedactor,
|
|
1525
1532
|
isRerankerAvailable: () => isRerankerAvailable,
|
|
1526
1533
|
maskScopedEmbeddingCache: () => maskScopedEmbeddingCache,
|
|
1534
|
+
memoryCipher: () => memoryCipher,
|
|
1527
1535
|
moveMemoriesToFolderOp: () => moveMemoriesToFolderOp,
|
|
1528
1536
|
noopLogger: () => noopLogger,
|
|
1529
1537
|
onKeyAvailable: () => onKeyAvailable,
|
|
@@ -1533,6 +1541,7 @@ __export(index_exports, {
|
|
|
1533
1541
|
queueManager: () => queueManager,
|
|
1534
1542
|
rankProfileCandidates: () => rankProfileCandidates,
|
|
1535
1543
|
recall: () => recall,
|
|
1544
|
+
reencryptMemoryField: () => reencryptMemoryField,
|
|
1536
1545
|
reflect: () => reflect,
|
|
1537
1546
|
refreshEncryptionKeyIfMatches: () => refreshEncryptionKeyIfMatches,
|
|
1538
1547
|
refreshNotionAccessToken: () => refreshNotionAccessToken,
|
|
@@ -3916,14 +3925,14 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
|
|
|
3916
3925
|
});
|
|
3917
3926
|
return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
3918
3927
|
}
|
|
3919
|
-
async function updateMessageChunksOp(ctx, uniqueId,
|
|
3928
|
+
async function updateMessageChunksOp(ctx, uniqueId, chunks2, embeddingModel) {
|
|
3920
3929
|
let message;
|
|
3921
3930
|
try {
|
|
3922
3931
|
message = await ctx.messagesCollection.find(uniqueId);
|
|
3923
3932
|
} catch {
|
|
3924
3933
|
return null;
|
|
3925
3934
|
}
|
|
3926
|
-
const storedChunks =
|
|
3935
|
+
const storedChunks = chunks2.map(({ text: _text, ...rest }) => rest);
|
|
3927
3936
|
await ctx.database.write(async () => {
|
|
3928
3937
|
await message.update((msg) => {
|
|
3929
3938
|
msg._setRaw("chunks", JSON.stringify(storedChunks));
|
|
@@ -3967,12 +3976,12 @@ async function stripLegacyChunkTextOp(ctx) {
|
|
|
3967
3976
|
const messages = await ctx.messagesCollection.query(import_watermelondb2.Q.where("id", import_watermelondb2.Q.oneOf(changedIds))).fetch();
|
|
3968
3977
|
const updates = messages.flatMap((message) => {
|
|
3969
3978
|
const raw = message._raw;
|
|
3970
|
-
const
|
|
3971
|
-
if (!
|
|
3979
|
+
const chunks2 = chunksWithoutText(raw.chunks);
|
|
3980
|
+
if (!chunks2) return [];
|
|
3972
3981
|
const updatedAt = raw.updated_at;
|
|
3973
3982
|
return [
|
|
3974
3983
|
message.prepareUpdate((msg) => {
|
|
3975
|
-
msg._setRaw("chunks", JSON.stringify(
|
|
3984
|
+
msg._setRaw("chunks", JSON.stringify(chunks2));
|
|
3976
3985
|
msg._setRaw("updated_at", updatedAt);
|
|
3977
3986
|
})
|
|
3978
3987
|
];
|
|
@@ -4133,15 +4142,15 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
4133
4142
|
}
|
|
4134
4143
|
continue;
|
|
4135
4144
|
}
|
|
4136
|
-
const
|
|
4137
|
-
if (
|
|
4138
|
-
const vectors =
|
|
4145
|
+
const chunks2 = await readRawJsonField(message, "chunks", ctx.walletAddress);
|
|
4146
|
+
if (chunks2 && chunks2.length > 0) {
|
|
4147
|
+
const vectors = chunks2.map(
|
|
4139
4148
|
(chunk) => decodeChunkVector(chunk.vector, () => {
|
|
4140
4149
|
unreadableVectors++;
|
|
4141
4150
|
})
|
|
4142
4151
|
);
|
|
4143
4152
|
chunkCache?.set(message.id, { version, chunks: vectors });
|
|
4144
|
-
for (let ci = 0; ci <
|
|
4153
|
+
for (let ci = 0; ci < chunks2.length; ci++) {
|
|
4145
4154
|
const vec = vectors[ci];
|
|
4146
4155
|
if (vec.length === 0) continue;
|
|
4147
4156
|
const similarity = cosineSimilarity(queryVector, vec);
|
|
@@ -4149,7 +4158,7 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
4149
4158
|
candidates.push({
|
|
4150
4159
|
message,
|
|
4151
4160
|
similarity,
|
|
4152
|
-
chunkTextSource: { kind: "chunk", chunk:
|
|
4161
|
+
chunkTextSource: { kind: "chunk", chunk: chunks2[ci], siblings: chunks2 }
|
|
4153
4162
|
});
|
|
4154
4163
|
}
|
|
4155
4164
|
}
|
|
@@ -4301,7 +4310,7 @@ function chunkText(text12, options) {
|
|
|
4301
4310
|
];
|
|
4302
4311
|
}
|
|
4303
4312
|
const sentences = splitIntoSentences(text12);
|
|
4304
|
-
const
|
|
4313
|
+
const chunks2 = [];
|
|
4305
4314
|
let currentChunkSentences = [];
|
|
4306
4315
|
let currentChunkStart = 0;
|
|
4307
4316
|
let currentOffset = 0;
|
|
@@ -4315,7 +4324,7 @@ function chunkText(text12, options) {
|
|
|
4315
4324
|
if (sentence.length > chunkSize) {
|
|
4316
4325
|
if (currentChunkSentences.length > 0) {
|
|
4317
4326
|
const chunkText2 = currentChunkSentences.join(" ");
|
|
4318
|
-
|
|
4327
|
+
chunks2.push({
|
|
4319
4328
|
text: chunkText2,
|
|
4320
4329
|
startOffset: currentChunkStart,
|
|
4321
4330
|
endOffset: currentOffset
|
|
@@ -4326,7 +4335,7 @@ function chunkText(text12, options) {
|
|
|
4326
4335
|
const chunkEnd = Math.min(j + chunkSize, sentence.length);
|
|
4327
4336
|
const chunk = sentence.slice(j, chunkEnd);
|
|
4328
4337
|
if (chunk.length >= minChunkSize) {
|
|
4329
|
-
|
|
4338
|
+
chunks2.push({
|
|
4330
4339
|
text: chunk,
|
|
4331
4340
|
startOffset: sentenceStart + j,
|
|
4332
4341
|
endOffset: sentenceStart + chunkEnd
|
|
@@ -4340,7 +4349,7 @@ function chunkText(text12, options) {
|
|
|
4340
4349
|
const currentText = currentChunkSentences.join(" ");
|
|
4341
4350
|
const potentialLength = currentText.length + (currentText ? 1 : 0) + sentence.length;
|
|
4342
4351
|
if (potentialLength > chunkSize && currentChunkSentences.length > 0) {
|
|
4343
|
-
|
|
4352
|
+
chunks2.push({
|
|
4344
4353
|
text: currentText,
|
|
4345
4354
|
startOffset: currentChunkStart,
|
|
4346
4355
|
endOffset: currentOffset
|
|
@@ -4371,14 +4380,14 @@ function chunkText(text12, options) {
|
|
|
4371
4380
|
if (currentChunkSentences.length > 0) {
|
|
4372
4381
|
const chunkText2 = currentChunkSentences.join(" ");
|
|
4373
4382
|
if (chunkText2.length >= minChunkSize) {
|
|
4374
|
-
|
|
4383
|
+
chunks2.push({
|
|
4375
4384
|
text: chunkText2,
|
|
4376
4385
|
startOffset: currentChunkStart,
|
|
4377
4386
|
endOffset: text12.length
|
|
4378
4387
|
});
|
|
4379
4388
|
}
|
|
4380
4389
|
}
|
|
4381
|
-
if (
|
|
4390
|
+
if (chunks2.length === 0) {
|
|
4382
4391
|
const trimmedText = text12.trim();
|
|
4383
4392
|
if (trimmedText.length > 0) {
|
|
4384
4393
|
return [
|
|
@@ -4390,7 +4399,7 @@ function chunkText(text12, options) {
|
|
|
4390
4399
|
];
|
|
4391
4400
|
}
|
|
4392
4401
|
}
|
|
4393
|
-
return
|
|
4402
|
+
return chunks2;
|
|
4394
4403
|
}
|
|
4395
4404
|
function shouldChunkMessage(content, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
4396
4405
|
return content.length > chunkSize;
|
|
@@ -4462,9 +4471,9 @@ function createSseClient({
|
|
|
4462
4471
|
if (done) break;
|
|
4463
4472
|
buffer += value;
|
|
4464
4473
|
buffer = buffer.replace(/\r\n?/g, "\n");
|
|
4465
|
-
const
|
|
4466
|
-
buffer =
|
|
4467
|
-
for (const chunk of
|
|
4474
|
+
const chunks2 = buffer.split("\n\n");
|
|
4475
|
+
buffer = chunks2.pop() ?? "";
|
|
4476
|
+
for (const chunk of chunks2) {
|
|
4468
4477
|
const lines = chunk.split("\n");
|
|
4469
4478
|
const dataLines = [];
|
|
4470
4479
|
let eventName;
|
|
@@ -5411,18 +5420,18 @@ async function embedMany(texts, options, outer) {
|
|
|
5411
5420
|
outer
|
|
5412
5421
|
);
|
|
5413
5422
|
} else {
|
|
5414
|
-
const
|
|
5423
|
+
const chunks2 = [];
|
|
5415
5424
|
for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
|
|
5416
|
-
|
|
5425
|
+
chunks2.push(uncachedTexts.slice(i, i + chunkSize));
|
|
5417
5426
|
}
|
|
5418
|
-
const allEmbeddings = new Array(
|
|
5427
|
+
const allEmbeddings = new Array(chunks2.length);
|
|
5419
5428
|
let nextIndex = 0;
|
|
5420
5429
|
const worker = async () => {
|
|
5421
|
-
while (nextIndex <
|
|
5430
|
+
while (nextIndex < chunks2.length) {
|
|
5422
5431
|
if (outer?.aborted) throw outer.reason;
|
|
5423
5432
|
const idx = nextIndex++;
|
|
5424
5433
|
allEmbeddings[idx] = await generateEmbeddingsBatch(
|
|
5425
|
-
|
|
5434
|
+
chunks2[idx],
|
|
5426
5435
|
headers,
|
|
5427
5436
|
baseUrl,
|
|
5428
5437
|
embeddingModel,
|
|
@@ -5434,7 +5443,7 @@ async function embedMany(texts, options, outer) {
|
|
|
5434
5443
|
}
|
|
5435
5444
|
};
|
|
5436
5445
|
const workers = Array.from(
|
|
5437
|
-
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY,
|
|
5446
|
+
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks2.length) },
|
|
5438
5447
|
() => worker()
|
|
5439
5448
|
);
|
|
5440
5449
|
await Promise.all(workers);
|
|
@@ -10084,7 +10093,7 @@ function sseFailureMessage(status, statusText, detail = "") {
|
|
|
10084
10093
|
return `SSE failed: ${status} ${statusText}${detail}`;
|
|
10085
10094
|
}
|
|
10086
10095
|
function parseSseChunks(raw, incompleteBuffer) {
|
|
10087
|
-
const
|
|
10096
|
+
const chunks2 = [];
|
|
10088
10097
|
const text12 = incompleteBuffer + raw;
|
|
10089
10098
|
const lines = text12.split("\n");
|
|
10090
10099
|
const remaining = raw.endsWith("\n") ? "" : lines.pop() ?? "";
|
|
@@ -10093,11 +10102,11 @@ function parseSseChunks(raw, incompleteBuffer) {
|
|
|
10093
10102
|
const data = line.substring(6).trim();
|
|
10094
10103
|
if (data === "[DONE]") continue;
|
|
10095
10104
|
try {
|
|
10096
|
-
|
|
10105
|
+
chunks2.push(JSON.parse(data));
|
|
10097
10106
|
} catch {
|
|
10098
10107
|
}
|
|
10099
10108
|
}
|
|
10100
|
-
return { chunks, remaining };
|
|
10109
|
+
return { chunks: chunks2, remaining };
|
|
10101
10110
|
}
|
|
10102
10111
|
var xhrTransport = (options) => {
|
|
10103
10112
|
const queue = [];
|
|
@@ -10166,18 +10175,18 @@ var xhrTransport = (options) => {
|
|
|
10166
10175
|
const newData = xhr.responseText.substring(lastProcessedIndex);
|
|
10167
10176
|
lastProcessedIndex = xhr.responseText.length;
|
|
10168
10177
|
if (newData.length > 0) options.onActivity?.();
|
|
10169
|
-
const { chunks, remaining } = parseSseChunks(newData, incompleteBuffer);
|
|
10178
|
+
const { chunks: chunks2, remaining } = parseSseChunks(newData, incompleteBuffer);
|
|
10170
10179
|
incompleteBuffer = remaining;
|
|
10171
|
-
for (const chunk of
|
|
10180
|
+
for (const chunk of chunks2) {
|
|
10172
10181
|
push({ type: "data", value: chunk });
|
|
10173
10182
|
}
|
|
10174
10183
|
};
|
|
10175
10184
|
xhr.onload = () => {
|
|
10176
10185
|
options.signal?.removeEventListener("abort", abortHandler);
|
|
10177
10186
|
if (incompleteBuffer) {
|
|
10178
|
-
const { chunks } = parseSseChunks(incompleteBuffer + "\n", "");
|
|
10187
|
+
const { chunks: chunks2 } = parseSseChunks(incompleteBuffer + "\n", "");
|
|
10179
10188
|
incompleteBuffer = "";
|
|
10180
|
-
for (const chunk of
|
|
10189
|
+
for (const chunk of chunks2) {
|
|
10181
10190
|
push({ type: "data", value: chunk });
|
|
10182
10191
|
}
|
|
10183
10192
|
}
|
|
@@ -10818,6 +10827,15 @@ __decorateClass([
|
|
|
10818
10827
|
__decorateClass([
|
|
10819
10828
|
(0, import_decorators6.text)("scope")
|
|
10820
10829
|
], VaultMemory.prototype, "scope", 2);
|
|
10830
|
+
__decorateClass([
|
|
10831
|
+
(0, import_decorators6.field)("kind")
|
|
10832
|
+
], VaultMemory.prototype, "kind", 2);
|
|
10833
|
+
__decorateClass([
|
|
10834
|
+
(0, import_decorators6.field)("kind_value")
|
|
10835
|
+
], VaultMemory.prototype, "kindValue", 2);
|
|
10836
|
+
__decorateClass([
|
|
10837
|
+
(0, import_decorators6.field)("level")
|
|
10838
|
+
], VaultMemory.prototype, "level", 2);
|
|
10821
10839
|
__decorateClass([
|
|
10822
10840
|
(0, import_decorators6.field)("folder_id")
|
|
10823
10841
|
], VaultMemory.prototype, "folderId", 2);
|
|
@@ -11043,7 +11061,7 @@ __decorateClass([
|
|
|
11043
11061
|
], VaultFolder.prototype, "context", 2);
|
|
11044
11062
|
|
|
11045
11063
|
// src/lib/db/schema.ts
|
|
11046
|
-
var SDK_SCHEMA_VERSION =
|
|
11064
|
+
var SDK_SCHEMA_VERSION = 48;
|
|
11047
11065
|
var sdkSchema = (0, import_watermelondb17.appSchema)({
|
|
11048
11066
|
version: SDK_SCHEMA_VERSION,
|
|
11049
11067
|
tables: [
|
|
@@ -11138,6 +11156,9 @@ var sdkSchema = (0, import_watermelondb17.appSchema)({
|
|
|
11138
11156
|
columns: [
|
|
11139
11157
|
{ name: "content", type: "string" },
|
|
11140
11158
|
{ name: "scope", type: "string", isIndexed: true },
|
|
11159
|
+
{ name: "kind", type: "string", isOptional: true, isIndexed: true },
|
|
11160
|
+
{ name: "kind_value", type: "string", isOptional: true },
|
|
11161
|
+
{ name: "level", type: "string", isOptional: true, isIndexed: true },
|
|
11141
11162
|
{ name: "folder_id", type: "string", isOptional: true, isIndexed: true },
|
|
11142
11163
|
{ name: "created_at", type: "number", isIndexed: true },
|
|
11143
11164
|
{ name: "updated_at", type: "number", isIndexed: true },
|
|
@@ -11814,6 +11835,22 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
|
|
|
11814
11835
|
]
|
|
11815
11836
|
})
|
|
11816
11837
|
]
|
|
11838
|
+
},
|
|
11839
|
+
{
|
|
11840
|
+
toVersion: 48,
|
|
11841
|
+
steps: [
|
|
11842
|
+
(0, import_migrations2.addColumns)({
|
|
11843
|
+
table: "memory_vault",
|
|
11844
|
+
columns: [
|
|
11845
|
+
{ name: "kind", type: "string", isOptional: true, isIndexed: true },
|
|
11846
|
+
{ name: "kind_value", type: "string", isOptional: true },
|
|
11847
|
+
{ name: "level", type: "string", isOptional: true, isIndexed: true }
|
|
11848
|
+
]
|
|
11849
|
+
}),
|
|
11850
|
+
(0, import_migrations2.unsafeExecuteSql)(
|
|
11851
|
+
"UPDATE memory_vault SET level = CASE WHEN scope IN ('shared', 'public') THEN 'matching' ELSE 'private' END WHERE level IS NULL;"
|
|
11852
|
+
)
|
|
11853
|
+
]
|
|
11817
11854
|
}
|
|
11818
11855
|
]
|
|
11819
11856
|
});
|
|
@@ -12381,13 +12418,54 @@ async function decryptVaultMemoryFields(memory, address, signMessage, embeddedWa
|
|
|
12381
12418
|
}
|
|
12382
12419
|
}
|
|
12383
12420
|
const decryptedContent = await decryptField(memory.content, address);
|
|
12421
|
+
const decryptedKindValue = typeof memory.kindValue === "string" ? await decryptField(memory.kindValue, address) : memory.kindValue;
|
|
12384
12422
|
return {
|
|
12385
12423
|
...memory,
|
|
12386
|
-
content: decryptedContent
|
|
12424
|
+
content: decryptedContent,
|
|
12425
|
+
...decryptedKindValue !== void 0 && { kindValue: decryptedKindValue }
|
|
12387
12426
|
};
|
|
12388
12427
|
}
|
|
12389
12428
|
|
|
12390
12429
|
// src/lib/db/memoryVault/types.ts
|
|
12430
|
+
var MEMORY_KINDS = [
|
|
12431
|
+
"display_name",
|
|
12432
|
+
"birth_date",
|
|
12433
|
+
"bio",
|
|
12434
|
+
"occupation",
|
|
12435
|
+
"interest",
|
|
12436
|
+
"gender",
|
|
12437
|
+
"height_cm",
|
|
12438
|
+
"looking_for",
|
|
12439
|
+
"politics",
|
|
12440
|
+
"religion",
|
|
12441
|
+
"ethnicity",
|
|
12442
|
+
"smoking",
|
|
12443
|
+
"drinking",
|
|
12444
|
+
"exercise",
|
|
12445
|
+
"sexuality",
|
|
12446
|
+
"prompt"
|
|
12447
|
+
];
|
|
12448
|
+
var MEMORY_LEVELS = ["private", "matching", "profile"];
|
|
12449
|
+
var MemoryLevelError = class extends Error {
|
|
12450
|
+
constructor(message) {
|
|
12451
|
+
super(message);
|
|
12452
|
+
this.name = "MemoryLevelError";
|
|
12453
|
+
}
|
|
12454
|
+
};
|
|
12455
|
+
var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
|
|
12456
|
+
function levelFromScope(scope) {
|
|
12457
|
+
return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
|
|
12458
|
+
}
|
|
12459
|
+
function scopeForLevel(level) {
|
|
12460
|
+
return level === "private" ? "private" : "shared";
|
|
12461
|
+
}
|
|
12462
|
+
function resolveMemoryLevel(level, scope) {
|
|
12463
|
+
return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
|
|
12464
|
+
}
|
|
12465
|
+
function levelForScopeChange(current, nextScope) {
|
|
12466
|
+
const implied = levelFromScope(nextScope);
|
|
12467
|
+
return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
|
|
12468
|
+
}
|
|
12391
12469
|
function parseMedia(value) {
|
|
12392
12470
|
if (typeof value !== "string" || value === "") return null;
|
|
12393
12471
|
try {
|
|
@@ -12417,6 +12495,56 @@ function visibilityConditions(requested) {
|
|
|
12417
12495
|
if (excluded.length === 0) return [];
|
|
12418
12496
|
return [import_watermelondb20.Q.or(import_watermelondb20.Q.where("visibility", null), import_watermelondb20.Q.where("visibility", import_watermelondb20.Q.notIn(excluded)))];
|
|
12419
12497
|
}
|
|
12498
|
+
function isKinded(record2) {
|
|
12499
|
+
return record2.kind !== null && record2.kind !== void 0;
|
|
12500
|
+
}
|
|
12501
|
+
function assertValidKindLevel(kind, level) {
|
|
12502
|
+
const hasKind = kind !== null && kind !== void 0;
|
|
12503
|
+
if (hasKind && !MEMORY_KINDS.includes(kind)) {
|
|
12504
|
+
throw new MemoryLevelError(`Unknown memory kind: ${kind}`);
|
|
12505
|
+
}
|
|
12506
|
+
if (level !== void 0 && !MEMORY_LEVELS.includes(level)) {
|
|
12507
|
+
throw new MemoryLevelError(`Unknown memory level: ${level}`);
|
|
12508
|
+
}
|
|
12509
|
+
if (level === "profile" && !hasKind) {
|
|
12510
|
+
throw new MemoryLevelError("Only a memory with a kind can be at level 'profile'");
|
|
12511
|
+
}
|
|
12512
|
+
}
|
|
12513
|
+
function resolveCreateLevel(opts) {
|
|
12514
|
+
if (opts.level !== void 0) return { level: opts.level, scope: scopeForLevel(opts.level) };
|
|
12515
|
+
if (opts.scope !== void 0) return { level: levelFromScope(opts.scope), scope: opts.scope };
|
|
12516
|
+
return { level: "private", scope: "private" };
|
|
12517
|
+
}
|
|
12518
|
+
async function encryptKindValue(ctx, value) {
|
|
12519
|
+
if (typeof value !== "string" || !ctx.walletAddress || !ctx.signMessage) return value;
|
|
12520
|
+
return encryptVaultMemoryContent(
|
|
12521
|
+
value,
|
|
12522
|
+
ctx.walletAddress,
|
|
12523
|
+
ctx.signMessage,
|
|
12524
|
+
ctx.embeddedWalletSigner
|
|
12525
|
+
);
|
|
12526
|
+
}
|
|
12527
|
+
function levelConditions(requested) {
|
|
12528
|
+
if (!requested?.length) return [];
|
|
12529
|
+
const published = ["shared", "public"];
|
|
12530
|
+
const wantsMatching = requested.includes("matching");
|
|
12531
|
+
const wantsPrivate = requested.includes("private");
|
|
12532
|
+
const unresolved = import_watermelondb20.Q.or(import_watermelondb20.Q.where("level", null), import_watermelondb20.Q.where("level", import_watermelondb20.Q.notIn([...MEMORY_LEVELS])));
|
|
12533
|
+
const byLevel = import_watermelondb20.Q.where("level", import_watermelondb20.Q.oneOf([...requested]));
|
|
12534
|
+
if (wantsMatching && wantsPrivate) return [import_watermelondb20.Q.or(byLevel, unresolved)];
|
|
12535
|
+
if (wantsMatching) {
|
|
12536
|
+
return [import_watermelondb20.Q.or(byLevel, import_watermelondb20.Q.and(unresolved, import_watermelondb20.Q.where("scope", import_watermelondb20.Q.oneOf(published))))];
|
|
12537
|
+
}
|
|
12538
|
+
if (wantsPrivate) {
|
|
12539
|
+
return [
|
|
12540
|
+
import_watermelondb20.Q.or(
|
|
12541
|
+
byLevel,
|
|
12542
|
+
import_watermelondb20.Q.and(unresolved, import_watermelondb20.Q.or(import_watermelondb20.Q.where("scope", null), import_watermelondb20.Q.where("scope", import_watermelondb20.Q.notIn(published))))
|
|
12543
|
+
)
|
|
12544
|
+
];
|
|
12545
|
+
}
|
|
12546
|
+
return [byLevel];
|
|
12547
|
+
}
|
|
12420
12548
|
function isOwnedByCtxUser(ctx, record2) {
|
|
12421
12549
|
return ctx.userId === void 0 || record2.userId === ctx.userId;
|
|
12422
12550
|
}
|
|
@@ -12460,6 +12588,9 @@ function vaultMemoryToStoredRaw(memory) {
|
|
|
12460
12588
|
uniqueId: memory.id,
|
|
12461
12589
|
content: memory.content,
|
|
12462
12590
|
scope: memory.scope,
|
|
12591
|
+
kind: memory.kind ?? null,
|
|
12592
|
+
kindValue: memory.kindValue ?? null,
|
|
12593
|
+
level: resolveMemoryLevel(memory.level, memory.scope),
|
|
12463
12594
|
folderId: memory.folderId ?? null,
|
|
12464
12595
|
userId: memory.userId ?? null,
|
|
12465
12596
|
embedding: memory.embedding ?? null,
|
|
@@ -12498,9 +12629,13 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
|
|
|
12498
12629
|
}
|
|
12499
12630
|
return raw;
|
|
12500
12631
|
}
|
|
12501
|
-
function populateNewVaultMemory(record2, ctx, opts, encryptedContent) {
|
|
12632
|
+
function populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue) {
|
|
12633
|
+
const { level, scope } = resolveCreateLevel(opts);
|
|
12502
12634
|
record2._setRaw("content", encryptedContent);
|
|
12503
|
-
record2._setRaw("scope",
|
|
12635
|
+
record2._setRaw("scope", scope);
|
|
12636
|
+
record2._setRaw("level", level);
|
|
12637
|
+
record2._setRaw("kind", opts.kind ?? null);
|
|
12638
|
+
record2._setRaw("kind_value", encryptedKindValue ?? null);
|
|
12504
12639
|
record2._setRaw("folder_id", opts.folderId ?? null);
|
|
12505
12640
|
record2._setRaw("user_id", ctx.userId ?? null);
|
|
12506
12641
|
record2._setRaw("is_deleted", false);
|
|
@@ -12534,6 +12669,8 @@ function populateNewVaultMemory(record2, ctx, opts, encryptedContent) {
|
|
|
12534
12669
|
}
|
|
12535
12670
|
}
|
|
12536
12671
|
async function createVaultMemoryOp(ctx, opts) {
|
|
12672
|
+
assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
|
|
12673
|
+
const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
|
|
12537
12674
|
const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
12538
12675
|
opts.content,
|
|
12539
12676
|
ctx.walletAddress,
|
|
@@ -12544,13 +12681,15 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
12544
12681
|
if (ctx.canWrite && !await ctx.canWrite())
|
|
12545
12682
|
throw new Error("Memory source is no longer eligible");
|
|
12546
12683
|
return ctx.vaultMemoryCollection.create(
|
|
12547
|
-
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent)
|
|
12684
|
+
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
|
|
12548
12685
|
);
|
|
12549
12686
|
});
|
|
12550
12687
|
return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
12551
12688
|
}
|
|
12552
12689
|
async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
12553
12690
|
if (!targetId) return { created: null, retired: false };
|
|
12691
|
+
assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
|
|
12692
|
+
const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
|
|
12554
12693
|
const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
12555
12694
|
opts.content,
|
|
12556
12695
|
ctx.walletAddress,
|
|
@@ -12567,9 +12706,10 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
12567
12706
|
} catch {
|
|
12568
12707
|
return;
|
|
12569
12708
|
}
|
|
12570
|
-
if (target.isDeleted || target.supersededBy || !isOwnedByCtxUser(ctx, target))
|
|
12709
|
+
if (target.isDeleted || target.supersededBy || isKinded(target) || !isOwnedByCtxUser(ctx, target))
|
|
12710
|
+
return;
|
|
12571
12711
|
createdRecord = await ctx.vaultMemoryCollection.create(
|
|
12572
|
-
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent)
|
|
12712
|
+
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
|
|
12573
12713
|
);
|
|
12574
12714
|
await target.update((r) => {
|
|
12575
12715
|
r._setRaw("superseded_by", createdRecord.id);
|
|
@@ -12633,6 +12773,10 @@ async function getMemoriesByEventTimeOp(ctx, windowStart, windowEnd) {
|
|
|
12633
12773
|
}
|
|
12634
12774
|
async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
12635
12775
|
if (optionsArray.length === 0) return [];
|
|
12776
|
+
for (const opts of optionsArray) assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
|
|
12777
|
+
const encryptedKindValues = await Promise.all(
|
|
12778
|
+
optionsArray.map((opts) => encryptKindValue(ctx, opts.kindValue))
|
|
12779
|
+
);
|
|
12636
12780
|
const encryptedContents = await Promise.all(
|
|
12637
12781
|
optionsArray.map(async (opts) => {
|
|
12638
12782
|
if (ctx.walletAddress && ctx.signMessage) {
|
|
@@ -12651,7 +12795,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
12651
12795
|
throw new Error("Memory source is no longer eligible");
|
|
12652
12796
|
const prepared = optionsArray.map(
|
|
12653
12797
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate(
|
|
12654
|
-
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i])
|
|
12798
|
+
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
|
|
12655
12799
|
)
|
|
12656
12800
|
);
|
|
12657
12801
|
await ctx.database.batch(...prepared);
|
|
@@ -12694,6 +12838,9 @@ function vaultMemoryRawToStoredRaw(raw) {
|
|
|
12694
12838
|
uniqueId: raw.id,
|
|
12695
12839
|
content: raw.content ?? "",
|
|
12696
12840
|
scope: raw.scope ?? "",
|
|
12841
|
+
kind: raw.kind ?? null,
|
|
12842
|
+
kindValue: raw.kind_value ?? null,
|
|
12843
|
+
level: resolveMemoryLevel(raw.level, raw.scope),
|
|
12697
12844
|
folderId: raw.folder_id ?? null,
|
|
12698
12845
|
userId: raw.user_id ?? null,
|
|
12699
12846
|
embedding: raw.embedding ?? null,
|
|
@@ -12737,6 +12884,8 @@ async function getAllVaultMemoriesOp(ctx, options) {
|
|
|
12737
12884
|
...baseVaultConditions(ctx, options),
|
|
12738
12885
|
...options?.scopes?.length ? [import_watermelondb20.Q.where("scope", import_watermelondb20.Q.oneOf(options.scopes))] : [],
|
|
12739
12886
|
...visibilityConditions(options?.visibility),
|
|
12887
|
+
...levelConditions(options?.levels),
|
|
12888
|
+
...options?.kinds?.length ? [import_watermelondb20.Q.where("kind", import_watermelondb20.Q.oneOf(options.kinds))] : [],
|
|
12740
12889
|
...options?.folderId !== void 0 ? [import_watermelondb20.Q.where("folder_id", options.folderId)] : [],
|
|
12741
12890
|
...options?.factTypes?.length ? [import_watermelondb20.Q.where("fact_type", import_watermelondb20.Q.oneOf(options.factTypes))] : [],
|
|
12742
12891
|
import_watermelondb20.Q.sortBy(options?.since ? "updated_at" : "created_at", import_watermelondb20.Q.desc),
|
|
@@ -12903,6 +13052,14 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
12903
13052
|
try {
|
|
12904
13053
|
const probe = await ctx.vaultMemoryCollection.find(id);
|
|
12905
13054
|
if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
|
|
13055
|
+
if (opts.freeFormOnly && isKinded(probe)) return null;
|
|
13056
|
+
const levelAfter = (current) => {
|
|
13057
|
+
if (opts.level !== void 0) return opts.level;
|
|
13058
|
+
if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
|
|
13059
|
+
return levelForScopeChange(current, opts.scope);
|
|
13060
|
+
};
|
|
13061
|
+
assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
|
|
13062
|
+
const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
|
|
12906
13063
|
const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
12907
13064
|
opts.content,
|
|
12908
13065
|
ctx.walletAddress,
|
|
@@ -12915,10 +13072,13 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
12915
13072
|
await ctx.database.write(async () => {
|
|
12916
13073
|
if (ctx.canWrite && !await ctx.canWrite())
|
|
12917
13074
|
throw new Error("Memory source is no longer eligible");
|
|
12918
|
-
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
|
|
13075
|
+
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
|
|
12919
13076
|
stale = true;
|
|
12920
13077
|
return;
|
|
12921
13078
|
}
|
|
13079
|
+
const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
|
|
13080
|
+
const nextLevel = levelAfter(record2);
|
|
13081
|
+
assertValidKindLevel(nextKind, nextLevel);
|
|
12922
13082
|
let observedSources = [];
|
|
12923
13083
|
let replayedObservation = false;
|
|
12924
13084
|
if (opts.observationSourceIds?.length) {
|
|
@@ -12932,8 +13092,18 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
12932
13092
|
}
|
|
12933
13093
|
await record2.update((r) => {
|
|
12934
13094
|
r._setRaw("content", encryptedContent);
|
|
12935
|
-
if (opts.
|
|
13095
|
+
if (opts.level !== void 0) {
|
|
13096
|
+
r._setRaw("level", nextLevel);
|
|
13097
|
+
r._setRaw("scope", scopeForLevel(nextLevel));
|
|
13098
|
+
} else if (opts.scope !== void 0) {
|
|
12936
13099
|
r._setRaw("scope", opts.scope);
|
|
13100
|
+
r._setRaw("level", nextLevel);
|
|
13101
|
+
}
|
|
13102
|
+
if (opts.kind !== void 0) {
|
|
13103
|
+
r._setRaw("kind", opts.kind);
|
|
13104
|
+
}
|
|
13105
|
+
if (encryptedKindValue !== void 0) {
|
|
13106
|
+
r._setRaw("kind_value", encryptedKindValue);
|
|
12937
13107
|
}
|
|
12938
13108
|
if (opts.folderId !== void 0) {
|
|
12939
13109
|
r._setRaw("folder_id", opts.folderId);
|
|
@@ -12992,7 +13162,8 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
12992
13162
|
ctx.signMessage,
|
|
12993
13163
|
ctx.embeddedWalletSigner
|
|
12994
13164
|
);
|
|
12995
|
-
} catch {
|
|
13165
|
+
} catch (err) {
|
|
13166
|
+
if (err instanceof MemoryLevelError) throw err;
|
|
12996
13167
|
return null;
|
|
12997
13168
|
}
|
|
12998
13169
|
}
|
|
@@ -13128,6 +13299,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
|
|
|
13128
13299
|
try {
|
|
13129
13300
|
const record2 = await ctx.vaultMemoryCollection.find(id);
|
|
13130
13301
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
13302
|
+
if (isKinded(record2)) return false;
|
|
13131
13303
|
let successor;
|
|
13132
13304
|
try {
|
|
13133
13305
|
successor = await ctx.vaultMemoryCollection.find(supersededById);
|
|
@@ -13428,7 +13600,10 @@ function assertVaultScopeForSweep(ctx) {
|
|
|
13428
13600
|
}
|
|
13429
13601
|
async function getDecayCandidatesRawOp(ctx) {
|
|
13430
13602
|
assertVaultScopeForSweep(ctx);
|
|
13431
|
-
const results = await ctx.vaultMemoryCollection.query(
|
|
13603
|
+
const results = await ctx.vaultMemoryCollection.query(
|
|
13604
|
+
...baseVaultConditions(ctx, { includeArchived: true, includeQuarantined: true }),
|
|
13605
|
+
import_watermelondb20.Q.where("kind", null)
|
|
13606
|
+
).unsafeFetchRaw();
|
|
13432
13607
|
return results.map((raw) => ({
|
|
13433
13608
|
uniqueId: raw.id,
|
|
13434
13609
|
factType: raw.fact_type ?? null,
|
|
@@ -13689,6 +13864,7 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
|
|
|
13689
13864
|
record2._raw.id = row.memoryId;
|
|
13690
13865
|
record2._setRaw("content", content);
|
|
13691
13866
|
record2._setRaw("scope", "shared");
|
|
13867
|
+
record2._setRaw("level", "matching");
|
|
13692
13868
|
record2._setRaw("folder_id", null);
|
|
13693
13869
|
record2._setRaw("user_id", ctx.userId ?? null);
|
|
13694
13870
|
record2._setRaw("is_deleted", false);
|
|
@@ -14098,6 +14274,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
|
|
|
14098
14274
|
for (const memory of memories) {
|
|
14099
14275
|
updates.push(
|
|
14100
14276
|
memory.prepareUpdate((r) => {
|
|
14277
|
+
r._setRaw("level", levelForScopeChange(r, opts.scope));
|
|
14101
14278
|
r._setRaw("scope", opts.scope);
|
|
14102
14279
|
})
|
|
14103
14280
|
);
|
|
@@ -14119,6 +14296,7 @@ async function deleteVaultFolderOp(ctx, id) {
|
|
|
14119
14296
|
const preparedMemories = memories.map(
|
|
14120
14297
|
(memory) => memory.prepareUpdate((r) => {
|
|
14121
14298
|
r._setRaw("folder_id", null);
|
|
14299
|
+
r._setRaw("level", levelForScopeChange(r, "private"));
|
|
14122
14300
|
r._setRaw("scope", "private");
|
|
14123
14301
|
})
|
|
14124
14302
|
);
|
|
@@ -14155,6 +14333,7 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
|
|
|
14155
14333
|
const prepared = memories.map(
|
|
14156
14334
|
(memory) => memory.prepareUpdate((r) => {
|
|
14157
14335
|
r._setRaw("folder_id", folderId);
|
|
14336
|
+
r._setRaw("level", levelForScopeChange(r, targetScope));
|
|
14158
14337
|
r._setRaw("scope", targetScope);
|
|
14159
14338
|
})
|
|
14160
14339
|
);
|
|
@@ -16484,6 +16663,7 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
16484
16663
|
includeArchived: true,
|
|
16485
16664
|
...options.folderId !== void 0 && { folderId: options.folderId }
|
|
16486
16665
|
});
|
|
16666
|
+
prepared = withoutKindedRows(prepared);
|
|
16487
16667
|
if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
|
|
16488
16668
|
throw new Error(
|
|
16489
16669
|
"retain: embeddings unavailable \u2014 refusing to auto-merge against an inert cosine lane, which would create a duplicate instead of merging into the existing memory. Retry when embeddings recover, or pass enableAutoMerge: false to force a create."
|
|
@@ -16525,6 +16705,7 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
16525
16705
|
const resurrect = resurrectFields(existing);
|
|
16526
16706
|
const updated = await ctx.persistence.update(targetId, {
|
|
16527
16707
|
content: existing.content,
|
|
16708
|
+
freeFormOnly: true,
|
|
16528
16709
|
proofCountIncrement: 1,
|
|
16529
16710
|
observationSourceIds: options.sourceChunkIds,
|
|
16530
16711
|
sourceChunkIds: mergedSourceIds,
|
|
@@ -16653,6 +16834,17 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
16653
16834
|
...consolidationDecidedCreate && { consolidation: "create" }
|
|
16654
16835
|
};
|
|
16655
16836
|
}
|
|
16837
|
+
function withoutKindedRows(prepared) {
|
|
16838
|
+
const kinded = new Set(
|
|
16839
|
+
prepared.memories.filter((m) => m.kind !== null && m.kind !== void 0).map((m) => m.uniqueId)
|
|
16840
|
+
);
|
|
16841
|
+
if (kinded.size === 0) return prepared;
|
|
16842
|
+
return {
|
|
16843
|
+
...prepared,
|
|
16844
|
+
memories: prepared.memories.filter((m) => !kinded.has(m.uniqueId)),
|
|
16845
|
+
embeddedItems: prepared.embeddedItems.filter((item) => !kinded.has(item.id))
|
|
16846
|
+
};
|
|
16847
|
+
}
|
|
16656
16848
|
function unionStrings(a, b) {
|
|
16657
16849
|
return [.../* @__PURE__ */ new Set([...a, ...b])];
|
|
16658
16850
|
}
|
|
@@ -16752,6 +16944,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
16752
16944
|
const resurrect = resurrectFields(existing);
|
|
16753
16945
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
16754
16946
|
content: existing.content,
|
|
16947
|
+
freeFormOnly: true,
|
|
16755
16948
|
proofCountIncrement: 1,
|
|
16756
16949
|
observationSourceIds: options.sourceChunkIds,
|
|
16757
16950
|
sourceChunkIds: mergedSourceIds,
|
|
@@ -16797,6 +16990,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
16797
16990
|
const resurrect = resurrectFields(existing);
|
|
16798
16991
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
16799
16992
|
content: decision.content,
|
|
16993
|
+
freeFormOnly: true,
|
|
16800
16994
|
proofCountIncrement: 1,
|
|
16801
16995
|
observationSourceIds: options.sourceChunkIds,
|
|
16802
16996
|
sourceChunkIds: mergedSourceIds,
|
|
@@ -16840,7 +17034,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
16840
17034
|
}
|
|
16841
17035
|
async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
16842
17036
|
const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
|
|
16843
|
-
if (stillExists) {
|
|
17037
|
+
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
|
|
16844
17038
|
throw new Error(`retain: merge into memory ${targetId} failed to persist`);
|
|
16845
17039
|
}
|
|
16846
17040
|
}
|
|
@@ -19503,6 +19697,65 @@ function createLocalMemoryStore(options) {
|
|
|
19503
19697
|
};
|
|
19504
19698
|
}
|
|
19505
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
|
+
|
|
19506
19759
|
// src/lib/memory/store/remotePersistence.ts
|
|
19507
19760
|
var RemoteMemoryError = class extends Error {
|
|
19508
19761
|
constructor(message, status, code) {
|
|
@@ -19555,6 +19808,30 @@ var candidateListLimits = [
|
|
|
19555
19808
|
["memory_ids", 1e3],
|
|
19556
19809
|
["force_ids", 100]
|
|
19557
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
|
+
];
|
|
19558
19835
|
function record(value) {
|
|
19559
19836
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19560
19837
|
}
|
|
@@ -19889,6 +20166,35 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
19889
20166
|
throw new Error("Invalid nearby batch response");
|
|
19890
20167
|
return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
|
|
19891
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
|
+
},
|
|
19892
20198
|
candidateSet,
|
|
19893
20199
|
candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
|
|
19894
20200
|
};
|
|
@@ -19914,6 +20220,9 @@ function sourceIds(value) {
|
|
|
19914
20220
|
return [];
|
|
19915
20221
|
}
|
|
19916
20222
|
}
|
|
20223
|
+
function isMemoryLevel(value) {
|
|
20224
|
+
return MEMORY_LEVELS.includes(value);
|
|
20225
|
+
}
|
|
19917
20226
|
function stored(row) {
|
|
19918
20227
|
return {
|
|
19919
20228
|
uniqueId: row.memory_id,
|
|
@@ -19921,6 +20230,9 @@ function stored(row) {
|
|
|
19921
20230
|
scope: row.scope,
|
|
19922
20231
|
folderId: row.folder_id ?? null,
|
|
19923
20232
|
userId: null,
|
|
20233
|
+
kind: row.kind ?? null,
|
|
20234
|
+
kindValue: row.kind_value ?? null,
|
|
20235
|
+
...isMemoryLevel(row.level) && { level: row.level },
|
|
19924
20236
|
embedding: row.embedding ? JSON.stringify(row.embedding) : null,
|
|
19925
20237
|
embeddingModel: row.embedding_model ?? null,
|
|
19926
20238
|
sourceChunkIds: row.source_chunk_ids === void 0 ? null : sourceIds(row.source_chunk_ids),
|
|
@@ -20142,7 +20454,8 @@ function createRemoteMemoryPipeline(options) {
|
|
|
20142
20454
|
create: (input) => write(createRow(input), 0),
|
|
20143
20455
|
update: async (id, patch) => {
|
|
20144
20456
|
const existing = await get(id);
|
|
20145
|
-
if (!existing
|
|
20457
|
+
if (!existing || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
|
|
20458
|
+
return null;
|
|
20146
20459
|
const snapshot = snapshots.get(id);
|
|
20147
20460
|
const memory = {
|
|
20148
20461
|
...snapshot.memory,
|
|
@@ -20271,6 +20584,490 @@ function createRemoteMemoryPipeline(options) {
|
|
|
20271
20584
|
};
|
|
20272
20585
|
}
|
|
20273
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
|
+
|
|
20274
21071
|
// src/lib/memory/synthesizeProfile.ts
|
|
20275
21072
|
init_internalFlowMarker();
|
|
20276
21073
|
init_logger();
|
|
@@ -23696,7 +24493,7 @@ function useChat(options) {
|
|
|
23696
24493
|
|
|
23697
24494
|
// src/expo/useChatStorage.ts
|
|
23698
24495
|
var import_react5 = require("react");
|
|
23699
|
-
var
|
|
24496
|
+
var import_uuid7 = require("uuid");
|
|
23700
24497
|
init_clientConfig();
|
|
23701
24498
|
|
|
23702
24499
|
// src/lib/chat/assembleMessages.ts
|
|
@@ -24359,9 +25156,9 @@ async function decryptMediaFields(media, address, signMessage, embeddedWalletSig
|
|
|
24359
25156
|
}
|
|
24360
25157
|
|
|
24361
25158
|
// src/lib/db/media/types.ts
|
|
24362
|
-
var
|
|
25159
|
+
var import_uuid6 = require("uuid");
|
|
24363
25160
|
function generateMediaId() {
|
|
24364
|
-
return `media_${(0,
|
|
25161
|
+
return `media_${(0, import_uuid6.v7)()}`;
|
|
24365
25162
|
}
|
|
24366
25163
|
|
|
24367
25164
|
// src/lib/db/media/operations.ts
|
|
@@ -25321,7 +26118,7 @@ function useChatStorage(options) {
|
|
|
25321
26118
|
};
|
|
25322
26119
|
};
|
|
25323
26120
|
pendingResumeRef.current = null;
|
|
25324
|
-
const effectiveAssistantUniqueId = assistantUniqueId ?? (resumable ? `msg_${(0,
|
|
26121
|
+
const effectiveAssistantUniqueId = assistantUniqueId ?? (resumable ? `msg_${(0, import_uuid7.v7)()}` : void 0);
|
|
25325
26122
|
const embedToolText = (text12, mask, masked, token) => {
|
|
25326
26123
|
const opts = {
|
|
25327
26124
|
getToken: token,
|
|
@@ -25839,7 +26636,7 @@ function useChatStorage(options) {
|
|
|
25839
26636
|
const detachedResult = result;
|
|
25840
26637
|
if (detachedResult.detached) {
|
|
25841
26638
|
recordToolSetTurn(database, convId, matchedToolSets);
|
|
25842
|
-
const rowId = effectiveAssistantUniqueId ?? `msg_${(0,
|
|
26639
|
+
const rowId = effectiveAssistantUniqueId ?? `msg_${(0, import_uuid7.v7)()}`;
|
|
25843
26640
|
pendingResumeRef.current = {
|
|
25844
26641
|
handle: detachedResult.resume ?? null,
|
|
25845
26642
|
convId,
|
|
@@ -26349,6 +27146,10 @@ function useChatStorage(options) {
|
|
|
26349
27146
|
LoggerProvider,
|
|
26350
27147
|
MAX_HOPS,
|
|
26351
27148
|
MEDIUM_TTL_MS,
|
|
27149
|
+
MEMORY_KINDS,
|
|
27150
|
+
MEMORY_LEVELS,
|
|
27151
|
+
MemoryKeyError,
|
|
27152
|
+
MemoryLevelError,
|
|
26352
27153
|
NEVER_TTL_MS,
|
|
26353
27154
|
NODE_BUDGET,
|
|
26354
27155
|
NOTION_OAUTH_CONFIG,
|
|
@@ -26360,6 +27161,7 @@ function useChatStorage(options) {
|
|
|
26360
27161
|
RECALL_MAX_LIMIT,
|
|
26361
27162
|
RECALL_TOOL_NAME,
|
|
26362
27163
|
RemoteMemoryError,
|
|
27164
|
+
RemoteMemoryPartialCreateError,
|
|
26363
27165
|
RerankerUnavailableError,
|
|
26364
27166
|
SDK_SCHEMA_VERSION,
|
|
26365
27167
|
SHORT_TTL_MS,
|
|
@@ -26425,6 +27227,7 @@ function useChatStorage(options) {
|
|
|
26425
27227
|
createRecallTool,
|
|
26426
27228
|
createRemoteMemoryPersistence,
|
|
26427
27229
|
createRemoteMemoryPipeline,
|
|
27230
|
+
createRemoteMemoryStore,
|
|
26428
27231
|
createStockPricePreProcessor,
|
|
26429
27232
|
createStreamingDeAnonymizer,
|
|
26430
27233
|
createVaultEmbeddingCache,
|
|
@@ -26441,6 +27244,7 @@ function useChatStorage(options) {
|
|
|
26441
27244
|
deleteVaultMemoryOp,
|
|
26442
27245
|
dequantizeEmbedding,
|
|
26443
27246
|
deriveKeyFromSignatureBytes,
|
|
27247
|
+
deriveMemoryKeyRing,
|
|
26444
27248
|
discoverNotionOAuthEndpoints,
|
|
26445
27249
|
eagerEmbedContent,
|
|
26446
27250
|
embedAllMessages,
|
|
@@ -26484,6 +27288,7 @@ function useChatStorage(options) {
|
|
|
26484
27288
|
isPiiRedactor,
|
|
26485
27289
|
isRerankerAvailable,
|
|
26486
27290
|
maskScopedEmbeddingCache,
|
|
27291
|
+
memoryCipher,
|
|
26487
27292
|
moveMemoriesToFolderOp,
|
|
26488
27293
|
noopLogger,
|
|
26489
27294
|
onKeyAvailable,
|
|
@@ -26493,6 +27298,7 @@ function useChatStorage(options) {
|
|
|
26493
27298
|
queueManager,
|
|
26494
27299
|
rankProfileCandidates,
|
|
26495
27300
|
recall,
|
|
27301
|
+
reencryptMemoryField,
|
|
26496
27302
|
reflect,
|
|
26497
27303
|
refreshEncryptionKeyIfMatches,
|
|
26498
27304
|
refreshNotionAccessToken,
|