@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/react/index.cjs
CHANGED
|
@@ -1427,6 +1427,7 @@ __export(index_exports, {
|
|
|
1427
1427
|
MEMORY_KINDS: () => MEMORY_KINDS,
|
|
1428
1428
|
MEMORY_LEVELS: () => MEMORY_LEVELS,
|
|
1429
1429
|
MemoryEntityModel: () => MemoryEntity,
|
|
1430
|
+
MemoryKeyError: () => MemoryKeyError,
|
|
1430
1431
|
MemoryLevelError: () => MemoryLevelError,
|
|
1431
1432
|
NEVER_TTL_MS: () => NEVER_TTL_MS,
|
|
1432
1433
|
NODE_BUDGET: () => NODE_BUDGET,
|
|
@@ -1441,6 +1442,7 @@ __export(index_exports, {
|
|
|
1441
1442
|
RECALL_MAX_LIMIT: () => RECALL_MAX_LIMIT,
|
|
1442
1443
|
RECALL_TOOL_NAME: () => RECALL_TOOL_NAME,
|
|
1443
1444
|
RemoteMemoryError: () => RemoteMemoryError,
|
|
1445
|
+
RemoteMemoryPartialCreateError: () => RemoteMemoryPartialCreateError,
|
|
1444
1446
|
RerankerUnavailableError: () => RerankerUnavailableError,
|
|
1445
1447
|
SDK_SCHEMA_VERSION: () => SDK_SCHEMA_VERSION,
|
|
1446
1448
|
SERVER_TOOL_DEPENDENCY_SETS: () => SERVER_TOOL_DEPENDENCY_SETS,
|
|
@@ -1534,6 +1536,7 @@ __export(index_exports, {
|
|
|
1534
1536
|
createRecallTool: () => createRecallTool,
|
|
1535
1537
|
createRemoteMemoryPersistence: () => createRemoteMemoryPersistence,
|
|
1536
1538
|
createRemoteMemoryPipeline: () => createRemoteMemoryPipeline,
|
|
1539
|
+
createRemoteMemoryStore: () => createRemoteMemoryStore,
|
|
1537
1540
|
createSavedToolOp: () => createSavedToolOp,
|
|
1538
1541
|
createServerToolsFilter: () => createServerToolsFilter,
|
|
1539
1542
|
createStockPricePreProcessor: () => createStockPricePreProcessor,
|
|
@@ -1565,6 +1568,7 @@ __export(index_exports, {
|
|
|
1565
1568
|
deleteVaultMemoryOp: () => deleteVaultMemoryOp,
|
|
1566
1569
|
dequantizeEmbedding: () => dequantizeEmbedding,
|
|
1567
1570
|
deriveKeyFromSignatureBytes: () => deriveKeyFromSignatureBytes,
|
|
1571
|
+
deriveMemoryKeyRing: () => deriveMemoryKeyRing,
|
|
1568
1572
|
eagerEmbedContent: () => eagerEmbedContent,
|
|
1569
1573
|
embedAllMessages: () => embedAllMessages,
|
|
1570
1574
|
embedMessage: () => embedMessage,
|
|
@@ -1704,6 +1708,7 @@ __export(index_exports, {
|
|
|
1704
1708
|
linkMemoryEntitiesOp: () => linkMemoryEntitiesOp,
|
|
1705
1709
|
maskScopedEmbeddingCache: () => maskScopedEmbeddingCache,
|
|
1706
1710
|
mediaToStored: () => mediaToStored,
|
|
1711
|
+
memoryCipher: () => memoryCipher,
|
|
1707
1712
|
migrateCalendarToken: () => migrateCalendarToken,
|
|
1708
1713
|
migrateDisplayResult: () => migrateDisplayResult,
|
|
1709
1714
|
migrateDriveToken: () => migrateDriveToken,
|
|
@@ -1725,6 +1730,7 @@ __export(index_exports, {
|
|
|
1725
1730
|
rankProfileCandidates: () => rankProfileCandidates,
|
|
1726
1731
|
readEncryptedFile: () => readEncryptedFile,
|
|
1727
1732
|
recall: () => recall,
|
|
1733
|
+
reencryptMemoryField: () => reencryptMemoryField,
|
|
1728
1734
|
reflect: () => reflect,
|
|
1729
1735
|
refreshCalendarToken: () => refreshCalendarToken,
|
|
1730
1736
|
refreshDriveToken: () => refreshDriveToken,
|
|
@@ -1904,9 +1910,9 @@ function createSseClient({
|
|
|
1904
1910
|
if (done) break;
|
|
1905
1911
|
buffer += value;
|
|
1906
1912
|
buffer = buffer.replace(/\r\n?/g, "\n");
|
|
1907
|
-
const
|
|
1908
|
-
buffer =
|
|
1909
|
-
for (const chunk of
|
|
1913
|
+
const chunks2 = buffer.split("\n\n");
|
|
1914
|
+
buffer = chunks2.pop() ?? "";
|
|
1915
|
+
for (const chunk of chunks2) {
|
|
1910
1916
|
const lines = chunk.split("\n");
|
|
1911
1917
|
const dataLines = [];
|
|
1912
1918
|
let eventName;
|
|
@@ -6558,14 +6564,14 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
|
|
|
6558
6564
|
});
|
|
6559
6565
|
return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
6560
6566
|
}
|
|
6561
|
-
async function updateMessageChunksOp(ctx, uniqueId,
|
|
6567
|
+
async function updateMessageChunksOp(ctx, uniqueId, chunks2, embeddingModel) {
|
|
6562
6568
|
let message;
|
|
6563
6569
|
try {
|
|
6564
6570
|
message = await ctx.messagesCollection.find(uniqueId);
|
|
6565
6571
|
} catch {
|
|
6566
6572
|
return null;
|
|
6567
6573
|
}
|
|
6568
|
-
const storedChunks =
|
|
6574
|
+
const storedChunks = chunks2.map(({ text: _text, ...rest }) => rest);
|
|
6569
6575
|
await ctx.database.write(async () => {
|
|
6570
6576
|
await message.update((msg) => {
|
|
6571
6577
|
msg._setRaw("chunks", JSON.stringify(storedChunks));
|
|
@@ -6609,12 +6615,12 @@ async function stripLegacyChunkTextOp(ctx) {
|
|
|
6609
6615
|
const messages = await ctx.messagesCollection.query(import_watermelondb2.Q.where("id", import_watermelondb2.Q.oneOf(changedIds))).fetch();
|
|
6610
6616
|
const updates = messages.flatMap((message) => {
|
|
6611
6617
|
const raw = message._raw;
|
|
6612
|
-
const
|
|
6613
|
-
if (!
|
|
6618
|
+
const chunks2 = chunksWithoutText(raw.chunks);
|
|
6619
|
+
if (!chunks2) return [];
|
|
6614
6620
|
const updatedAt = raw.updated_at;
|
|
6615
6621
|
return [
|
|
6616
6622
|
message.prepareUpdate((msg) => {
|
|
6617
|
-
msg._setRaw("chunks", JSON.stringify(
|
|
6623
|
+
msg._setRaw("chunks", JSON.stringify(chunks2));
|
|
6618
6624
|
msg._setRaw("updated_at", updatedAt);
|
|
6619
6625
|
})
|
|
6620
6626
|
];
|
|
@@ -6824,15 +6830,15 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
6824
6830
|
}
|
|
6825
6831
|
continue;
|
|
6826
6832
|
}
|
|
6827
|
-
const
|
|
6828
|
-
if (
|
|
6829
|
-
const vectors =
|
|
6833
|
+
const chunks2 = await readRawJsonField(message, "chunks", ctx.walletAddress);
|
|
6834
|
+
if (chunks2 && chunks2.length > 0) {
|
|
6835
|
+
const vectors = chunks2.map(
|
|
6830
6836
|
(chunk) => decodeChunkVector(chunk.vector, () => {
|
|
6831
6837
|
unreadableVectors++;
|
|
6832
6838
|
})
|
|
6833
6839
|
);
|
|
6834
6840
|
chunkCache?.set(message.id, { version, chunks: vectors });
|
|
6835
|
-
for (let ci = 0; ci <
|
|
6841
|
+
for (let ci = 0; ci < chunks2.length; ci++) {
|
|
6836
6842
|
const vec = vectors[ci];
|
|
6837
6843
|
if (vec.length === 0) continue;
|
|
6838
6844
|
const similarity = cosineSimilarity(queryVector, vec);
|
|
@@ -6840,7 +6846,7 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
6840
6846
|
candidates.push({
|
|
6841
6847
|
message,
|
|
6842
6848
|
similarity,
|
|
6843
|
-
chunkTextSource: { kind: "chunk", chunk:
|
|
6849
|
+
chunkTextSource: { kind: "chunk", chunk: chunks2[ci], siblings: chunks2 }
|
|
6844
6850
|
});
|
|
6845
6851
|
}
|
|
6846
6852
|
}
|
|
@@ -7020,7 +7026,7 @@ function chunkText(text12, options) {
|
|
|
7020
7026
|
];
|
|
7021
7027
|
}
|
|
7022
7028
|
const sentences = splitIntoSentences(text12);
|
|
7023
|
-
const
|
|
7029
|
+
const chunks2 = [];
|
|
7024
7030
|
let currentChunkSentences = [];
|
|
7025
7031
|
let currentChunkStart = 0;
|
|
7026
7032
|
let currentOffset = 0;
|
|
@@ -7034,7 +7040,7 @@ function chunkText(text12, options) {
|
|
|
7034
7040
|
if (sentence.length > chunkSize) {
|
|
7035
7041
|
if (currentChunkSentences.length > 0) {
|
|
7036
7042
|
const chunkText2 = currentChunkSentences.join(" ");
|
|
7037
|
-
|
|
7043
|
+
chunks2.push({
|
|
7038
7044
|
text: chunkText2,
|
|
7039
7045
|
startOffset: currentChunkStart,
|
|
7040
7046
|
endOffset: currentOffset
|
|
@@ -7045,7 +7051,7 @@ function chunkText(text12, options) {
|
|
|
7045
7051
|
const chunkEnd = Math.min(j + chunkSize, sentence.length);
|
|
7046
7052
|
const chunk = sentence.slice(j, chunkEnd);
|
|
7047
7053
|
if (chunk.length >= minChunkSize) {
|
|
7048
|
-
|
|
7054
|
+
chunks2.push({
|
|
7049
7055
|
text: chunk,
|
|
7050
7056
|
startOffset: sentenceStart + j,
|
|
7051
7057
|
endOffset: sentenceStart + chunkEnd
|
|
@@ -7059,7 +7065,7 @@ function chunkText(text12, options) {
|
|
|
7059
7065
|
const currentText = currentChunkSentences.join(" ");
|
|
7060
7066
|
const potentialLength = currentText.length + (currentText ? 1 : 0) + sentence.length;
|
|
7061
7067
|
if (potentialLength > chunkSize && currentChunkSentences.length > 0) {
|
|
7062
|
-
|
|
7068
|
+
chunks2.push({
|
|
7063
7069
|
text: currentText,
|
|
7064
7070
|
startOffset: currentChunkStart,
|
|
7065
7071
|
endOffset: currentOffset
|
|
@@ -7090,14 +7096,14 @@ function chunkText(text12, options) {
|
|
|
7090
7096
|
if (currentChunkSentences.length > 0) {
|
|
7091
7097
|
const chunkText2 = currentChunkSentences.join(" ");
|
|
7092
7098
|
if (chunkText2.length >= minChunkSize) {
|
|
7093
|
-
|
|
7099
|
+
chunks2.push({
|
|
7094
7100
|
text: chunkText2,
|
|
7095
7101
|
startOffset: currentChunkStart,
|
|
7096
7102
|
endOffset: text12.length
|
|
7097
7103
|
});
|
|
7098
7104
|
}
|
|
7099
7105
|
}
|
|
7100
|
-
if (
|
|
7106
|
+
if (chunks2.length === 0) {
|
|
7101
7107
|
const trimmedText = text12.trim();
|
|
7102
7108
|
if (trimmedText.length > 0) {
|
|
7103
7109
|
return [
|
|
@@ -7109,7 +7115,7 @@ function chunkText(text12, options) {
|
|
|
7109
7115
|
];
|
|
7110
7116
|
}
|
|
7111
7117
|
}
|
|
7112
|
-
return
|
|
7118
|
+
return chunks2;
|
|
7113
7119
|
}
|
|
7114
7120
|
function shouldChunkMessage(content, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
7115
7121
|
return content.length > chunkSize;
|
|
@@ -7328,18 +7334,18 @@ async function embedMany(texts, options, outer) {
|
|
|
7328
7334
|
outer
|
|
7329
7335
|
);
|
|
7330
7336
|
} else {
|
|
7331
|
-
const
|
|
7337
|
+
const chunks2 = [];
|
|
7332
7338
|
for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
|
|
7333
|
-
|
|
7339
|
+
chunks2.push(uncachedTexts.slice(i, i + chunkSize));
|
|
7334
7340
|
}
|
|
7335
|
-
const allEmbeddings = new Array(
|
|
7341
|
+
const allEmbeddings = new Array(chunks2.length);
|
|
7336
7342
|
let nextIndex = 0;
|
|
7337
7343
|
const worker = async () => {
|
|
7338
|
-
while (nextIndex <
|
|
7344
|
+
while (nextIndex < chunks2.length) {
|
|
7339
7345
|
if (outer?.aborted) throw outer.reason;
|
|
7340
7346
|
const idx = nextIndex++;
|
|
7341
7347
|
allEmbeddings[idx] = await generateEmbeddingsBatch(
|
|
7342
|
-
|
|
7348
|
+
chunks2[idx],
|
|
7343
7349
|
headers,
|
|
7344
7350
|
baseUrl,
|
|
7345
7351
|
embeddingModel,
|
|
@@ -7351,7 +7357,7 @@ async function embedMany(texts, options, outer) {
|
|
|
7351
7357
|
}
|
|
7352
7358
|
};
|
|
7353
7359
|
const workers = Array.from(
|
|
7354
|
-
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY,
|
|
7360
|
+
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks2.length) },
|
|
7355
7361
|
() => worker()
|
|
7356
7362
|
);
|
|
7357
7363
|
await Promise.all(workers);
|
|
@@ -14705,8 +14711,8 @@ var WatermelonChatStorageAdapter = class {
|
|
|
14705
14711
|
updateMessageEmbedding(uniqueId, vector, embeddingModel) {
|
|
14706
14712
|
return updateMessageEmbeddingOp(this.ctx, uniqueId, vector, embeddingModel);
|
|
14707
14713
|
}
|
|
14708
|
-
updateMessageChunks(uniqueId,
|
|
14709
|
-
return updateMessageChunksOp(this.ctx, uniqueId,
|
|
14714
|
+
updateMessageChunks(uniqueId, chunks2, embeddingModel) {
|
|
14715
|
+
return updateMessageChunksOp(this.ctx, uniqueId, chunks2, embeddingModel);
|
|
14710
14716
|
}
|
|
14711
14717
|
updateMessageError(uniqueId, error) {
|
|
14712
14718
|
return updateMessageErrorOp(this.ctx, uniqueId, error);
|
|
@@ -23062,6 +23068,65 @@ function createLocalMemoryStore(options) {
|
|
|
23062
23068
|
};
|
|
23063
23069
|
}
|
|
23064
23070
|
|
|
23071
|
+
// src/lib/memory/store/memoryKeys.ts
|
|
23072
|
+
var KEY_ID_DOMAIN = "anuma-private-memory-key-id-v1";
|
|
23073
|
+
var MemoryKeyError = class extends Error {
|
|
23074
|
+
constructor(message) {
|
|
23075
|
+
super(message);
|
|
23076
|
+
this.name = "MemoryKeyError";
|
|
23077
|
+
}
|
|
23078
|
+
};
|
|
23079
|
+
async function importAesKey(hex) {
|
|
23080
|
+
return crypto.subtle.importKey(
|
|
23081
|
+
"raw",
|
|
23082
|
+
hexToBytes(hex).buffer,
|
|
23083
|
+
{ name: "AES-GCM" },
|
|
23084
|
+
false,
|
|
23085
|
+
["encrypt", "decrypt"]
|
|
23086
|
+
);
|
|
23087
|
+
}
|
|
23088
|
+
async function deriveMemoryKeyRing(signatureHex) {
|
|
23089
|
+
const v3Hex = await deriveKeyFromSignatureV3(signatureHex);
|
|
23090
|
+
const digest = await crypto.subtle.digest(
|
|
23091
|
+
"SHA-256",
|
|
23092
|
+
new TextEncoder().encode(`${KEY_ID_DOMAIN}:${v3Hex}`)
|
|
23093
|
+
);
|
|
23094
|
+
const keyId = "v3:" + Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
23095
|
+
return {
|
|
23096
|
+
keyId,
|
|
23097
|
+
v3: await importAesKey(v3Hex),
|
|
23098
|
+
v2: await importAesKey(await deriveKeyFromSignature(signatureHex))
|
|
23099
|
+
};
|
|
23100
|
+
}
|
|
23101
|
+
async function decryptWith(value, rings) {
|
|
23102
|
+
const version = value.startsWith("enc:v3:") ? "v3" : "v2";
|
|
23103
|
+
for (const ring of rings) {
|
|
23104
|
+
try {
|
|
23105
|
+
return await decryptDataWithKey(value.slice(`enc:${version}:`.length), ring[version]);
|
|
23106
|
+
} catch {
|
|
23107
|
+
continue;
|
|
23108
|
+
}
|
|
23109
|
+
}
|
|
23110
|
+
throw new MemoryKeyError(`No supplied key decrypts this enc:${version} field`);
|
|
23111
|
+
}
|
|
23112
|
+
function memoryCipher(canonical) {
|
|
23113
|
+
return {
|
|
23114
|
+
encrypt: async (plaintext) => `enc:v3:${await encryptDataWithKey(plaintext, canonical.v3)}`,
|
|
23115
|
+
decrypt: async (ciphertext) => {
|
|
23116
|
+
if (!ciphertext.startsWith("enc:v3:") || !isEncrypted(ciphertext))
|
|
23117
|
+
throw new MemoryKeyError("Remote memory content must be enc:v3 ciphertext");
|
|
23118
|
+
return decryptWith(ciphertext, [canonical]);
|
|
23119
|
+
}
|
|
23120
|
+
};
|
|
23121
|
+
}
|
|
23122
|
+
async function reencryptMemoryField(value, canonical, fallbacks = []) {
|
|
23123
|
+
const { encrypt } = memoryCipher(canonical);
|
|
23124
|
+
if (!value.startsWith("enc:")) return encrypt(value);
|
|
23125
|
+
if (!isEncrypted(value))
|
|
23126
|
+
throw new MemoryKeyError("Field has an encryption prefix but an invalid payload");
|
|
23127
|
+
return encrypt(await decryptWith(value, [canonical, ...fallbacks]));
|
|
23128
|
+
}
|
|
23129
|
+
|
|
23065
23130
|
// src/lib/memory/store/remotePersistence.ts
|
|
23066
23131
|
var RemoteMemoryError = class extends Error {
|
|
23067
23132
|
constructor(message, status, code) {
|
|
@@ -23114,6 +23179,30 @@ var candidateListLimits = [
|
|
|
23114
23179
|
["memory_ids", 1e3],
|
|
23115
23180
|
["force_ids", 100]
|
|
23116
23181
|
];
|
|
23182
|
+
var queryListLimits = [
|
|
23183
|
+
["scopes", 20],
|
|
23184
|
+
["fact_types", 20],
|
|
23185
|
+
["visibility", 20],
|
|
23186
|
+
["memory_ids", 1e3],
|
|
23187
|
+
["topics", 100]
|
|
23188
|
+
];
|
|
23189
|
+
var queryFields = [
|
|
23190
|
+
"include_deleted",
|
|
23191
|
+
"include_archived",
|
|
23192
|
+
"include_quarantined",
|
|
23193
|
+
"include_superseded",
|
|
23194
|
+
"archived_only",
|
|
23195
|
+
"scopes",
|
|
23196
|
+
"fact_types",
|
|
23197
|
+
"visibility",
|
|
23198
|
+
"memory_ids",
|
|
23199
|
+
"topics",
|
|
23200
|
+
"updated_after",
|
|
23201
|
+
"order",
|
|
23202
|
+
"cursor",
|
|
23203
|
+
"limit",
|
|
23204
|
+
"include_embeddings"
|
|
23205
|
+
];
|
|
23117
23206
|
function record(value) {
|
|
23118
23207
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23119
23208
|
}
|
|
@@ -23448,6 +23537,35 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
23448
23537
|
throw new Error("Invalid nearby batch response");
|
|
23449
23538
|
return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
|
|
23450
23539
|
},
|
|
23540
|
+
query: async (queryOptions = {}) => {
|
|
23541
|
+
const { signal, ...query } = queryOptions;
|
|
23542
|
+
if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
|
|
23543
|
+
throw new Error("Page limit must be 1\u2013200");
|
|
23544
|
+
for (const [key, max] of queryListLimits) {
|
|
23545
|
+
const values = query[key];
|
|
23546
|
+
if (values && values.length > max)
|
|
23547
|
+
throw new Error(`Query ${key} accepts at most ${max} entries (got ${values.length})`);
|
|
23548
|
+
}
|
|
23549
|
+
const page = await request(
|
|
23550
|
+
"/memories/query",
|
|
23551
|
+
{
|
|
23552
|
+
method: "POST",
|
|
23553
|
+
body: JSON.stringify(
|
|
23554
|
+
Object.fromEntries(
|
|
23555
|
+
queryFields.filter((key) => query[key] !== void 0).map((key) => [key, query[key]])
|
|
23556
|
+
)
|
|
23557
|
+
)
|
|
23558
|
+
},
|
|
23559
|
+
signal
|
|
23560
|
+
);
|
|
23561
|
+
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")
|
|
23562
|
+
throw new Error("Invalid nearby private-memory page");
|
|
23563
|
+
return {
|
|
23564
|
+
...await decodeAll(page.items),
|
|
23565
|
+
...page.next_cursor !== void 0 && { next_cursor: page.next_cursor },
|
|
23566
|
+
...page.changes_cursor !== void 0 && { changes_cursor: page.changes_cursor }
|
|
23567
|
+
};
|
|
23568
|
+
},
|
|
23451
23569
|
candidateSet,
|
|
23452
23570
|
candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
|
|
23453
23571
|
};
|
|
@@ -23837,6 +23955,490 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23837
23955
|
};
|
|
23838
23956
|
}
|
|
23839
23957
|
|
|
23958
|
+
// src/lib/memory/store/remoteStore.ts
|
|
23959
|
+
var import_uuid6 = require("uuid");
|
|
23960
|
+
init_logger();
|
|
23961
|
+
function relevant(change, options) {
|
|
23962
|
+
return options.includeDeleted ? change === "membership" : change !== "embedding" || !!options.embeddings;
|
|
23963
|
+
}
|
|
23964
|
+
function safely(onChange) {
|
|
23965
|
+
try {
|
|
23966
|
+
onChange();
|
|
23967
|
+
} catch (error) {
|
|
23968
|
+
getLogger().warn("[memory/remote-store] Subscriber threw:", error);
|
|
23969
|
+
}
|
|
23970
|
+
}
|
|
23971
|
+
var MAX_BATCH = 50;
|
|
23972
|
+
var MAX_QUERY_IDS = 1e3;
|
|
23973
|
+
var MAX_QUERY_TOPICS = 100;
|
|
23974
|
+
var MAX_QUERY_FILTER = 20;
|
|
23975
|
+
var RemoteMemoryPartialCreateError = class extends Error {
|
|
23976
|
+
constructor(created, cause) {
|
|
23977
|
+
super(`createMany stored ${created.length} memories before a batch failed`);
|
|
23978
|
+
this.created = created;
|
|
23979
|
+
this.cause = cause;
|
|
23980
|
+
this.name = "RemoteMemoryPartialCreateError";
|
|
23981
|
+
}
|
|
23982
|
+
};
|
|
23983
|
+
function warnFailed(failed) {
|
|
23984
|
+
if (failed.length)
|
|
23985
|
+
getLogger().warn(
|
|
23986
|
+
`[memory/remote-store] Skipping ${failed.length} undecryptable row(s)`,
|
|
23987
|
+
failed.map((failure) => failure.memory_id)
|
|
23988
|
+
);
|
|
23989
|
+
}
|
|
23990
|
+
function bounded(filters, key) {
|
|
23991
|
+
const values = filters[key];
|
|
23992
|
+
if (!values || values.length <= MAX_QUERY_FILTER) return [filters];
|
|
23993
|
+
return chunks(values, MAX_QUERY_FILTER).map((chunk) => ({ ...filters, [key]: chunk }));
|
|
23994
|
+
}
|
|
23995
|
+
function chunks(values, size) {
|
|
23996
|
+
const out = [];
|
|
23997
|
+
for (let i = 0; i < values.length; i += size) out.push(values.slice(i, i + size));
|
|
23998
|
+
return out;
|
|
23999
|
+
}
|
|
24000
|
+
function stateFilters(options) {
|
|
24001
|
+
return {
|
|
24002
|
+
include_deleted: options.includeDeleted,
|
|
24003
|
+
include_archived: options.includeArchived,
|
|
24004
|
+
include_quarantined: options.includeQuarantined,
|
|
24005
|
+
include_superseded: options.includeSuperseded
|
|
24006
|
+
};
|
|
24007
|
+
}
|
|
24008
|
+
function hidden(memory, options) {
|
|
24009
|
+
if (memory.trust_tier === "quarantined") return true;
|
|
24010
|
+
if (options.includeDeleted) return false;
|
|
24011
|
+
return !!memory.is_deleted || memory.archived_at !== void 0 && memory.archived_at !== null || !!memory.superseded_by;
|
|
24012
|
+
}
|
|
24013
|
+
function subscriptionKey({ memory, version }, options) {
|
|
24014
|
+
if (hidden(memory, options)) return void 0;
|
|
24015
|
+
if (options.includeDeleted) return String(!!memory.is_deleted);
|
|
24016
|
+
return JSON.stringify([
|
|
24017
|
+
options.embeddings ? version : null,
|
|
24018
|
+
memory.content,
|
|
24019
|
+
memory.scope,
|
|
24020
|
+
memory.updated_at,
|
|
24021
|
+
memory.fact_type,
|
|
24022
|
+
memory.event_time_start,
|
|
24023
|
+
memory.event_time_end,
|
|
24024
|
+
memory.event_time_kind,
|
|
24025
|
+
memory.trust_tier,
|
|
24026
|
+
memory.visibility,
|
|
24027
|
+
memory.published_at,
|
|
24028
|
+
memory.geohash,
|
|
24029
|
+
memory.topics,
|
|
24030
|
+
memory.topics_user_managed,
|
|
24031
|
+
memory.media,
|
|
24032
|
+
memory.source
|
|
24033
|
+
]);
|
|
24034
|
+
}
|
|
24035
|
+
function topicInputs(topics, source) {
|
|
24036
|
+
return topics.flatMap((topic) => {
|
|
24037
|
+
const name = (typeof topic === "string" ? topic : topic.name).trim();
|
|
24038
|
+
const kind = typeof topic === "string" ? void 0 : topic.kind;
|
|
24039
|
+
return name ? [{ name, ...kind && { kind }, source }] : [];
|
|
24040
|
+
});
|
|
24041
|
+
}
|
|
24042
|
+
function mergeTopics(existing, added) {
|
|
24043
|
+
const byName = /* @__PURE__ */ new Map();
|
|
24044
|
+
for (const topic of [...existing, ...added]) {
|
|
24045
|
+
const key = normalizeEntityName(topic.name);
|
|
24046
|
+
if (!byName.has(key)) byName.set(key, topic);
|
|
24047
|
+
}
|
|
24048
|
+
return [...byName.values()];
|
|
24049
|
+
}
|
|
24050
|
+
function canonicalTopics(row) {
|
|
24051
|
+
return new Set((parseTopics(row.topics) ?? []).map((topic) => normalizeEntityName(topic.name)));
|
|
24052
|
+
}
|
|
24053
|
+
function createRemoteMemoryStore(options) {
|
|
24054
|
+
const { persistence, embeddingOptions } = options;
|
|
24055
|
+
const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
24056
|
+
const pollIntervalMs = options.pollIntervalMs ?? 6e4;
|
|
24057
|
+
const pipeline = createRemoteMemoryPipeline(options);
|
|
24058
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
24059
|
+
const seen = /* @__PURE__ */ new Map();
|
|
24060
|
+
let timer;
|
|
24061
|
+
const notify = (change, records = []) => {
|
|
24062
|
+
if (timer) for (const record2 of records) seen.set(record2.memory.memory_id, record2);
|
|
24063
|
+
for (const subscriber of [...subscribers])
|
|
24064
|
+
if (relevant(change, subscriber.options)) safely(subscriber.onChange);
|
|
24065
|
+
};
|
|
24066
|
+
const enumerate = async (filters, max = Infinity) => {
|
|
24067
|
+
const records = [];
|
|
24068
|
+
let cursor2;
|
|
24069
|
+
do {
|
|
24070
|
+
const page = await persistence.query({
|
|
24071
|
+
...filters,
|
|
24072
|
+
limit: Math.min(200, Math.max(1, max - records.length)),
|
|
24073
|
+
...cursor2 && { cursor: cursor2 }
|
|
24074
|
+
});
|
|
24075
|
+
warnFailed(page.failed);
|
|
24076
|
+
records.push(...page.items);
|
|
24077
|
+
cursor2 = page.next_cursor;
|
|
24078
|
+
} while (cursor2 && records.length < max);
|
|
24079
|
+
return records.slice(0, max);
|
|
24080
|
+
};
|
|
24081
|
+
const enumerateIds = async (ids, filters) => (await Promise.all(
|
|
24082
|
+
chunks([...new Set(ids)], MAX_QUERY_IDS).map(
|
|
24083
|
+
(memory_ids) => enumerate({ ...filters, memory_ids })
|
|
24084
|
+
)
|
|
24085
|
+
)).flat();
|
|
24086
|
+
const queues = /* @__PURE__ */ new Map();
|
|
24087
|
+
const serialized = (id, task) => {
|
|
24088
|
+
const run = (queues.get(id) ?? Promise.resolve()).then(task, task);
|
|
24089
|
+
const settled = run.catch(() => void 0);
|
|
24090
|
+
queues.set(id, settled);
|
|
24091
|
+
void settled.then(() => {
|
|
24092
|
+
if (queues.get(id) === settled) queues.delete(id);
|
|
24093
|
+
});
|
|
24094
|
+
return run;
|
|
24095
|
+
};
|
|
24096
|
+
const live = async (id) => {
|
|
24097
|
+
const record2 = await persistence.get(id);
|
|
24098
|
+
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
24099
|
+
};
|
|
24100
|
+
const mutate = async (id, change, edit) => serialized(id, async () => {
|
|
24101
|
+
const record2 = await live(id);
|
|
24102
|
+
if (!record2) return null;
|
|
24103
|
+
const next = edit(structuredClone(record2.memory));
|
|
24104
|
+
if (!next) return null;
|
|
24105
|
+
const saved = await persistence.put(next, record2);
|
|
24106
|
+
notify(change, [saved]);
|
|
24107
|
+
return saved;
|
|
24108
|
+
});
|
|
24109
|
+
const embedInBackground = ({ memory: { memory_id: id, content } }) => {
|
|
24110
|
+
generateEmbedding(content, embeddingOptions).then(
|
|
24111
|
+
(vector) => serialized(id, async () => {
|
|
24112
|
+
const current = await live(id);
|
|
24113
|
+
if (!current || current.memory.content !== content || current.memory.embedding?.length)
|
|
24114
|
+
return;
|
|
24115
|
+
const saved = await persistence.put(
|
|
24116
|
+
{ ...current.memory, embedding: storedVector(vector), embedding_model: model },
|
|
24117
|
+
current
|
|
24118
|
+
);
|
|
24119
|
+
notify("embedding", [saved]);
|
|
24120
|
+
})
|
|
24121
|
+
).catch((error) => {
|
|
24122
|
+
getLogger().warn("[memory/remote-store] Failed to embed memory:", error);
|
|
24123
|
+
});
|
|
24124
|
+
};
|
|
24125
|
+
const newRow = (input) => {
|
|
24126
|
+
const now = Date.now();
|
|
24127
|
+
const scope = input.scope ?? "private";
|
|
24128
|
+
return {
|
|
24129
|
+
memory_id: (0, import_uuid6.v7)(),
|
|
24130
|
+
content: input.content,
|
|
24131
|
+
scope,
|
|
24132
|
+
level: levelFromScope(scope),
|
|
24133
|
+
created_at: now,
|
|
24134
|
+
updated_at: now,
|
|
24135
|
+
is_deleted: false,
|
|
24136
|
+
...input.embedding !== void 0 && {
|
|
24137
|
+
embedding: storedVector(JSON.parse(input.embedding)),
|
|
24138
|
+
embedding_model: input.embeddingModel ?? model
|
|
24139
|
+
},
|
|
24140
|
+
proof_count: 1,
|
|
24141
|
+
source: "manual",
|
|
24142
|
+
...input.eventTime && {
|
|
24143
|
+
event_time_start: input.eventTime.start ?? void 0,
|
|
24144
|
+
event_time_end: input.eventTime.end ?? void 0,
|
|
24145
|
+
event_time_kind: input.eventTime.kind ?? void 0
|
|
24146
|
+
},
|
|
24147
|
+
fact_type: input.factType,
|
|
24148
|
+
geohash: input.geohash,
|
|
24149
|
+
visibility: "private",
|
|
24150
|
+
twin_opt_in: false
|
|
24151
|
+
};
|
|
24152
|
+
};
|
|
24153
|
+
const created = (records, inputs) => {
|
|
24154
|
+
records.forEach((record2, i) => {
|
|
24155
|
+
if (inputs[i].embedding === void 0) embedInBackground(record2);
|
|
24156
|
+
});
|
|
24157
|
+
notify("membership", records);
|
|
24158
|
+
return records.map((record2) => stored(record2.memory));
|
|
24159
|
+
};
|
|
24160
|
+
const asStored = (record2) => record2 ? stored(record2.memory) : null;
|
|
24161
|
+
const everyState = {
|
|
24162
|
+
include_deleted: true,
|
|
24163
|
+
include_archived: true,
|
|
24164
|
+
include_quarantined: true,
|
|
24165
|
+
include_superseded: true
|
|
24166
|
+
};
|
|
24167
|
+
const changesSince = async (cursor2, pending2) => {
|
|
24168
|
+
const records = [];
|
|
24169
|
+
const failed = /* @__PURE__ */ new Set();
|
|
24170
|
+
const collect = (page) => {
|
|
24171
|
+
warnFailed(page.failed);
|
|
24172
|
+
records.push(...page.items);
|
|
24173
|
+
for (const failure of page.failed) failed.add(failure.memory_id);
|
|
24174
|
+
};
|
|
24175
|
+
let resume = cursor2;
|
|
24176
|
+
let next;
|
|
24177
|
+
do {
|
|
24178
|
+
const page = await persistence.query({
|
|
24179
|
+
...everyState,
|
|
24180
|
+
order: "changed",
|
|
24181
|
+
limit: 200,
|
|
24182
|
+
...(next ?? resume) && { cursor: next ?? resume }
|
|
24183
|
+
});
|
|
24184
|
+
collect(page);
|
|
24185
|
+
resume = page.changes_cursor ?? resume;
|
|
24186
|
+
next = page.next_cursor;
|
|
24187
|
+
} while (next);
|
|
24188
|
+
for (const memory_ids of chunks([...pending2], MAX_QUERY_IDS)) {
|
|
24189
|
+
let retry;
|
|
24190
|
+
do {
|
|
24191
|
+
const page = await persistence.query({
|
|
24192
|
+
...everyState,
|
|
24193
|
+
memory_ids,
|
|
24194
|
+
limit: 200,
|
|
24195
|
+
...retry && { cursor: retry }
|
|
24196
|
+
});
|
|
24197
|
+
collect(page);
|
|
24198
|
+
retry = page.next_cursor;
|
|
24199
|
+
} while (retry);
|
|
24200
|
+
}
|
|
24201
|
+
return { records, resume, failed };
|
|
24202
|
+
};
|
|
24203
|
+
let generation = 0;
|
|
24204
|
+
let ready = false;
|
|
24205
|
+
let cursor;
|
|
24206
|
+
let pending = /* @__PURE__ */ new Set();
|
|
24207
|
+
let polling = false;
|
|
24208
|
+
const poll = () => {
|
|
24209
|
+
if (polling) return;
|
|
24210
|
+
polling = true;
|
|
24211
|
+
const current = generation;
|
|
24212
|
+
changesSince(cursor, pending).then(({ records, resume, failed }) => {
|
|
24213
|
+
if (current !== generation) return;
|
|
24214
|
+
const changed = /* @__PURE__ */ new Set();
|
|
24215
|
+
for (const record2 of records) {
|
|
24216
|
+
const id = record2.memory.memory_id;
|
|
24217
|
+
const previous = seen.get(id);
|
|
24218
|
+
seen.set(id, record2);
|
|
24219
|
+
if (!ready) continue;
|
|
24220
|
+
for (const subscriber of subscribers) {
|
|
24221
|
+
const before = previous && subscriptionKey(previous, subscriber.options);
|
|
24222
|
+
if (before !== subscriptionKey(record2, subscriber.options)) changed.add(subscriber);
|
|
24223
|
+
}
|
|
24224
|
+
}
|
|
24225
|
+
ready = true;
|
|
24226
|
+
cursor = resume;
|
|
24227
|
+
pending = failed;
|
|
24228
|
+
for (const subscriber of changed)
|
|
24229
|
+
if (subscribers.has(subscriber)) safely(subscriber.onChange);
|
|
24230
|
+
}).catch((error) => {
|
|
24231
|
+
getLogger().warn("[memory/remote-store] Subscription poll failed:", error);
|
|
24232
|
+
}).finally(() => {
|
|
24233
|
+
polling = false;
|
|
24234
|
+
});
|
|
24235
|
+
};
|
|
24236
|
+
return {
|
|
24237
|
+
list: async (listOptions = {}) => {
|
|
24238
|
+
const order = listOptions.since ? "updated" : "created";
|
|
24239
|
+
const filters = {
|
|
24240
|
+
...stateFilters(listOptions),
|
|
24241
|
+
include_embeddings: true,
|
|
24242
|
+
order,
|
|
24243
|
+
...listOptions.scopes?.length && { scopes: listOptions.scopes },
|
|
24244
|
+
...listOptions.factTypes?.length && { fact_types: listOptions.factTypes },
|
|
24245
|
+
...listOptions.visibility?.length && { visibility: listOptions.visibility },
|
|
24246
|
+
...listOptions.since && { updated_after: listOptions.since.getTime() }
|
|
24247
|
+
};
|
|
24248
|
+
const max = listOptions.limit && listOptions.limit > 0 ? listOptions.limit : Infinity;
|
|
24249
|
+
const variants = bounded(filters, "scopes").flatMap((f) => bounded(f, "fact_types"));
|
|
24250
|
+
if (!listOptions.memoryIds && variants.length === 1)
|
|
24251
|
+
return (await enumerate(filters, max)).map((r) => stored(r.memory));
|
|
24252
|
+
const fetched = await Promise.all(
|
|
24253
|
+
variants.map(
|
|
24254
|
+
(variant) => listOptions.memoryIds ? enumerateIds(listOptions.memoryIds, variant) : enumerate(variant, max)
|
|
24255
|
+
)
|
|
24256
|
+
);
|
|
24257
|
+
const rows = [...new Map(fetched.flat().map((r) => [r.memory.memory_id, r])).values()].map((record2) => stored(record2.memory)).sort(
|
|
24258
|
+
(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)
|
|
24259
|
+
);
|
|
24260
|
+
return rows.slice(0, max);
|
|
24261
|
+
},
|
|
24262
|
+
get: async (id) => asStored(await live(id)),
|
|
24263
|
+
listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
|
|
24264
|
+
(record2) => stored(record2.memory)
|
|
24265
|
+
),
|
|
24266
|
+
memoriesByTopics: async (names) => {
|
|
24267
|
+
const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
|
|
24268
|
+
const out = /* @__PURE__ */ new Map();
|
|
24269
|
+
const pages = await Promise.all(
|
|
24270
|
+
chunks([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
|
|
24271
|
+
);
|
|
24272
|
+
for (const { memory } of pages.flat()) {
|
|
24273
|
+
const matched = [...canonicalTopics(memory)].filter((name) => wanted.has(name));
|
|
24274
|
+
if (matched.length) out.set(memory.memory_id, new Set(matched));
|
|
24275
|
+
}
|
|
24276
|
+
return out;
|
|
24277
|
+
},
|
|
24278
|
+
topicsByMemories: async (memoryIds) => {
|
|
24279
|
+
const out = /* @__PURE__ */ new Map();
|
|
24280
|
+
for (const { memory } of await enumerateIds(memoryIds, {
|
|
24281
|
+
include_archived: true,
|
|
24282
|
+
include_superseded: true,
|
|
24283
|
+
include_quarantined: true
|
|
24284
|
+
})) {
|
|
24285
|
+
const topics = canonicalTopics(memory);
|
|
24286
|
+
if (topics.size) out.set(memory.memory_id, topics);
|
|
24287
|
+
}
|
|
24288
|
+
return out;
|
|
24289
|
+
},
|
|
24290
|
+
create: async (input) => {
|
|
24291
|
+
const record2 = await persistence.put(newRow(input), 0);
|
|
24292
|
+
return created([record2], [input])[0];
|
|
24293
|
+
},
|
|
24294
|
+
createMany: async (inputs) => {
|
|
24295
|
+
const out = [];
|
|
24296
|
+
for (const batch of chunks(inputs, MAX_BATCH)) {
|
|
24297
|
+
let records;
|
|
24298
|
+
try {
|
|
24299
|
+
records = await persistence.putMany(
|
|
24300
|
+
batch.map((input) => ({ memory: newRow(input), expectedVersion: 0 }))
|
|
24301
|
+
);
|
|
24302
|
+
} catch (error) {
|
|
24303
|
+
if (out.length === 0) throw error;
|
|
24304
|
+
throw new RemoteMemoryPartialCreateError(out, error);
|
|
24305
|
+
}
|
|
24306
|
+
out.push(...created(records, batch));
|
|
24307
|
+
}
|
|
24308
|
+
return out;
|
|
24309
|
+
},
|
|
24310
|
+
update: async (id, patch) => {
|
|
24311
|
+
const saved = await mutate(id, "edit", (memory) => {
|
|
24312
|
+
if (memory.superseded_by) return null;
|
|
24313
|
+
memory.content = patch.content;
|
|
24314
|
+
memory.updated_at = Date.now();
|
|
24315
|
+
if (patch.scope !== void 0) {
|
|
24316
|
+
memory.level = levelForScopeChange(
|
|
24317
|
+
{ level: memory.level, scope: memory.scope },
|
|
24318
|
+
patch.scope
|
|
24319
|
+
);
|
|
24320
|
+
memory.scope = patch.scope;
|
|
24321
|
+
}
|
|
24322
|
+
if (patch.factType !== void 0) memory.fact_type = patch.factType ?? void 0;
|
|
24323
|
+
if (patch.eventTime !== void 0) {
|
|
24324
|
+
memory.event_time_start = patch.eventTime?.start ?? void 0;
|
|
24325
|
+
memory.event_time_end = patch.eventTime?.end ?? void 0;
|
|
24326
|
+
memory.event_time_kind = patch.eventTime?.kind ?? void 0;
|
|
24327
|
+
}
|
|
24328
|
+
if (patch.embedding === void 0 || patch.embedding === null) {
|
|
24329
|
+
memory.embedding = [];
|
|
24330
|
+
delete memory.embedding_model;
|
|
24331
|
+
} else {
|
|
24332
|
+
memory.embedding = storedVector(JSON.parse(patch.embedding));
|
|
24333
|
+
memory.embedding_model = patch.embeddingModel ?? model;
|
|
24334
|
+
}
|
|
24335
|
+
return memory;
|
|
24336
|
+
});
|
|
24337
|
+
if (saved && patch.embedding === void 0) embedInBackground(saved);
|
|
24338
|
+
return asStored(saved);
|
|
24339
|
+
},
|
|
24340
|
+
delete: async (id) => !!await mutate(id, "membership", (memory) => ({ ...memory, is_deleted: true })),
|
|
24341
|
+
supersede: async (id, supersededById) => {
|
|
24342
|
+
if (id === supersededById) return false;
|
|
24343
|
+
const [first, second] = [id, supersededById].sort();
|
|
24344
|
+
return serialized(
|
|
24345
|
+
first,
|
|
24346
|
+
() => serialized(second, async () => {
|
|
24347
|
+
const [old, next] = await Promise.all([live(id), live(supersededById)]);
|
|
24348
|
+
if (!old || !next || old.memory.superseded_by || next.memory.superseded_by) return false;
|
|
24349
|
+
if (old.memory.kind !== void 0 && old.memory.kind !== null) return false;
|
|
24350
|
+
const saved = await persistence.putMany([
|
|
24351
|
+
{
|
|
24352
|
+
memory: { ...old.memory, superseded_by: supersededById, superseded_at: Date.now() },
|
|
24353
|
+
expectedVersion: old
|
|
24354
|
+
},
|
|
24355
|
+
{ memory: next.memory, expectedVersion: next }
|
|
24356
|
+
]);
|
|
24357
|
+
notify("membership", saved);
|
|
24358
|
+
return true;
|
|
24359
|
+
})
|
|
24360
|
+
);
|
|
24361
|
+
},
|
|
24362
|
+
archive: async (id) => !!await mutate(
|
|
24363
|
+
id,
|
|
24364
|
+
"edit",
|
|
24365
|
+
(memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
|
|
24366
|
+
),
|
|
24367
|
+
restore: (id) => serialized(id, async () => {
|
|
24368
|
+
const record2 = await live(id);
|
|
24369
|
+
if (!record2) return false;
|
|
24370
|
+
if (record2.memory.archived_at === void 0 || record2.memory.archived_at === null)
|
|
24371
|
+
return true;
|
|
24372
|
+
const { archived_at: _archivedAt, ...memory } = record2.memory;
|
|
24373
|
+
notify("edit", [await persistence.put(memory, record2)]);
|
|
24374
|
+
return true;
|
|
24375
|
+
}),
|
|
24376
|
+
setTopics: async (memoryId, topics) => asStored(
|
|
24377
|
+
await mutate(memoryId, "edit", (memory) => ({
|
|
24378
|
+
...memory,
|
|
24379
|
+
topics: serializeTopics(mergeTopics([], topicInputs(topics, "user"))),
|
|
24380
|
+
topics_user_managed: true,
|
|
24381
|
+
topics_updated_at: Date.now()
|
|
24382
|
+
}))
|
|
24383
|
+
),
|
|
24384
|
+
addTopics: async (memoryId, topics) => {
|
|
24385
|
+
const added = topicInputs(topics, "auto");
|
|
24386
|
+
const saved = await mutate(memoryId, "edit", (memory) => ({
|
|
24387
|
+
...memory,
|
|
24388
|
+
topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
|
|
24389
|
+
topics_updated_at: Date.now()
|
|
24390
|
+
}));
|
|
24391
|
+
if (!saved) return [];
|
|
24392
|
+
const now = /* @__PURE__ */ new Date();
|
|
24393
|
+
return mergeTopics([], added).map(
|
|
24394
|
+
(topic) => ({
|
|
24395
|
+
uniqueId: normalizeEntityName(topic.name),
|
|
24396
|
+
canonicalName: normalizeEntityName(topic.name),
|
|
24397
|
+
kind: topic.kind ?? null,
|
|
24398
|
+
createdAt: now,
|
|
24399
|
+
updatedAt: now
|
|
24400
|
+
})
|
|
24401
|
+
);
|
|
24402
|
+
},
|
|
24403
|
+
setVisibility: async (id, visibility, visibilityOptions) => asStored(
|
|
24404
|
+
await mutate(id, "edit", (memory) => {
|
|
24405
|
+
memory.visibility = visibility;
|
|
24406
|
+
if (visibility === "private") delete memory.published_at;
|
|
24407
|
+
else memory.published_at ?? (memory.published_at = Date.now());
|
|
24408
|
+
if (visibilityOptions?.twinOptIn !== void 0)
|
|
24409
|
+
memory.twin_opt_in = visibilityOptions.twinOptIn;
|
|
24410
|
+
return memory;
|
|
24411
|
+
})
|
|
24412
|
+
),
|
|
24413
|
+
recall: (query, recallOptions) => pipeline.recall(query, recallOptions),
|
|
24414
|
+
retain: async (content, retainOptions) => {
|
|
24415
|
+
const result = await pipeline.retain(content, retainOptions);
|
|
24416
|
+
if (result.action === "create" || result.action === "supersede") notify("membership");
|
|
24417
|
+
else if (result.action === "update" || result.action === "merge") notify("edit");
|
|
24418
|
+
return result;
|
|
24419
|
+
},
|
|
24420
|
+
subscribe: (onChange, subscribeOptions = {}) => {
|
|
24421
|
+
const subscriber = { onChange, options: subscribeOptions };
|
|
24422
|
+
subscribers.add(subscriber);
|
|
24423
|
+
if (pollIntervalMs > 0 && !timer) {
|
|
24424
|
+
timer = setInterval(poll, pollIntervalMs);
|
|
24425
|
+
poll();
|
|
24426
|
+
}
|
|
24427
|
+
return () => {
|
|
24428
|
+
subscribers.delete(subscriber);
|
|
24429
|
+
if (subscribers.size || !timer) return;
|
|
24430
|
+
clearInterval(timer);
|
|
24431
|
+
timer = void 0;
|
|
24432
|
+
generation++;
|
|
24433
|
+
seen.clear();
|
|
24434
|
+
ready = false;
|
|
24435
|
+
cursor = void 0;
|
|
24436
|
+
pending = /* @__PURE__ */ new Set();
|
|
24437
|
+
};
|
|
24438
|
+
}
|
|
24439
|
+
};
|
|
24440
|
+
}
|
|
24441
|
+
|
|
23840
24442
|
// src/lib/memory/synthesizeProfile.ts
|
|
23841
24443
|
init_internalFlowMarker();
|
|
23842
24444
|
init_logger();
|
|
@@ -37819,6 +38421,7 @@ function useWalletBinding(options = {}) {
|
|
|
37819
38421
|
MEMORY_KINDS,
|
|
37820
38422
|
MEMORY_LEVELS,
|
|
37821
38423
|
MemoryEntityModel,
|
|
38424
|
+
MemoryKeyError,
|
|
37822
38425
|
MemoryLevelError,
|
|
37823
38426
|
NEVER_TTL_MS,
|
|
37824
38427
|
NODE_BUDGET,
|
|
@@ -37833,6 +38436,7 @@ function useWalletBinding(options = {}) {
|
|
|
37833
38436
|
RECALL_MAX_LIMIT,
|
|
37834
38437
|
RECALL_TOOL_NAME,
|
|
37835
38438
|
RemoteMemoryError,
|
|
38439
|
+
RemoteMemoryPartialCreateError,
|
|
37836
38440
|
RerankerUnavailableError,
|
|
37837
38441
|
SDK_SCHEMA_VERSION,
|
|
37838
38442
|
SERVER_TOOL_DEPENDENCY_SETS,
|
|
@@ -37926,6 +38530,7 @@ function useWalletBinding(options = {}) {
|
|
|
37926
38530
|
createRecallTool,
|
|
37927
38531
|
createRemoteMemoryPersistence,
|
|
37928
38532
|
createRemoteMemoryPipeline,
|
|
38533
|
+
createRemoteMemoryStore,
|
|
37929
38534
|
createSavedToolOp,
|
|
37930
38535
|
createServerToolsFilter,
|
|
37931
38536
|
createStockPricePreProcessor,
|
|
@@ -37957,6 +38562,7 @@ function useWalletBinding(options = {}) {
|
|
|
37957
38562
|
deleteVaultMemoryOp,
|
|
37958
38563
|
dequantizeEmbedding,
|
|
37959
38564
|
deriveKeyFromSignatureBytes,
|
|
38565
|
+
deriveMemoryKeyRing,
|
|
37960
38566
|
eagerEmbedContent,
|
|
37961
38567
|
embedAllMessages,
|
|
37962
38568
|
embedMessage,
|
|
@@ -38096,6 +38702,7 @@ function useWalletBinding(options = {}) {
|
|
|
38096
38702
|
linkMemoryEntitiesOp,
|
|
38097
38703
|
maskScopedEmbeddingCache,
|
|
38098
38704
|
mediaToStored,
|
|
38705
|
+
memoryCipher,
|
|
38099
38706
|
migrateCalendarToken,
|
|
38100
38707
|
migrateDisplayResult,
|
|
38101
38708
|
migrateDriveToken,
|
|
@@ -38117,6 +38724,7 @@ function useWalletBinding(options = {}) {
|
|
|
38117
38724
|
rankProfileCandidates,
|
|
38118
38725
|
readEncryptedFile,
|
|
38119
38726
|
recall,
|
|
38727
|
+
reencryptMemoryField,
|
|
38120
38728
|
reflect,
|
|
38121
38729
|
refreshCalendarToken,
|
|
38122
38730
|
refreshDriveToken,
|