@anuma/sdk 6.35.0 → 6.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +646 -38
- package/dist/expo/index.d.mts +74 -1
- package/dist/expo/index.d.ts +74 -1
- package/dist/expo/index.mjs +639 -38
- package/dist/react/index.cjs +636 -28
- package/dist/react/index.d.mts +74 -1
- package/dist/react/index.d.ts +74 -1
- package/dist/react/index.mjs +629 -28
- package/package.json +1 -1
package/dist/expo/index.mjs
CHANGED
|
@@ -2358,14 +2358,14 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
|
|
|
2358
2358
|
});
|
|
2359
2359
|
return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
2360
2360
|
}
|
|
2361
|
-
async function updateMessageChunksOp(ctx, uniqueId,
|
|
2361
|
+
async function updateMessageChunksOp(ctx, uniqueId, chunks2, embeddingModel) {
|
|
2362
2362
|
let message;
|
|
2363
2363
|
try {
|
|
2364
2364
|
message = await ctx.messagesCollection.find(uniqueId);
|
|
2365
2365
|
} catch {
|
|
2366
2366
|
return null;
|
|
2367
2367
|
}
|
|
2368
|
-
const storedChunks =
|
|
2368
|
+
const storedChunks = chunks2.map(({ text: _text, ...rest }) => rest);
|
|
2369
2369
|
await ctx.database.write(async () => {
|
|
2370
2370
|
await message.update((msg) => {
|
|
2371
2371
|
msg._setRaw("chunks", JSON.stringify(storedChunks));
|
|
@@ -2409,12 +2409,12 @@ async function stripLegacyChunkTextOp(ctx) {
|
|
|
2409
2409
|
const messages = await ctx.messagesCollection.query(Q.where("id", Q.oneOf(changedIds))).fetch();
|
|
2410
2410
|
const updates = messages.flatMap((message) => {
|
|
2411
2411
|
const raw = message._raw;
|
|
2412
|
-
const
|
|
2413
|
-
if (!
|
|
2412
|
+
const chunks2 = chunksWithoutText(raw.chunks);
|
|
2413
|
+
if (!chunks2) return [];
|
|
2414
2414
|
const updatedAt = raw.updated_at;
|
|
2415
2415
|
return [
|
|
2416
2416
|
message.prepareUpdate((msg) => {
|
|
2417
|
-
msg._setRaw("chunks", JSON.stringify(
|
|
2417
|
+
msg._setRaw("chunks", JSON.stringify(chunks2));
|
|
2418
2418
|
msg._setRaw("updated_at", updatedAt);
|
|
2419
2419
|
})
|
|
2420
2420
|
];
|
|
@@ -2575,15 +2575,15 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
2575
2575
|
}
|
|
2576
2576
|
continue;
|
|
2577
2577
|
}
|
|
2578
|
-
const
|
|
2579
|
-
if (
|
|
2580
|
-
const vectors =
|
|
2578
|
+
const chunks2 = await readRawJsonField(message, "chunks", ctx.walletAddress);
|
|
2579
|
+
if (chunks2 && chunks2.length > 0) {
|
|
2580
|
+
const vectors = chunks2.map(
|
|
2581
2581
|
(chunk) => decodeChunkVector(chunk.vector, () => {
|
|
2582
2582
|
unreadableVectors++;
|
|
2583
2583
|
})
|
|
2584
2584
|
);
|
|
2585
2585
|
chunkCache?.set(message.id, { version, chunks: vectors });
|
|
2586
|
-
for (let ci = 0; ci <
|
|
2586
|
+
for (let ci = 0; ci < chunks2.length; ci++) {
|
|
2587
2587
|
const vec = vectors[ci];
|
|
2588
2588
|
if (vec.length === 0) continue;
|
|
2589
2589
|
const similarity = cosineSimilarity(queryVector, vec);
|
|
@@ -2591,7 +2591,7 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
2591
2591
|
candidates.push({
|
|
2592
2592
|
message,
|
|
2593
2593
|
similarity,
|
|
2594
|
-
chunkTextSource: { kind: "chunk", chunk:
|
|
2594
|
+
chunkTextSource: { kind: "chunk", chunk: chunks2[ci], siblings: chunks2 }
|
|
2595
2595
|
});
|
|
2596
2596
|
}
|
|
2597
2597
|
}
|
|
@@ -2740,7 +2740,7 @@ function chunkText(text12, options) {
|
|
|
2740
2740
|
];
|
|
2741
2741
|
}
|
|
2742
2742
|
const sentences = splitIntoSentences(text12);
|
|
2743
|
-
const
|
|
2743
|
+
const chunks2 = [];
|
|
2744
2744
|
let currentChunkSentences = [];
|
|
2745
2745
|
let currentChunkStart = 0;
|
|
2746
2746
|
let currentOffset = 0;
|
|
@@ -2754,7 +2754,7 @@ function chunkText(text12, options) {
|
|
|
2754
2754
|
if (sentence.length > chunkSize) {
|
|
2755
2755
|
if (currentChunkSentences.length > 0) {
|
|
2756
2756
|
const chunkText2 = currentChunkSentences.join(" ");
|
|
2757
|
-
|
|
2757
|
+
chunks2.push({
|
|
2758
2758
|
text: chunkText2,
|
|
2759
2759
|
startOffset: currentChunkStart,
|
|
2760
2760
|
endOffset: currentOffset
|
|
@@ -2765,7 +2765,7 @@ function chunkText(text12, options) {
|
|
|
2765
2765
|
const chunkEnd = Math.min(j + chunkSize, sentence.length);
|
|
2766
2766
|
const chunk = sentence.slice(j, chunkEnd);
|
|
2767
2767
|
if (chunk.length >= minChunkSize) {
|
|
2768
|
-
|
|
2768
|
+
chunks2.push({
|
|
2769
2769
|
text: chunk,
|
|
2770
2770
|
startOffset: sentenceStart + j,
|
|
2771
2771
|
endOffset: sentenceStart + chunkEnd
|
|
@@ -2779,7 +2779,7 @@ function chunkText(text12, options) {
|
|
|
2779
2779
|
const currentText = currentChunkSentences.join(" ");
|
|
2780
2780
|
const potentialLength = currentText.length + (currentText ? 1 : 0) + sentence.length;
|
|
2781
2781
|
if (potentialLength > chunkSize && currentChunkSentences.length > 0) {
|
|
2782
|
-
|
|
2782
|
+
chunks2.push({
|
|
2783
2783
|
text: currentText,
|
|
2784
2784
|
startOffset: currentChunkStart,
|
|
2785
2785
|
endOffset: currentOffset
|
|
@@ -2810,14 +2810,14 @@ function chunkText(text12, options) {
|
|
|
2810
2810
|
if (currentChunkSentences.length > 0) {
|
|
2811
2811
|
const chunkText2 = currentChunkSentences.join(" ");
|
|
2812
2812
|
if (chunkText2.length >= minChunkSize) {
|
|
2813
|
-
|
|
2813
|
+
chunks2.push({
|
|
2814
2814
|
text: chunkText2,
|
|
2815
2815
|
startOffset: currentChunkStart,
|
|
2816
2816
|
endOffset: text12.length
|
|
2817
2817
|
});
|
|
2818
2818
|
}
|
|
2819
2819
|
}
|
|
2820
|
-
if (
|
|
2820
|
+
if (chunks2.length === 0) {
|
|
2821
2821
|
const trimmedText = text12.trim();
|
|
2822
2822
|
if (trimmedText.length > 0) {
|
|
2823
2823
|
return [
|
|
@@ -2829,7 +2829,7 @@ function chunkText(text12, options) {
|
|
|
2829
2829
|
];
|
|
2830
2830
|
}
|
|
2831
2831
|
}
|
|
2832
|
-
return
|
|
2832
|
+
return chunks2;
|
|
2833
2833
|
}
|
|
2834
2834
|
function shouldChunkMessage(content, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
2835
2835
|
return content.length > chunkSize;
|
|
@@ -2901,9 +2901,9 @@ function createSseClient({
|
|
|
2901
2901
|
if (done) break;
|
|
2902
2902
|
buffer += value;
|
|
2903
2903
|
buffer = buffer.replace(/\r\n?/g, "\n");
|
|
2904
|
-
const
|
|
2905
|
-
buffer =
|
|
2906
|
-
for (const chunk of
|
|
2904
|
+
const chunks2 = buffer.split("\n\n");
|
|
2905
|
+
buffer = chunks2.pop() ?? "";
|
|
2906
|
+
for (const chunk of chunks2) {
|
|
2907
2907
|
const lines = chunk.split("\n");
|
|
2908
2908
|
const dataLines = [];
|
|
2909
2909
|
let eventName;
|
|
@@ -3848,18 +3848,18 @@ async function embedMany(texts, options, outer) {
|
|
|
3848
3848
|
outer
|
|
3849
3849
|
);
|
|
3850
3850
|
} else {
|
|
3851
|
-
const
|
|
3851
|
+
const chunks2 = [];
|
|
3852
3852
|
for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
|
|
3853
|
-
|
|
3853
|
+
chunks2.push(uncachedTexts.slice(i, i + chunkSize));
|
|
3854
3854
|
}
|
|
3855
|
-
const allEmbeddings = new Array(
|
|
3855
|
+
const allEmbeddings = new Array(chunks2.length);
|
|
3856
3856
|
let nextIndex = 0;
|
|
3857
3857
|
const worker = async () => {
|
|
3858
|
-
while (nextIndex <
|
|
3858
|
+
while (nextIndex < chunks2.length) {
|
|
3859
3859
|
if (outer?.aborted) throw outer.reason;
|
|
3860
3860
|
const idx = nextIndex++;
|
|
3861
3861
|
allEmbeddings[idx] = await generateEmbeddingsBatch(
|
|
3862
|
-
|
|
3862
|
+
chunks2[idx],
|
|
3863
3863
|
headers,
|
|
3864
3864
|
baseUrl,
|
|
3865
3865
|
embeddingModel,
|
|
@@ -3871,7 +3871,7 @@ async function embedMany(texts, options, outer) {
|
|
|
3871
3871
|
}
|
|
3872
3872
|
};
|
|
3873
3873
|
const workers = Array.from(
|
|
3874
|
-
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY,
|
|
3874
|
+
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks2.length) },
|
|
3875
3875
|
() => worker()
|
|
3876
3876
|
);
|
|
3877
3877
|
await Promise.all(workers);
|
|
@@ -8507,7 +8507,7 @@ function sseFailureMessage(status, statusText, detail = "") {
|
|
|
8507
8507
|
return `SSE failed: ${status} ${statusText}${detail}`;
|
|
8508
8508
|
}
|
|
8509
8509
|
function parseSseChunks(raw, incompleteBuffer) {
|
|
8510
|
-
const
|
|
8510
|
+
const chunks2 = [];
|
|
8511
8511
|
const text12 = incompleteBuffer + raw;
|
|
8512
8512
|
const lines = text12.split("\n");
|
|
8513
8513
|
const remaining = raw.endsWith("\n") ? "" : lines.pop() ?? "";
|
|
@@ -8516,11 +8516,11 @@ function parseSseChunks(raw, incompleteBuffer) {
|
|
|
8516
8516
|
const data = line.substring(6).trim();
|
|
8517
8517
|
if (data === "[DONE]") continue;
|
|
8518
8518
|
try {
|
|
8519
|
-
|
|
8519
|
+
chunks2.push(JSON.parse(data));
|
|
8520
8520
|
} catch {
|
|
8521
8521
|
}
|
|
8522
8522
|
}
|
|
8523
|
-
return { chunks, remaining };
|
|
8523
|
+
return { chunks: chunks2, remaining };
|
|
8524
8524
|
}
|
|
8525
8525
|
var xhrTransport = (options) => {
|
|
8526
8526
|
const queue = [];
|
|
@@ -8589,18 +8589,18 @@ var xhrTransport = (options) => {
|
|
|
8589
8589
|
const newData = xhr.responseText.substring(lastProcessedIndex);
|
|
8590
8590
|
lastProcessedIndex = xhr.responseText.length;
|
|
8591
8591
|
if (newData.length > 0) options.onActivity?.();
|
|
8592
|
-
const { chunks, remaining } = parseSseChunks(newData, incompleteBuffer);
|
|
8592
|
+
const { chunks: chunks2, remaining } = parseSseChunks(newData, incompleteBuffer);
|
|
8593
8593
|
incompleteBuffer = remaining;
|
|
8594
|
-
for (const chunk of
|
|
8594
|
+
for (const chunk of chunks2) {
|
|
8595
8595
|
push({ type: "data", value: chunk });
|
|
8596
8596
|
}
|
|
8597
8597
|
};
|
|
8598
8598
|
xhr.onload = () => {
|
|
8599
8599
|
options.signal?.removeEventListener("abort", abortHandler);
|
|
8600
8600
|
if (incompleteBuffer) {
|
|
8601
|
-
const { chunks } = parseSseChunks(incompleteBuffer + "\n", "");
|
|
8601
|
+
const { chunks: chunks2 } = parseSseChunks(incompleteBuffer + "\n", "");
|
|
8602
8602
|
incompleteBuffer = "";
|
|
8603
|
-
for (const chunk of
|
|
8603
|
+
for (const chunk of chunks2) {
|
|
8604
8604
|
push({ type: "data", value: chunk });
|
|
8605
8605
|
}
|
|
8606
8606
|
}
|
|
@@ -18069,6 +18069,65 @@ function createLocalMemoryStore(options) {
|
|
|
18069
18069
|
};
|
|
18070
18070
|
}
|
|
18071
18071
|
|
|
18072
|
+
// src/lib/memory/store/memoryKeys.ts
|
|
18073
|
+
var KEY_ID_DOMAIN = "anuma-private-memory-key-id-v1";
|
|
18074
|
+
var MemoryKeyError = class extends Error {
|
|
18075
|
+
constructor(message) {
|
|
18076
|
+
super(message);
|
|
18077
|
+
this.name = "MemoryKeyError";
|
|
18078
|
+
}
|
|
18079
|
+
};
|
|
18080
|
+
async function importAesKey(hex) {
|
|
18081
|
+
return crypto.subtle.importKey(
|
|
18082
|
+
"raw",
|
|
18083
|
+
hexToBytes(hex).buffer,
|
|
18084
|
+
{ name: "AES-GCM" },
|
|
18085
|
+
false,
|
|
18086
|
+
["encrypt", "decrypt"]
|
|
18087
|
+
);
|
|
18088
|
+
}
|
|
18089
|
+
async function deriveMemoryKeyRing(signatureHex) {
|
|
18090
|
+
const v3Hex = await deriveKeyFromSignatureV3(signatureHex);
|
|
18091
|
+
const digest = await crypto.subtle.digest(
|
|
18092
|
+
"SHA-256",
|
|
18093
|
+
new TextEncoder().encode(`${KEY_ID_DOMAIN}:${v3Hex}`)
|
|
18094
|
+
);
|
|
18095
|
+
const keyId = "v3:" + Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
18096
|
+
return {
|
|
18097
|
+
keyId,
|
|
18098
|
+
v3: await importAesKey(v3Hex),
|
|
18099
|
+
v2: await importAesKey(await deriveKeyFromSignature(signatureHex))
|
|
18100
|
+
};
|
|
18101
|
+
}
|
|
18102
|
+
async function decryptWith(value, rings) {
|
|
18103
|
+
const version = value.startsWith("enc:v3:") ? "v3" : "v2";
|
|
18104
|
+
for (const ring of rings) {
|
|
18105
|
+
try {
|
|
18106
|
+
return await decryptDataWithKey(value.slice(`enc:${version}:`.length), ring[version]);
|
|
18107
|
+
} catch {
|
|
18108
|
+
continue;
|
|
18109
|
+
}
|
|
18110
|
+
}
|
|
18111
|
+
throw new MemoryKeyError(`No supplied key decrypts this enc:${version} field`);
|
|
18112
|
+
}
|
|
18113
|
+
function memoryCipher(canonical) {
|
|
18114
|
+
return {
|
|
18115
|
+
encrypt: async (plaintext) => `enc:v3:${await encryptDataWithKey(plaintext, canonical.v3)}`,
|
|
18116
|
+
decrypt: async (ciphertext) => {
|
|
18117
|
+
if (!ciphertext.startsWith("enc:v3:") || !isEncrypted(ciphertext))
|
|
18118
|
+
throw new MemoryKeyError("Remote memory content must be enc:v3 ciphertext");
|
|
18119
|
+
return decryptWith(ciphertext, [canonical]);
|
|
18120
|
+
}
|
|
18121
|
+
};
|
|
18122
|
+
}
|
|
18123
|
+
async function reencryptMemoryField(value, canonical, fallbacks = []) {
|
|
18124
|
+
const { encrypt } = memoryCipher(canonical);
|
|
18125
|
+
if (!value.startsWith("enc:")) return encrypt(value);
|
|
18126
|
+
if (!isEncrypted(value))
|
|
18127
|
+
throw new MemoryKeyError("Field has an encryption prefix but an invalid payload");
|
|
18128
|
+
return encrypt(await decryptWith(value, [canonical, ...fallbacks]));
|
|
18129
|
+
}
|
|
18130
|
+
|
|
18072
18131
|
// src/lib/memory/store/remotePersistence.ts
|
|
18073
18132
|
var RemoteMemoryError = class extends Error {
|
|
18074
18133
|
constructor(message, status, code) {
|
|
@@ -18121,6 +18180,30 @@ var candidateListLimits = [
|
|
|
18121
18180
|
["memory_ids", 1e3],
|
|
18122
18181
|
["force_ids", 100]
|
|
18123
18182
|
];
|
|
18183
|
+
var queryListLimits = [
|
|
18184
|
+
["scopes", 20],
|
|
18185
|
+
["fact_types", 20],
|
|
18186
|
+
["visibility", 20],
|
|
18187
|
+
["memory_ids", 1e3],
|
|
18188
|
+
["topics", 100]
|
|
18189
|
+
];
|
|
18190
|
+
var queryFields = [
|
|
18191
|
+
"include_deleted",
|
|
18192
|
+
"include_archived",
|
|
18193
|
+
"include_quarantined",
|
|
18194
|
+
"include_superseded",
|
|
18195
|
+
"archived_only",
|
|
18196
|
+
"scopes",
|
|
18197
|
+
"fact_types",
|
|
18198
|
+
"visibility",
|
|
18199
|
+
"memory_ids",
|
|
18200
|
+
"topics",
|
|
18201
|
+
"updated_after",
|
|
18202
|
+
"order",
|
|
18203
|
+
"cursor",
|
|
18204
|
+
"limit",
|
|
18205
|
+
"include_embeddings"
|
|
18206
|
+
];
|
|
18124
18207
|
function record(value) {
|
|
18125
18208
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18126
18209
|
}
|
|
@@ -18455,6 +18538,35 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
18455
18538
|
throw new Error("Invalid nearby batch response");
|
|
18456
18539
|
return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
|
|
18457
18540
|
},
|
|
18541
|
+
query: async (queryOptions = {}) => {
|
|
18542
|
+
const { signal, ...query } = queryOptions;
|
|
18543
|
+
if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
|
|
18544
|
+
throw new Error("Page limit must be 1\u2013200");
|
|
18545
|
+
for (const [key, max] of queryListLimits) {
|
|
18546
|
+
const values = query[key];
|
|
18547
|
+
if (values && values.length > max)
|
|
18548
|
+
throw new Error(`Query ${key} accepts at most ${max} entries (got ${values.length})`);
|
|
18549
|
+
}
|
|
18550
|
+
const page = await request(
|
|
18551
|
+
"/memories/query",
|
|
18552
|
+
{
|
|
18553
|
+
method: "POST",
|
|
18554
|
+
body: JSON.stringify(
|
|
18555
|
+
Object.fromEntries(
|
|
18556
|
+
queryFields.filter((key) => query[key] !== void 0).map((key) => [key, query[key]])
|
|
18557
|
+
)
|
|
18558
|
+
)
|
|
18559
|
+
},
|
|
18560
|
+
signal
|
|
18561
|
+
);
|
|
18562
|
+
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")
|
|
18563
|
+
throw new Error("Invalid nearby private-memory page");
|
|
18564
|
+
return {
|
|
18565
|
+
...await decodeAll(page.items),
|
|
18566
|
+
...page.next_cursor !== void 0 && { next_cursor: page.next_cursor },
|
|
18567
|
+
...page.changes_cursor !== void 0 && { changes_cursor: page.changes_cursor }
|
|
18568
|
+
};
|
|
18569
|
+
},
|
|
18458
18570
|
candidateSet,
|
|
18459
18571
|
candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
|
|
18460
18572
|
};
|
|
@@ -18843,6 +18955,489 @@ function createRemoteMemoryPipeline(options) {
|
|
|
18843
18955
|
};
|
|
18844
18956
|
}
|
|
18845
18957
|
|
|
18958
|
+
// src/lib/memory/store/remoteStore.ts
|
|
18959
|
+
import { v7 as uuidv75 } from "uuid";
|
|
18960
|
+
function relevant(change, options) {
|
|
18961
|
+
return options.includeDeleted ? change === "membership" : change !== "embedding" || !!options.embeddings;
|
|
18962
|
+
}
|
|
18963
|
+
function safely(onChange) {
|
|
18964
|
+
try {
|
|
18965
|
+
onChange();
|
|
18966
|
+
} catch (error) {
|
|
18967
|
+
getLogger().warn("[memory/remote-store] Subscriber threw:", error);
|
|
18968
|
+
}
|
|
18969
|
+
}
|
|
18970
|
+
var MAX_BATCH = 50;
|
|
18971
|
+
var MAX_QUERY_IDS = 1e3;
|
|
18972
|
+
var MAX_QUERY_TOPICS = 100;
|
|
18973
|
+
var MAX_QUERY_FILTER = 20;
|
|
18974
|
+
var RemoteMemoryPartialCreateError = class extends Error {
|
|
18975
|
+
constructor(created, cause) {
|
|
18976
|
+
super(`createMany stored ${created.length} memories before a batch failed`);
|
|
18977
|
+
this.created = created;
|
|
18978
|
+
this.cause = cause;
|
|
18979
|
+
this.name = "RemoteMemoryPartialCreateError";
|
|
18980
|
+
}
|
|
18981
|
+
};
|
|
18982
|
+
function warnFailed(failed) {
|
|
18983
|
+
if (failed.length)
|
|
18984
|
+
getLogger().warn(
|
|
18985
|
+
`[memory/remote-store] Skipping ${failed.length} undecryptable row(s)`,
|
|
18986
|
+
failed.map((failure) => failure.memory_id)
|
|
18987
|
+
);
|
|
18988
|
+
}
|
|
18989
|
+
function bounded(filters, key) {
|
|
18990
|
+
const values = filters[key];
|
|
18991
|
+
if (!values || values.length <= MAX_QUERY_FILTER) return [filters];
|
|
18992
|
+
return chunks(values, MAX_QUERY_FILTER).map((chunk) => ({ ...filters, [key]: chunk }));
|
|
18993
|
+
}
|
|
18994
|
+
function chunks(values, size) {
|
|
18995
|
+
const out = [];
|
|
18996
|
+
for (let i = 0; i < values.length; i += size) out.push(values.slice(i, i + size));
|
|
18997
|
+
return out;
|
|
18998
|
+
}
|
|
18999
|
+
function stateFilters(options) {
|
|
19000
|
+
return {
|
|
19001
|
+
include_deleted: options.includeDeleted,
|
|
19002
|
+
include_archived: options.includeArchived,
|
|
19003
|
+
include_quarantined: options.includeQuarantined,
|
|
19004
|
+
include_superseded: options.includeSuperseded
|
|
19005
|
+
};
|
|
19006
|
+
}
|
|
19007
|
+
function hidden(memory, options) {
|
|
19008
|
+
if (memory.trust_tier === "quarantined") return true;
|
|
19009
|
+
if (options.includeDeleted) return false;
|
|
19010
|
+
return !!memory.is_deleted || memory.archived_at !== void 0 && memory.archived_at !== null || !!memory.superseded_by;
|
|
19011
|
+
}
|
|
19012
|
+
function subscriptionKey({ memory, version }, options) {
|
|
19013
|
+
if (hidden(memory, options)) return void 0;
|
|
19014
|
+
if (options.includeDeleted) return String(!!memory.is_deleted);
|
|
19015
|
+
return JSON.stringify([
|
|
19016
|
+
options.embeddings ? version : null,
|
|
19017
|
+
memory.content,
|
|
19018
|
+
memory.scope,
|
|
19019
|
+
memory.updated_at,
|
|
19020
|
+
memory.fact_type,
|
|
19021
|
+
memory.event_time_start,
|
|
19022
|
+
memory.event_time_end,
|
|
19023
|
+
memory.event_time_kind,
|
|
19024
|
+
memory.trust_tier,
|
|
19025
|
+
memory.visibility,
|
|
19026
|
+
memory.published_at,
|
|
19027
|
+
memory.geohash,
|
|
19028
|
+
memory.topics,
|
|
19029
|
+
memory.topics_user_managed,
|
|
19030
|
+
memory.media,
|
|
19031
|
+
memory.source
|
|
19032
|
+
]);
|
|
19033
|
+
}
|
|
19034
|
+
function topicInputs(topics, source) {
|
|
19035
|
+
return topics.flatMap((topic) => {
|
|
19036
|
+
const name = (typeof topic === "string" ? topic : topic.name).trim();
|
|
19037
|
+
const kind = typeof topic === "string" ? void 0 : topic.kind;
|
|
19038
|
+
return name ? [{ name, ...kind && { kind }, source }] : [];
|
|
19039
|
+
});
|
|
19040
|
+
}
|
|
19041
|
+
function mergeTopics(existing, added) {
|
|
19042
|
+
const byName = /* @__PURE__ */ new Map();
|
|
19043
|
+
for (const topic of [...existing, ...added]) {
|
|
19044
|
+
const key = normalizeEntityName(topic.name);
|
|
19045
|
+
if (!byName.has(key)) byName.set(key, topic);
|
|
19046
|
+
}
|
|
19047
|
+
return [...byName.values()];
|
|
19048
|
+
}
|
|
19049
|
+
function canonicalTopics(row) {
|
|
19050
|
+
return new Set((parseTopics(row.topics) ?? []).map((topic) => normalizeEntityName(topic.name)));
|
|
19051
|
+
}
|
|
19052
|
+
function createRemoteMemoryStore(options) {
|
|
19053
|
+
const { persistence, embeddingOptions } = options;
|
|
19054
|
+
const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
19055
|
+
const pollIntervalMs = options.pollIntervalMs ?? 6e4;
|
|
19056
|
+
const pipeline = createRemoteMemoryPipeline(options);
|
|
19057
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
19058
|
+
const seen = /* @__PURE__ */ new Map();
|
|
19059
|
+
let timer;
|
|
19060
|
+
const notify = (change, records = []) => {
|
|
19061
|
+
if (timer) for (const record2 of records) seen.set(record2.memory.memory_id, record2);
|
|
19062
|
+
for (const subscriber of [...subscribers])
|
|
19063
|
+
if (relevant(change, subscriber.options)) safely(subscriber.onChange);
|
|
19064
|
+
};
|
|
19065
|
+
const enumerate = async (filters, max = Infinity) => {
|
|
19066
|
+
const records = [];
|
|
19067
|
+
let cursor2;
|
|
19068
|
+
do {
|
|
19069
|
+
const page = await persistence.query({
|
|
19070
|
+
...filters,
|
|
19071
|
+
limit: Math.min(200, Math.max(1, max - records.length)),
|
|
19072
|
+
...cursor2 && { cursor: cursor2 }
|
|
19073
|
+
});
|
|
19074
|
+
warnFailed(page.failed);
|
|
19075
|
+
records.push(...page.items);
|
|
19076
|
+
cursor2 = page.next_cursor;
|
|
19077
|
+
} while (cursor2 && records.length < max);
|
|
19078
|
+
return records.slice(0, max);
|
|
19079
|
+
};
|
|
19080
|
+
const enumerateIds = async (ids, filters) => (await Promise.all(
|
|
19081
|
+
chunks([...new Set(ids)], MAX_QUERY_IDS).map(
|
|
19082
|
+
(memory_ids) => enumerate({ ...filters, memory_ids })
|
|
19083
|
+
)
|
|
19084
|
+
)).flat();
|
|
19085
|
+
const queues = /* @__PURE__ */ new Map();
|
|
19086
|
+
const serialized = (id, task) => {
|
|
19087
|
+
const run = (queues.get(id) ?? Promise.resolve()).then(task, task);
|
|
19088
|
+
const settled = run.catch(() => void 0);
|
|
19089
|
+
queues.set(id, settled);
|
|
19090
|
+
void settled.then(() => {
|
|
19091
|
+
if (queues.get(id) === settled) queues.delete(id);
|
|
19092
|
+
});
|
|
19093
|
+
return run;
|
|
19094
|
+
};
|
|
19095
|
+
const live = async (id) => {
|
|
19096
|
+
const record2 = await persistence.get(id);
|
|
19097
|
+
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
19098
|
+
};
|
|
19099
|
+
const mutate = async (id, change, edit) => serialized(id, async () => {
|
|
19100
|
+
const record2 = await live(id);
|
|
19101
|
+
if (!record2) return null;
|
|
19102
|
+
const next = edit(structuredClone(record2.memory));
|
|
19103
|
+
if (!next) return null;
|
|
19104
|
+
const saved = await persistence.put(next, record2);
|
|
19105
|
+
notify(change, [saved]);
|
|
19106
|
+
return saved;
|
|
19107
|
+
});
|
|
19108
|
+
const embedInBackground = ({ memory: { memory_id: id, content } }) => {
|
|
19109
|
+
generateEmbedding(content, embeddingOptions).then(
|
|
19110
|
+
(vector) => serialized(id, async () => {
|
|
19111
|
+
const current = await live(id);
|
|
19112
|
+
if (!current || current.memory.content !== content || current.memory.embedding?.length)
|
|
19113
|
+
return;
|
|
19114
|
+
const saved = await persistence.put(
|
|
19115
|
+
{ ...current.memory, embedding: storedVector(vector), embedding_model: model },
|
|
19116
|
+
current
|
|
19117
|
+
);
|
|
19118
|
+
notify("embedding", [saved]);
|
|
19119
|
+
})
|
|
19120
|
+
).catch((error) => {
|
|
19121
|
+
getLogger().warn("[memory/remote-store] Failed to embed memory:", error);
|
|
19122
|
+
});
|
|
19123
|
+
};
|
|
19124
|
+
const newRow = (input) => {
|
|
19125
|
+
const now = Date.now();
|
|
19126
|
+
const scope = input.scope ?? "private";
|
|
19127
|
+
return {
|
|
19128
|
+
memory_id: uuidv75(),
|
|
19129
|
+
content: input.content,
|
|
19130
|
+
scope,
|
|
19131
|
+
level: levelFromScope(scope),
|
|
19132
|
+
created_at: now,
|
|
19133
|
+
updated_at: now,
|
|
19134
|
+
is_deleted: false,
|
|
19135
|
+
...input.embedding !== void 0 && {
|
|
19136
|
+
embedding: storedVector(JSON.parse(input.embedding)),
|
|
19137
|
+
embedding_model: input.embeddingModel ?? model
|
|
19138
|
+
},
|
|
19139
|
+
proof_count: 1,
|
|
19140
|
+
source: "manual",
|
|
19141
|
+
...input.eventTime && {
|
|
19142
|
+
event_time_start: input.eventTime.start ?? void 0,
|
|
19143
|
+
event_time_end: input.eventTime.end ?? void 0,
|
|
19144
|
+
event_time_kind: input.eventTime.kind ?? void 0
|
|
19145
|
+
},
|
|
19146
|
+
fact_type: input.factType,
|
|
19147
|
+
geohash: input.geohash,
|
|
19148
|
+
visibility: "private",
|
|
19149
|
+
twin_opt_in: false
|
|
19150
|
+
};
|
|
19151
|
+
};
|
|
19152
|
+
const created = (records, inputs) => {
|
|
19153
|
+
records.forEach((record2, i) => {
|
|
19154
|
+
if (inputs[i].embedding === void 0) embedInBackground(record2);
|
|
19155
|
+
});
|
|
19156
|
+
notify("membership", records);
|
|
19157
|
+
return records.map((record2) => stored(record2.memory));
|
|
19158
|
+
};
|
|
19159
|
+
const asStored = (record2) => record2 ? stored(record2.memory) : null;
|
|
19160
|
+
const everyState = {
|
|
19161
|
+
include_deleted: true,
|
|
19162
|
+
include_archived: true,
|
|
19163
|
+
include_quarantined: true,
|
|
19164
|
+
include_superseded: true
|
|
19165
|
+
};
|
|
19166
|
+
const changesSince = async (cursor2, pending2) => {
|
|
19167
|
+
const records = [];
|
|
19168
|
+
const failed = /* @__PURE__ */ new Set();
|
|
19169
|
+
const collect = (page) => {
|
|
19170
|
+
warnFailed(page.failed);
|
|
19171
|
+
records.push(...page.items);
|
|
19172
|
+
for (const failure of page.failed) failed.add(failure.memory_id);
|
|
19173
|
+
};
|
|
19174
|
+
let resume = cursor2;
|
|
19175
|
+
let next;
|
|
19176
|
+
do {
|
|
19177
|
+
const page = await persistence.query({
|
|
19178
|
+
...everyState,
|
|
19179
|
+
order: "changed",
|
|
19180
|
+
limit: 200,
|
|
19181
|
+
...(next ?? resume) && { cursor: next ?? resume }
|
|
19182
|
+
});
|
|
19183
|
+
collect(page);
|
|
19184
|
+
resume = page.changes_cursor ?? resume;
|
|
19185
|
+
next = page.next_cursor;
|
|
19186
|
+
} while (next);
|
|
19187
|
+
for (const memory_ids of chunks([...pending2], MAX_QUERY_IDS)) {
|
|
19188
|
+
let retry;
|
|
19189
|
+
do {
|
|
19190
|
+
const page = await persistence.query({
|
|
19191
|
+
...everyState,
|
|
19192
|
+
memory_ids,
|
|
19193
|
+
limit: 200,
|
|
19194
|
+
...retry && { cursor: retry }
|
|
19195
|
+
});
|
|
19196
|
+
collect(page);
|
|
19197
|
+
retry = page.next_cursor;
|
|
19198
|
+
} while (retry);
|
|
19199
|
+
}
|
|
19200
|
+
return { records, resume, failed };
|
|
19201
|
+
};
|
|
19202
|
+
let generation = 0;
|
|
19203
|
+
let ready = false;
|
|
19204
|
+
let cursor;
|
|
19205
|
+
let pending = /* @__PURE__ */ new Set();
|
|
19206
|
+
let polling = false;
|
|
19207
|
+
const poll = () => {
|
|
19208
|
+
if (polling) return;
|
|
19209
|
+
polling = true;
|
|
19210
|
+
const current = generation;
|
|
19211
|
+
changesSince(cursor, pending).then(({ records, resume, failed }) => {
|
|
19212
|
+
if (current !== generation) return;
|
|
19213
|
+
const changed = /* @__PURE__ */ new Set();
|
|
19214
|
+
for (const record2 of records) {
|
|
19215
|
+
const id = record2.memory.memory_id;
|
|
19216
|
+
const previous = seen.get(id);
|
|
19217
|
+
seen.set(id, record2);
|
|
19218
|
+
if (!ready) continue;
|
|
19219
|
+
for (const subscriber of subscribers) {
|
|
19220
|
+
const before = previous && subscriptionKey(previous, subscriber.options);
|
|
19221
|
+
if (before !== subscriptionKey(record2, subscriber.options)) changed.add(subscriber);
|
|
19222
|
+
}
|
|
19223
|
+
}
|
|
19224
|
+
ready = true;
|
|
19225
|
+
cursor = resume;
|
|
19226
|
+
pending = failed;
|
|
19227
|
+
for (const subscriber of changed)
|
|
19228
|
+
if (subscribers.has(subscriber)) safely(subscriber.onChange);
|
|
19229
|
+
}).catch((error) => {
|
|
19230
|
+
getLogger().warn("[memory/remote-store] Subscription poll failed:", error);
|
|
19231
|
+
}).finally(() => {
|
|
19232
|
+
polling = false;
|
|
19233
|
+
});
|
|
19234
|
+
};
|
|
19235
|
+
return {
|
|
19236
|
+
list: async (listOptions = {}) => {
|
|
19237
|
+
const order = listOptions.since ? "updated" : "created";
|
|
19238
|
+
const filters = {
|
|
19239
|
+
...stateFilters(listOptions),
|
|
19240
|
+
include_embeddings: true,
|
|
19241
|
+
order,
|
|
19242
|
+
...listOptions.scopes?.length && { scopes: listOptions.scopes },
|
|
19243
|
+
...listOptions.factTypes?.length && { fact_types: listOptions.factTypes },
|
|
19244
|
+
...listOptions.visibility?.length && { visibility: listOptions.visibility },
|
|
19245
|
+
...listOptions.since && { updated_after: listOptions.since.getTime() }
|
|
19246
|
+
};
|
|
19247
|
+
const max = listOptions.limit && listOptions.limit > 0 ? listOptions.limit : Infinity;
|
|
19248
|
+
const variants = bounded(filters, "scopes").flatMap((f) => bounded(f, "fact_types"));
|
|
19249
|
+
if (!listOptions.memoryIds && variants.length === 1)
|
|
19250
|
+
return (await enumerate(filters, max)).map((r) => stored(r.memory));
|
|
19251
|
+
const fetched = await Promise.all(
|
|
19252
|
+
variants.map(
|
|
19253
|
+
(variant) => listOptions.memoryIds ? enumerateIds(listOptions.memoryIds, variant) : enumerate(variant, max)
|
|
19254
|
+
)
|
|
19255
|
+
);
|
|
19256
|
+
const rows = [...new Map(fetched.flat().map((r) => [r.memory.memory_id, r])).values()].map((record2) => stored(record2.memory)).sort(
|
|
19257
|
+
(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)
|
|
19258
|
+
);
|
|
19259
|
+
return rows.slice(0, max);
|
|
19260
|
+
},
|
|
19261
|
+
get: async (id) => asStored(await live(id)),
|
|
19262
|
+
listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
|
|
19263
|
+
(record2) => stored(record2.memory)
|
|
19264
|
+
),
|
|
19265
|
+
memoriesByTopics: async (names) => {
|
|
19266
|
+
const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
|
|
19267
|
+
const out = /* @__PURE__ */ new Map();
|
|
19268
|
+
const pages = await Promise.all(
|
|
19269
|
+
chunks([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
|
|
19270
|
+
);
|
|
19271
|
+
for (const { memory } of pages.flat()) {
|
|
19272
|
+
const matched = [...canonicalTopics(memory)].filter((name) => wanted.has(name));
|
|
19273
|
+
if (matched.length) out.set(memory.memory_id, new Set(matched));
|
|
19274
|
+
}
|
|
19275
|
+
return out;
|
|
19276
|
+
},
|
|
19277
|
+
topicsByMemories: async (memoryIds) => {
|
|
19278
|
+
const out = /* @__PURE__ */ new Map();
|
|
19279
|
+
for (const { memory } of await enumerateIds(memoryIds, {
|
|
19280
|
+
include_archived: true,
|
|
19281
|
+
include_superseded: true,
|
|
19282
|
+
include_quarantined: true
|
|
19283
|
+
})) {
|
|
19284
|
+
const topics = canonicalTopics(memory);
|
|
19285
|
+
if (topics.size) out.set(memory.memory_id, topics);
|
|
19286
|
+
}
|
|
19287
|
+
return out;
|
|
19288
|
+
},
|
|
19289
|
+
create: async (input) => {
|
|
19290
|
+
const record2 = await persistence.put(newRow(input), 0);
|
|
19291
|
+
return created([record2], [input])[0];
|
|
19292
|
+
},
|
|
19293
|
+
createMany: async (inputs) => {
|
|
19294
|
+
const out = [];
|
|
19295
|
+
for (const batch of chunks(inputs, MAX_BATCH)) {
|
|
19296
|
+
let records;
|
|
19297
|
+
try {
|
|
19298
|
+
records = await persistence.putMany(
|
|
19299
|
+
batch.map((input) => ({ memory: newRow(input), expectedVersion: 0 }))
|
|
19300
|
+
);
|
|
19301
|
+
} catch (error) {
|
|
19302
|
+
if (out.length === 0) throw error;
|
|
19303
|
+
throw new RemoteMemoryPartialCreateError(out, error);
|
|
19304
|
+
}
|
|
19305
|
+
out.push(...created(records, batch));
|
|
19306
|
+
}
|
|
19307
|
+
return out;
|
|
19308
|
+
},
|
|
19309
|
+
update: async (id, patch) => {
|
|
19310
|
+
const saved = await mutate(id, "edit", (memory) => {
|
|
19311
|
+
if (memory.superseded_by) return null;
|
|
19312
|
+
memory.content = patch.content;
|
|
19313
|
+
memory.updated_at = Date.now();
|
|
19314
|
+
if (patch.scope !== void 0) {
|
|
19315
|
+
memory.level = levelForScopeChange(
|
|
19316
|
+
{ level: memory.level, scope: memory.scope },
|
|
19317
|
+
patch.scope
|
|
19318
|
+
);
|
|
19319
|
+
memory.scope = patch.scope;
|
|
19320
|
+
}
|
|
19321
|
+
if (patch.factType !== void 0) memory.fact_type = patch.factType ?? void 0;
|
|
19322
|
+
if (patch.eventTime !== void 0) {
|
|
19323
|
+
memory.event_time_start = patch.eventTime?.start ?? void 0;
|
|
19324
|
+
memory.event_time_end = patch.eventTime?.end ?? void 0;
|
|
19325
|
+
memory.event_time_kind = patch.eventTime?.kind ?? void 0;
|
|
19326
|
+
}
|
|
19327
|
+
if (patch.embedding === void 0 || patch.embedding === null) {
|
|
19328
|
+
memory.embedding = [];
|
|
19329
|
+
delete memory.embedding_model;
|
|
19330
|
+
} else {
|
|
19331
|
+
memory.embedding = storedVector(JSON.parse(patch.embedding));
|
|
19332
|
+
memory.embedding_model = patch.embeddingModel ?? model;
|
|
19333
|
+
}
|
|
19334
|
+
return memory;
|
|
19335
|
+
});
|
|
19336
|
+
if (saved && patch.embedding === void 0) embedInBackground(saved);
|
|
19337
|
+
return asStored(saved);
|
|
19338
|
+
},
|
|
19339
|
+
delete: async (id) => !!await mutate(id, "membership", (memory) => ({ ...memory, is_deleted: true })),
|
|
19340
|
+
supersede: async (id, supersededById) => {
|
|
19341
|
+
if (id === supersededById) return false;
|
|
19342
|
+
const [first, second] = [id, supersededById].sort();
|
|
19343
|
+
return serialized(
|
|
19344
|
+
first,
|
|
19345
|
+
() => serialized(second, async () => {
|
|
19346
|
+
const [old, next] = await Promise.all([live(id), live(supersededById)]);
|
|
19347
|
+
if (!old || !next || old.memory.superseded_by || next.memory.superseded_by) return false;
|
|
19348
|
+
if (old.memory.kind !== void 0 && old.memory.kind !== null) return false;
|
|
19349
|
+
const saved = await persistence.putMany([
|
|
19350
|
+
{
|
|
19351
|
+
memory: { ...old.memory, superseded_by: supersededById, superseded_at: Date.now() },
|
|
19352
|
+
expectedVersion: old
|
|
19353
|
+
},
|
|
19354
|
+
{ memory: next.memory, expectedVersion: next }
|
|
19355
|
+
]);
|
|
19356
|
+
notify("membership", saved);
|
|
19357
|
+
return true;
|
|
19358
|
+
})
|
|
19359
|
+
);
|
|
19360
|
+
},
|
|
19361
|
+
archive: async (id) => !!await mutate(
|
|
19362
|
+
id,
|
|
19363
|
+
"edit",
|
|
19364
|
+
(memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
|
|
19365
|
+
),
|
|
19366
|
+
restore: (id) => serialized(id, async () => {
|
|
19367
|
+
const record2 = await live(id);
|
|
19368
|
+
if (!record2) return false;
|
|
19369
|
+
if (record2.memory.archived_at === void 0 || record2.memory.archived_at === null)
|
|
19370
|
+
return true;
|
|
19371
|
+
const { archived_at: _archivedAt, ...memory } = record2.memory;
|
|
19372
|
+
notify("edit", [await persistence.put(memory, record2)]);
|
|
19373
|
+
return true;
|
|
19374
|
+
}),
|
|
19375
|
+
setTopics: async (memoryId, topics) => asStored(
|
|
19376
|
+
await mutate(memoryId, "edit", (memory) => ({
|
|
19377
|
+
...memory,
|
|
19378
|
+
topics: serializeTopics(mergeTopics([], topicInputs(topics, "user"))),
|
|
19379
|
+
topics_user_managed: true,
|
|
19380
|
+
topics_updated_at: Date.now()
|
|
19381
|
+
}))
|
|
19382
|
+
),
|
|
19383
|
+
addTopics: async (memoryId, topics) => {
|
|
19384
|
+
const added = topicInputs(topics, "auto");
|
|
19385
|
+
const saved = await mutate(memoryId, "edit", (memory) => ({
|
|
19386
|
+
...memory,
|
|
19387
|
+
topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
|
|
19388
|
+
topics_updated_at: Date.now()
|
|
19389
|
+
}));
|
|
19390
|
+
if (!saved) return [];
|
|
19391
|
+
const now = /* @__PURE__ */ new Date();
|
|
19392
|
+
return mergeTopics([], added).map(
|
|
19393
|
+
(topic) => ({
|
|
19394
|
+
uniqueId: normalizeEntityName(topic.name),
|
|
19395
|
+
canonicalName: normalizeEntityName(topic.name),
|
|
19396
|
+
kind: topic.kind ?? null,
|
|
19397
|
+
createdAt: now,
|
|
19398
|
+
updatedAt: now
|
|
19399
|
+
})
|
|
19400
|
+
);
|
|
19401
|
+
},
|
|
19402
|
+
setVisibility: async (id, visibility, visibilityOptions) => asStored(
|
|
19403
|
+
await mutate(id, "edit", (memory) => {
|
|
19404
|
+
memory.visibility = visibility;
|
|
19405
|
+
if (visibility === "private") delete memory.published_at;
|
|
19406
|
+
else memory.published_at ?? (memory.published_at = Date.now());
|
|
19407
|
+
if (visibilityOptions?.twinOptIn !== void 0)
|
|
19408
|
+
memory.twin_opt_in = visibilityOptions.twinOptIn;
|
|
19409
|
+
return memory;
|
|
19410
|
+
})
|
|
19411
|
+
),
|
|
19412
|
+
recall: (query, recallOptions) => pipeline.recall(query, recallOptions),
|
|
19413
|
+
retain: async (content, retainOptions) => {
|
|
19414
|
+
const result = await pipeline.retain(content, retainOptions);
|
|
19415
|
+
if (result.action === "create" || result.action === "supersede") notify("membership");
|
|
19416
|
+
else if (result.action === "update" || result.action === "merge") notify("edit");
|
|
19417
|
+
return result;
|
|
19418
|
+
},
|
|
19419
|
+
subscribe: (onChange, subscribeOptions = {}) => {
|
|
19420
|
+
const subscriber = { onChange, options: subscribeOptions };
|
|
19421
|
+
subscribers.add(subscriber);
|
|
19422
|
+
if (pollIntervalMs > 0 && !timer) {
|
|
19423
|
+
timer = setInterval(poll, pollIntervalMs);
|
|
19424
|
+
poll();
|
|
19425
|
+
}
|
|
19426
|
+
return () => {
|
|
19427
|
+
subscribers.delete(subscriber);
|
|
19428
|
+
if (subscribers.size || !timer) return;
|
|
19429
|
+
clearInterval(timer);
|
|
19430
|
+
timer = void 0;
|
|
19431
|
+
generation++;
|
|
19432
|
+
seen.clear();
|
|
19433
|
+
ready = false;
|
|
19434
|
+
cursor = void 0;
|
|
19435
|
+
pending = /* @__PURE__ */ new Set();
|
|
19436
|
+
};
|
|
19437
|
+
}
|
|
19438
|
+
};
|
|
19439
|
+
}
|
|
19440
|
+
|
|
18846
19441
|
// src/lib/memory/synthesizeProfile.ts
|
|
18847
19442
|
var DEFAULT_SYNTHESIS_MODEL = "inclusionai/ling-2.6-flash";
|
|
18848
19443
|
var DEFAULT_FACET_RECALL_LIMIT = 20;
|
|
@@ -22253,7 +22848,7 @@ function useChat(options) {
|
|
|
22253
22848
|
|
|
22254
22849
|
// src/expo/useChatStorage.ts
|
|
22255
22850
|
import { useCallback as useCallback4, useEffect as useEffect4, useMemo, useRef as useRef4, useState as useState4 } from "react";
|
|
22256
|
-
import { v7 as
|
|
22851
|
+
import { v7 as uuidv77 } from "uuid";
|
|
22257
22852
|
|
|
22258
22853
|
// src/lib/chat/assembleMessages.ts
|
|
22259
22854
|
function assembleMessagesWithHistory(historyMessages, callerMessages, summarySystemMessage) {
|
|
@@ -22910,9 +23505,9 @@ async function decryptMediaFields(media, address, signMessage, embeddedWalletSig
|
|
|
22910
23505
|
}
|
|
22911
23506
|
|
|
22912
23507
|
// src/lib/db/media/types.ts
|
|
22913
|
-
import { v7 as
|
|
23508
|
+
import { v7 as uuidv76 } from "uuid";
|
|
22914
23509
|
function generateMediaId() {
|
|
22915
|
-
return `media_${
|
|
23510
|
+
return `media_${uuidv76()}`;
|
|
22916
23511
|
}
|
|
22917
23512
|
|
|
22918
23513
|
// src/lib/db/media/operations.ts
|
|
@@ -23868,7 +24463,7 @@ function useChatStorage(options) {
|
|
|
23868
24463
|
};
|
|
23869
24464
|
};
|
|
23870
24465
|
pendingResumeRef.current = null;
|
|
23871
|
-
const effectiveAssistantUniqueId = assistantUniqueId ?? (resumable ? `msg_${
|
|
24466
|
+
const effectiveAssistantUniqueId = assistantUniqueId ?? (resumable ? `msg_${uuidv77()}` : void 0);
|
|
23872
24467
|
const embedToolText = (text12, mask, masked, token) => {
|
|
23873
24468
|
const opts = {
|
|
23874
24469
|
getToken: token,
|
|
@@ -24386,7 +24981,7 @@ function useChatStorage(options) {
|
|
|
24386
24981
|
const detachedResult = result;
|
|
24387
24982
|
if (detachedResult.detached) {
|
|
24388
24983
|
recordToolSetTurn(database, convId, matchedToolSets);
|
|
24389
|
-
const rowId = effectiveAssistantUniqueId ?? `msg_${
|
|
24984
|
+
const rowId = effectiveAssistantUniqueId ?? `msg_${uuidv77()}`;
|
|
24390
24985
|
pendingResumeRef.current = {
|
|
24391
24986
|
handle: detachedResult.resume ?? null,
|
|
24392
24987
|
convId,
|
|
@@ -24897,6 +25492,7 @@ export {
|
|
|
24897
25492
|
MEDIUM_TTL_MS,
|
|
24898
25493
|
MEMORY_KINDS,
|
|
24899
25494
|
MEMORY_LEVELS,
|
|
25495
|
+
MemoryKeyError,
|
|
24900
25496
|
MemoryLevelError,
|
|
24901
25497
|
NEVER_TTL_MS,
|
|
24902
25498
|
NODE_BUDGET,
|
|
@@ -24909,6 +25505,7 @@ export {
|
|
|
24909
25505
|
RECALL_MAX_LIMIT,
|
|
24910
25506
|
RECALL_TOOL_NAME,
|
|
24911
25507
|
RemoteMemoryError,
|
|
25508
|
+
RemoteMemoryPartialCreateError,
|
|
24912
25509
|
RerankerUnavailableError,
|
|
24913
25510
|
SDK_SCHEMA_VERSION,
|
|
24914
25511
|
SHORT_TTL_MS,
|
|
@@ -24974,6 +25571,7 @@ export {
|
|
|
24974
25571
|
createRecallTool,
|
|
24975
25572
|
createRemoteMemoryPersistence,
|
|
24976
25573
|
createRemoteMemoryPipeline,
|
|
25574
|
+
createRemoteMemoryStore,
|
|
24977
25575
|
createStockPricePreProcessor,
|
|
24978
25576
|
createStreamingDeAnonymizer,
|
|
24979
25577
|
createVaultEmbeddingCache,
|
|
@@ -24990,6 +25588,7 @@ export {
|
|
|
24990
25588
|
deleteVaultMemoryOp,
|
|
24991
25589
|
dequantizeEmbedding,
|
|
24992
25590
|
deriveKeyFromSignatureBytes,
|
|
25591
|
+
deriveMemoryKeyRing,
|
|
24993
25592
|
discoverNotionOAuthEndpoints,
|
|
24994
25593
|
eagerEmbedContent,
|
|
24995
25594
|
embedAllMessages,
|
|
@@ -25033,6 +25632,7 @@ export {
|
|
|
25033
25632
|
isPiiRedactor,
|
|
25034
25633
|
isRerankerAvailable,
|
|
25035
25634
|
maskScopedEmbeddingCache,
|
|
25635
|
+
memoryCipher,
|
|
25036
25636
|
moveMemoriesToFolderOp,
|
|
25037
25637
|
noopLogger,
|
|
25038
25638
|
onKeyAvailable,
|
|
@@ -25042,6 +25642,7 @@ export {
|
|
|
25042
25642
|
queueManager,
|
|
25043
25643
|
rankProfileCandidates,
|
|
25044
25644
|
recall,
|
|
25645
|
+
reencryptMemoryField,
|
|
25045
25646
|
reflect,
|
|
25046
25647
|
refreshEncryptionKeyIfMatches,
|
|
25047
25648
|
refreshNotionAccessToken,
|