@anuma/sdk 10.9.0 → 11.0.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/{consolidate-7QUL3TOE.mjs → consolidate-QBV3DDHU.mjs} +1 -1
- package/dist/expo/index.cjs +3446 -2649
- package/dist/expo/index.d.mts +967 -873
- package/dist/expo/index.d.ts +967 -873
- package/dist/expo/index.mjs +2966 -2177
- package/dist/react/index.cjs +1186 -684
- package/dist/react/index.d.mts +720 -715
- package/dist/react/index.d.ts +720 -715
- package/dist/react/index.mjs +1182 -684
- package/dist/server/index.cjs +19 -13
- package/dist/server/index.d.mts +4 -2
- package/dist/server/index.d.ts +4 -2
- package/dist/server/index.mjs +19 -13
- package/package.json +1 -1
- package/dist/expo/{chunk-4SOUKJD5.mjs → chunk-VNTEHEGI.mjs} +957 -957
package/dist/react/index.cjs
CHANGED
|
@@ -2394,9 +2394,9 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
2394
2394
|
return false;
|
|
2395
2395
|
}
|
|
2396
2396
|
const startEpoch = sessionEpoch;
|
|
2397
|
-
const
|
|
2398
|
-
if (
|
|
2399
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed,
|
|
2397
|
+
const cached2 = refreshCandidatesByAddress.get(walletAddress);
|
|
2398
|
+
if (cached2) {
|
|
2399
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached2, startEpoch);
|
|
2400
2400
|
}
|
|
2401
2401
|
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
2402
2402
|
if (!derivePromise) {
|
|
@@ -2748,10 +2748,10 @@ function parsePlaintextToken(raw, walletAddress) {
|
|
|
2748
2748
|
return null;
|
|
2749
2749
|
}
|
|
2750
2750
|
if (!parsed || typeof parsed !== "object") return null;
|
|
2751
|
-
const
|
|
2752
|
-
const data =
|
|
2751
|
+
const record3 = parsed;
|
|
2752
|
+
const data = record3.token?.accessToken ? record3.token : record3;
|
|
2753
2753
|
if (!data?.accessToken) return null;
|
|
2754
|
-
if (
|
|
2754
|
+
if (record3.wallet && record3.wallet !== walletAddress) return null;
|
|
2755
2755
|
return data;
|
|
2756
2756
|
}
|
|
2757
2757
|
function promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress) {
|
|
@@ -2843,10 +2843,10 @@ async function discoverOAuthMetadata() {
|
|
|
2843
2843
|
}
|
|
2844
2844
|
async function getOAuthMetadata() {
|
|
2845
2845
|
if (typeof window !== "undefined") {
|
|
2846
|
-
const
|
|
2847
|
-
if (
|
|
2846
|
+
const cached2 = sessionStorage.getItem(OAUTH_METADATA_KEY);
|
|
2847
|
+
if (cached2) {
|
|
2848
2848
|
try {
|
|
2849
|
-
return JSON.parse(
|
|
2849
|
+
return JSON.parse(cached2);
|
|
2850
2850
|
} catch {
|
|
2851
2851
|
}
|
|
2852
2852
|
}
|
|
@@ -2950,8 +2950,8 @@ async function storeTokenData(data, walletAddress) {
|
|
|
2950
2950
|
} catch {
|
|
2951
2951
|
}
|
|
2952
2952
|
}
|
|
2953
|
-
const
|
|
2954
|
-
sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(
|
|
2953
|
+
const record3 = { wallet: walletAddress, token: data };
|
|
2954
|
+
sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record3));
|
|
2955
2955
|
}
|
|
2956
2956
|
async function getStoredTokenData(walletAddress) {
|
|
2957
2957
|
if (typeof window === "undefined") return null;
|
|
@@ -3355,25 +3355,25 @@ var TRUNCATION_MARKER_HEAD = "... (tool output truncated, ";
|
|
|
3355
3355
|
var TRUNCATION_MARKER_TAIL = " characters omitted)";
|
|
3356
3356
|
var MAX_PERSISTED_TOOL_RESULT_CHARS = 1e5;
|
|
3357
3357
|
function buildToolResultContent(results) {
|
|
3358
|
-
const
|
|
3358
|
+
const entries2 = results.map(
|
|
3359
3359
|
(r) => `Tool "${r.name}" returned: ${JSON.stringify(r.result)}`.replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029")
|
|
3360
3360
|
);
|
|
3361
|
-
const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0,
|
|
3362
|
-
const summary = capEntries(
|
|
3361
|
+
const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0, entries2.length - 1);
|
|
3362
|
+
const summary = capEntries(entries2, MAX_PERSISTED_TOOL_RESULT_CHARS - framing).join(
|
|
3363
3363
|
ENTRY_SEPARATOR
|
|
3364
3364
|
);
|
|
3365
3365
|
return `${HEADER}${summary}${FOOTER}`;
|
|
3366
3366
|
}
|
|
3367
|
-
function capToolResultEntries(
|
|
3368
|
-
return capEntries(
|
|
3367
|
+
function capToolResultEntries(entries2, budget) {
|
|
3368
|
+
return capEntries(entries2, budget);
|
|
3369
3369
|
}
|
|
3370
|
-
function capEntries(
|
|
3371
|
-
const smallestFirst =
|
|
3372
|
-
const capped = [...
|
|
3370
|
+
function capEntries(entries2, budget) {
|
|
3371
|
+
const smallestFirst = entries2.map((_, index) => index).sort((a, b) => entries2[a].length - entries2[b].length);
|
|
3372
|
+
const capped = [...entries2];
|
|
3373
3373
|
let remaining = budget;
|
|
3374
|
-
let unassigned =
|
|
3374
|
+
let unassigned = entries2.length;
|
|
3375
3375
|
for (const index of smallestFirst) {
|
|
3376
|
-
capped[index] = truncateEntry(
|
|
3376
|
+
capped[index] = truncateEntry(entries2[index], Math.floor(remaining / unassigned));
|
|
3377
3377
|
remaining -= capped[index].length;
|
|
3378
3378
|
unassigned--;
|
|
3379
3379
|
}
|
|
@@ -4265,11 +4265,11 @@ var ToolCallEventIndex = class {
|
|
|
4265
4265
|
this.pending = /* @__PURE__ */ new Map();
|
|
4266
4266
|
this.resetCount = collection.database._resetCount;
|
|
4267
4267
|
collection.experimentalSubscribe((changes) => {
|
|
4268
|
-
for (const { record:
|
|
4268
|
+
for (const { record: record3, type } of changes) {
|
|
4269
4269
|
this.replace(
|
|
4270
|
-
|
|
4271
|
-
type === "destroyed" ? void 0 :
|
|
4272
|
-
type === "destroyed" ? void 0 :
|
|
4270
|
+
record3.id,
|
|
4271
|
+
type === "destroyed" ? void 0 : record3.conversationId,
|
|
4272
|
+
type === "destroyed" ? void 0 : record3._getRaw("tool_call_events")
|
|
4273
4273
|
);
|
|
4274
4274
|
}
|
|
4275
4275
|
});
|
|
@@ -5395,7 +5395,7 @@ async function updateMessageErrorOp(ctx, uniqueId, error) {
|
|
|
5395
5395
|
}
|
|
5396
5396
|
await ctx.database.write(async () => {
|
|
5397
5397
|
await message.update((msg) => {
|
|
5398
|
-
msg._setRaw("error", error);
|
|
5398
|
+
msg._setRaw("error", error ?? "");
|
|
5399
5399
|
});
|
|
5400
5400
|
});
|
|
5401
5401
|
return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
@@ -5712,15 +5712,15 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
5712
5712
|
staleSkipped++;
|
|
5713
5713
|
continue;
|
|
5714
5714
|
}
|
|
5715
|
-
const
|
|
5716
|
-
if (!
|
|
5715
|
+
const cached2 = chunkCache?.get(key3.id);
|
|
5716
|
+
if (!cached2 || cached2.version !== key3.version) {
|
|
5717
5717
|
missIds.push(key3.id);
|
|
5718
5718
|
continue;
|
|
5719
5719
|
}
|
|
5720
5720
|
cacheHits++;
|
|
5721
|
-
if (
|
|
5722
|
-
for (let ci = 0; ci <
|
|
5723
|
-
const vec =
|
|
5721
|
+
if (cached2.chunks.length > 0) {
|
|
5722
|
+
for (let ci = 0; ci < cached2.chunks.length; ci++) {
|
|
5723
|
+
const vec = cached2.chunks[ci];
|
|
5724
5724
|
if (vec.length === 0) continue;
|
|
5725
5725
|
const similarity = cosineSimilarity(queryVector, vec);
|
|
5726
5726
|
if (similarity >= minSimilarity) {
|
|
@@ -5733,8 +5733,8 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
5733
5733
|
});
|
|
5734
5734
|
}
|
|
5735
5735
|
}
|
|
5736
|
-
} else if (
|
|
5737
|
-
const similarity = cosineSimilarity(queryVector,
|
|
5736
|
+
} else if (cached2.fallback) {
|
|
5737
|
+
const similarity = cosineSimilarity(queryVector, cached2.fallback);
|
|
5738
5738
|
if (similarity >= minSimilarity) {
|
|
5739
5739
|
candidates.push({
|
|
5740
5740
|
id: key3.id,
|
|
@@ -6550,11 +6550,11 @@ var mergeConfigs = (a, b) => {
|
|
|
6550
6550
|
return config;
|
|
6551
6551
|
};
|
|
6552
6552
|
var headersEntries = (headers) => {
|
|
6553
|
-
const
|
|
6553
|
+
const entries2 = [];
|
|
6554
6554
|
headers.forEach((value, key3) => {
|
|
6555
|
-
|
|
6555
|
+
entries2.push([key3, value]);
|
|
6556
6556
|
});
|
|
6557
|
-
return
|
|
6557
|
+
return entries2;
|
|
6558
6558
|
};
|
|
6559
6559
|
var mergeHeaders = (...headers) => {
|
|
6560
6560
|
const mergedHeaders = new Headers();
|
|
@@ -7034,9 +7034,9 @@ async function embedOne(text16, options, outer) {
|
|
|
7034
7034
|
const { cache } = options;
|
|
7035
7035
|
if (!cache) return Array.from(await requestEmbedding(text16, options, outer));
|
|
7036
7036
|
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
7037
|
-
const
|
|
7038
|
-
const cachedModel =
|
|
7039
|
-
if (
|
|
7037
|
+
const cached2 = cache.get(text16);
|
|
7038
|
+
const cachedModel = cached2 && cachedEmbeddingModels.get(cached2);
|
|
7039
|
+
if (cached2 && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached2);
|
|
7040
7040
|
const inFlight = inFlightByCache.get(cache) ?? /* @__PURE__ */ new Map();
|
|
7041
7041
|
inFlightByCache.set(cache, inFlight);
|
|
7042
7042
|
const requestKey = JSON.stringify([model, text16]);
|
|
@@ -7151,10 +7151,10 @@ async function embedMany(texts, options, outer) {
|
|
|
7151
7151
|
const uncachedTexts = [];
|
|
7152
7152
|
for (let i = 0; i < texts.length; i++) {
|
|
7153
7153
|
if (cache) {
|
|
7154
|
-
const
|
|
7155
|
-
const cachedModel =
|
|
7156
|
-
if (
|
|
7157
|
-
results[i] = Array.from(
|
|
7154
|
+
const cached2 = cache.get(texts[i]);
|
|
7155
|
+
const cachedModel = cached2 && cachedEmbeddingModels.get(cached2);
|
|
7156
|
+
if (cached2 && (cachedModel === void 0 || cachedModel === embeddingModel)) {
|
|
7157
|
+
results[i] = Array.from(cached2);
|
|
7158
7158
|
continue;
|
|
7159
7159
|
}
|
|
7160
7160
|
}
|
|
@@ -7540,8 +7540,12 @@ function createCryptoPricePreProcessor(options = {}) {
|
|
|
7540
7540
|
}
|
|
7541
7541
|
|
|
7542
7542
|
// src/lib/memory/store/remotePersistence.ts
|
|
7543
|
+
init_logger();
|
|
7543
7544
|
init_portalLlm();
|
|
7544
7545
|
|
|
7546
|
+
// src/lib/memory/store/remoteTopics.ts
|
|
7547
|
+
init_logger();
|
|
7548
|
+
|
|
7545
7549
|
// src/lib/db/entities/types.ts
|
|
7546
7550
|
var ENTITY_KINDS = [
|
|
7547
7551
|
"person",
|
|
@@ -7598,58 +7602,337 @@ function parseTopics(value) {
|
|
|
7598
7602
|
return out;
|
|
7599
7603
|
}
|
|
7600
7604
|
|
|
7605
|
+
// src/lib/memory/store/topicCodec.ts
|
|
7606
|
+
var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
|
|
7607
|
+
var topicHashPattern = /^[0-9a-f]{64}$/;
|
|
7608
|
+
var MAX_SEALED_TOPIC_NAME_BYTES = 1024;
|
|
7609
|
+
function normalizeTopicName(name) {
|
|
7610
|
+
return normalizeEntityName(name).normalize("NFC");
|
|
7611
|
+
}
|
|
7612
|
+
function sealedTopicNamesFit(json5) {
|
|
7613
|
+
return (entries(json5) ?? []).every(
|
|
7614
|
+
(entry) => !hashed(entry) || typeof entry.name !== "string" || entry.name.length <= MAX_SEALED_TOPIC_NAME_BYTES
|
|
7615
|
+
);
|
|
7616
|
+
}
|
|
7617
|
+
function record(value) {
|
|
7618
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7619
|
+
}
|
|
7620
|
+
function hashed(entry) {
|
|
7621
|
+
return record(entry) && typeof entry.name_hash === "string";
|
|
7622
|
+
}
|
|
7623
|
+
function entries(json5) {
|
|
7624
|
+
if (typeof json5 !== "string") return void 0;
|
|
7625
|
+
try {
|
|
7626
|
+
const parsed = JSON.parse(json5);
|
|
7627
|
+
return Array.isArray(parsed) ? parsed : void 0;
|
|
7628
|
+
} catch {
|
|
7629
|
+
return void 0;
|
|
7630
|
+
}
|
|
7631
|
+
}
|
|
7632
|
+
function cached(cache, key3, load) {
|
|
7633
|
+
let pending = cache.get(key3);
|
|
7634
|
+
if (!pending) {
|
|
7635
|
+
const loading = load();
|
|
7636
|
+
pending = loading;
|
|
7637
|
+
cache.set(key3, loading);
|
|
7638
|
+
loading.catch(() => {
|
|
7639
|
+
if (cache.get(key3) === loading) cache.delete(key3);
|
|
7640
|
+
});
|
|
7641
|
+
}
|
|
7642
|
+
return pending;
|
|
7643
|
+
}
|
|
7644
|
+
function createTopicCodec(cipher) {
|
|
7645
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
7646
|
+
const opened = /* @__PURE__ */ new Map();
|
|
7647
|
+
const seals = /* @__PURE__ */ new Map();
|
|
7648
|
+
const legacyNames = /* @__PURE__ */ new Map();
|
|
7649
|
+
const hash = async (name) => {
|
|
7650
|
+
const normalized2 = normalizeTopicName(name);
|
|
7651
|
+
if (!normalized2) return null;
|
|
7652
|
+
return cached(hashes, normalized2, async () => {
|
|
7653
|
+
const digest = await cipher.hashTopic(normalized2);
|
|
7654
|
+
if (!topicHashPattern.test(digest))
|
|
7655
|
+
throw new Error("Topic hashing must return 64 lowercase hex characters");
|
|
7656
|
+
return digest;
|
|
7657
|
+
});
|
|
7658
|
+
};
|
|
7659
|
+
const seal = async (display) => {
|
|
7660
|
+
const nameHash = await hash(display);
|
|
7661
|
+
if (nameHash === null) return null;
|
|
7662
|
+
return cached(seals, display, async () => {
|
|
7663
|
+
const name = await cipher.encrypt(display);
|
|
7664
|
+
if (name === display || !ciphertextPattern.test(name))
|
|
7665
|
+
throw new Error(
|
|
7666
|
+
"Topic encryption must return SDK ciphertext; refusing to upload plaintext"
|
|
7667
|
+
);
|
|
7668
|
+
opened.set(name, Promise.resolve(display));
|
|
7669
|
+
return { name_hash: nameHash, name };
|
|
7670
|
+
});
|
|
7671
|
+
};
|
|
7672
|
+
const plain2 = (name) => {
|
|
7673
|
+
if (!ciphertextPattern.test(name)) return Promise.resolve(name);
|
|
7674
|
+
let pending = legacyNames.get(name);
|
|
7675
|
+
if (!pending) {
|
|
7676
|
+
pending = cipher.decrypt(name).catch(() => name);
|
|
7677
|
+
legacyNames.set(name, pending);
|
|
7678
|
+
}
|
|
7679
|
+
return pending;
|
|
7680
|
+
};
|
|
7681
|
+
const open = async ({ name, name_hash: nameHash }) => {
|
|
7682
|
+
if (nameHash === void 0) return plain2(name);
|
|
7683
|
+
if (typeof name !== "string" || typeof nameHash !== "string" || !topicHashPattern.test(nameHash) || !ciphertextPattern.test(name))
|
|
7684
|
+
throw new Error("Nearby returned a malformed topic name");
|
|
7685
|
+
const plaintext = await cached(opened, name, async () => {
|
|
7686
|
+
const value = await cipher.decrypt(name);
|
|
7687
|
+
if (value === name) throw new Error("Topic decryption failed");
|
|
7688
|
+
return value;
|
|
7689
|
+
});
|
|
7690
|
+
if (await hash(plaintext) !== nameHash) throw new Error("Topic name does not match its hash");
|
|
7691
|
+
if (!seals.has(plaintext)) seals.set(plaintext, Promise.resolve({ name_hash: nameHash, name }));
|
|
7692
|
+
return plaintext;
|
|
7693
|
+
};
|
|
7694
|
+
return {
|
|
7695
|
+
hash,
|
|
7696
|
+
seal,
|
|
7697
|
+
open,
|
|
7698
|
+
encodeTopics: async (json5) => {
|
|
7699
|
+
const list = entries(json5);
|
|
7700
|
+
if (!list) return json5;
|
|
7701
|
+
const sealed2 = await Promise.all(
|
|
7702
|
+
list.map(async (entry) => {
|
|
7703
|
+
if (!record(entry) || typeof entry.name !== "string") return null;
|
|
7704
|
+
const name = await seal(await plain2(entry.name));
|
|
7705
|
+
return name && { ...entry, name: name.name, name_hash: name.name_hash };
|
|
7706
|
+
})
|
|
7707
|
+
);
|
|
7708
|
+
return JSON.stringify(sealed2.filter((entry) => entry !== null));
|
|
7709
|
+
},
|
|
7710
|
+
decodeTopics: async (json5) => {
|
|
7711
|
+
const list = entries(json5);
|
|
7712
|
+
if (!list?.some(
|
|
7713
|
+
(entry) => hashed(entry) || record(entry) && typeof entry.name === "string" && ciphertextPattern.test(entry.name)
|
|
7714
|
+
))
|
|
7715
|
+
return json5;
|
|
7716
|
+
const decoded = await Promise.all(
|
|
7717
|
+
list.map(async (entry) => {
|
|
7718
|
+
if (!hashed(entry))
|
|
7719
|
+
return record(entry) && typeof entry.name === "string" ? { ...entry, name: await plain2(entry.name) } : entry;
|
|
7720
|
+
const { name_hash: nameHash, ...rest } = entry;
|
|
7721
|
+
return { ...rest, name: await open({ name: entry.name, name_hash: nameHash }) };
|
|
7722
|
+
})
|
|
7723
|
+
);
|
|
7724
|
+
return JSON.stringify(decoded);
|
|
7725
|
+
},
|
|
7726
|
+
isLegacy: (json5) => (entries(json5) ?? []).some(
|
|
7727
|
+
(entry) => record(entry) && typeof entry.name === "string" && !hashed(entry)
|
|
7728
|
+
),
|
|
7729
|
+
matchesLegacy: async (json5, names, hashes2) => {
|
|
7730
|
+
const list = typeof json5 === "string" ? entries(json5) ?? [] : [];
|
|
7731
|
+
if (list.some((entry) => hashed(entry) && hashes2.has(entry.name_hash))) return false;
|
|
7732
|
+
const legacy = await Promise.all(
|
|
7733
|
+
list.map(
|
|
7734
|
+
async (entry) => record(entry) && typeof entry.name === "string" && !hashed(entry) ? normalizeTopicName(await plain2(entry.name)) : null
|
|
7735
|
+
)
|
|
7736
|
+
);
|
|
7737
|
+
return legacy.some((name) => name !== null && names.has(name));
|
|
7738
|
+
},
|
|
7739
|
+
encodeCatalog: async (topic2) => {
|
|
7740
|
+
const sealed2 = await seal(normalizeTopicName(await plain2(topic2.name)));
|
|
7741
|
+
return sealed2 && { ...topic2, name: sealed2.name, name_hash: sealed2.name_hash };
|
|
7742
|
+
},
|
|
7743
|
+
decodeCatalog: async (item) => {
|
|
7744
|
+
const { name_hash: nameHash, ...rest } = item;
|
|
7745
|
+
return { ...rest, name: await open({ name: item.name, name_hash: nameHash }) };
|
|
7746
|
+
}
|
|
7747
|
+
};
|
|
7748
|
+
}
|
|
7749
|
+
|
|
7601
7750
|
// src/lib/memory/store/remoteTopics.ts
|
|
7751
|
+
var RETIRE_CONCURRENCY = 8;
|
|
7602
7752
|
function topic(value) {
|
|
7603
7753
|
const t = value;
|
|
7604
|
-
if (!t || typeof t.name !== "string" || !t.name || !Number.isSafeInteger(t.version) || t.version < 1 || typeof t.is_deleted !== "boolean" || typeof t.server_updated_at !== "string" || t.kind !== void 0 && typeof t.kind !== "string")
|
|
7754
|
+
if (!t || typeof t.name !== "string" || !t.name || t.name_hash !== void 0 && typeof t.name_hash !== "string" || !Number.isSafeInteger(t.version) || t.version < 1 || typeof t.is_deleted !== "boolean" || typeof t.server_updated_at !== "string" || t.kind !== void 0 && typeof t.kind !== "string")
|
|
7605
7755
|
throw new Error("Invalid nearby topic");
|
|
7606
7756
|
return t;
|
|
7607
7757
|
}
|
|
7608
|
-
function
|
|
7758
|
+
async function wireTopics(request, signal) {
|
|
7759
|
+
const out = [];
|
|
7760
|
+
let cursor;
|
|
7761
|
+
do {
|
|
7762
|
+
const page = await request(
|
|
7763
|
+
"/topics?limit=200" + (cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""),
|
|
7764
|
+
{},
|
|
7765
|
+
signal
|
|
7766
|
+
);
|
|
7767
|
+
if (!Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string")
|
|
7768
|
+
throw new Error("Invalid nearby topic page");
|
|
7769
|
+
out.push(...page.items.map(topic));
|
|
7770
|
+
cursor = page.next_cursor;
|
|
7771
|
+
} while (cursor);
|
|
7772
|
+
return out;
|
|
7773
|
+
}
|
|
7774
|
+
function hashesOf(items) {
|
|
7775
|
+
return new Set(items.flatMap((t) => t.name_hash === void 0 ? [] : [t.name_hash]));
|
|
7776
|
+
}
|
|
7777
|
+
async function sealedImport(request, codec, topics, signal) {
|
|
7778
|
+
let oversized = 0;
|
|
7779
|
+
for (let i = 0; i < topics.length; i += 50) {
|
|
7780
|
+
signal?.throwIfAborted();
|
|
7781
|
+
const sealed2 = (await Promise.all(topics.slice(i, i + 50).map((t) => codec.encodeCatalog(t)))).filter((t) => {
|
|
7782
|
+
if (t === null) return false;
|
|
7783
|
+
if (t.name.length <= MAX_SEALED_TOPIC_NAME_BYTES) return true;
|
|
7784
|
+
oversized++;
|
|
7785
|
+
return false;
|
|
7786
|
+
});
|
|
7787
|
+
if (sealed2.length)
|
|
7788
|
+
await request(
|
|
7789
|
+
"/topics/import",
|
|
7790
|
+
{ method: "POST", body: JSON.stringify({ topics: sealed2 }) },
|
|
7791
|
+
signal
|
|
7792
|
+
);
|
|
7793
|
+
}
|
|
7794
|
+
signal?.throwIfAborted();
|
|
7795
|
+
if (oversized)
|
|
7796
|
+
getLogger().warn(
|
|
7797
|
+
`[memory/remote] Skipped ${oversized} topic catalog entries whose sealed name exceeds ${MAX_SEALED_TOPIC_NAME_BYTES} bytes`
|
|
7798
|
+
);
|
|
7799
|
+
}
|
|
7800
|
+
function createRemoteTopicPersistence(request, codec) {
|
|
7801
|
+
let legacyOnly = /* @__PURE__ */ new Set();
|
|
7609
7802
|
return {
|
|
7610
7803
|
topics: async () => {
|
|
7611
|
-
const
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7804
|
+
const items = await wireTopics(request);
|
|
7805
|
+
const hashed2 = hashesOf(items);
|
|
7806
|
+
const legacy = /* @__PURE__ */ new Set();
|
|
7807
|
+
const decoded = await Promise.all(
|
|
7808
|
+
items.map(async (item) => {
|
|
7809
|
+
const plain2 = await codec.decodeCatalog(item);
|
|
7810
|
+
const name = normalizeTopicName(plain2.name);
|
|
7811
|
+
if (item.name_hash === void 0) {
|
|
7812
|
+
const hash = await codec.hash(name);
|
|
7813
|
+
if (hash !== null && hashed2.has(hash)) return null;
|
|
7814
|
+
legacy.add(name);
|
|
7815
|
+
}
|
|
7816
|
+
return { ...plain2, name };
|
|
7817
|
+
})
|
|
7818
|
+
);
|
|
7819
|
+
legacyOnly = legacy;
|
|
7820
|
+
return decoded.filter((t) => t !== null);
|
|
7624
7821
|
},
|
|
7625
7822
|
putTopic: async (value, expectedVersion) => {
|
|
7626
7823
|
if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
|
|
7627
7824
|
throw new Error("Expected topic version must be a nonnegative integer");
|
|
7628
|
-
|
|
7825
|
+
const sealed2 = await codec.encodeCatalog(value);
|
|
7826
|
+
if (!sealed2) throw new Error("Topic name must not be empty");
|
|
7827
|
+
const saved = topic(
|
|
7629
7828
|
await request("/topics", {
|
|
7630
7829
|
method: "PUT",
|
|
7631
|
-
body: JSON.stringify({
|
|
7830
|
+
body: JSON.stringify({
|
|
7831
|
+
topic: sealed2,
|
|
7832
|
+
expected_version: legacyOnly.has(normalizeTopicName(value.name)) ? 0 : expectedVersion
|
|
7833
|
+
})
|
|
7632
7834
|
})
|
|
7633
7835
|
);
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7836
|
+
const decoded = await codec.decodeCatalog(saved);
|
|
7837
|
+
legacyOnly.delete(decoded.name);
|
|
7838
|
+
return decoded;
|
|
7839
|
+
},
|
|
7840
|
+
importTopics: (topics, signal) => sealedImport(
|
|
7841
|
+
request,
|
|
7842
|
+
codec,
|
|
7843
|
+
topics.map(({ name, kind }) => ({ name, ...kind !== void 0 && { kind } })),
|
|
7844
|
+
signal
|
|
7845
|
+
)
|
|
7846
|
+
};
|
|
7847
|
+
}
|
|
7848
|
+
async function retireLegacyTopics(request, codec, topics, imported, signal) {
|
|
7849
|
+
const failures = [];
|
|
7850
|
+
const put = async (topic2, expectedVersion) => {
|
|
7851
|
+
try {
|
|
7852
|
+
await request(
|
|
7853
|
+
"/topics",
|
|
7854
|
+
{ method: "PUT", body: JSON.stringify({ topic: topic2, expected_version: expectedVersion }) },
|
|
7855
|
+
signal
|
|
7856
|
+
);
|
|
7857
|
+
return "saved";
|
|
7858
|
+
} catch (error) {
|
|
7859
|
+
if (signal?.aborted) throw error;
|
|
7860
|
+
if (error instanceof RemoteMemoryError && error.status === 409) return "conflict";
|
|
7861
|
+
failures.push(error);
|
|
7862
|
+
return "failed";
|
|
7863
|
+
}
|
|
7864
|
+
};
|
|
7865
|
+
const retire = (item) => put(
|
|
7866
|
+
{ name: item.name, ...item.kind !== void 0 && { kind: item.kind }, is_deleted: true },
|
|
7867
|
+
item.version
|
|
7868
|
+
);
|
|
7869
|
+
const changed = [];
|
|
7870
|
+
let next = 0;
|
|
7871
|
+
const worker = async () => {
|
|
7872
|
+
while (next < topics.length) {
|
|
7647
7873
|
signal?.throwIfAborted();
|
|
7874
|
+
const item = topics[next++];
|
|
7875
|
+
if (await retire(item) === "conflict") changed.push(item);
|
|
7648
7876
|
}
|
|
7649
7877
|
};
|
|
7878
|
+
await Promise.all(
|
|
7879
|
+
Array.from({ length: Math.min(RETIRE_CONCURRENCY, topics.length) }, () => worker())
|
|
7880
|
+
);
|
|
7881
|
+
if (changed.length) {
|
|
7882
|
+
const current = await wireTopics(request, signal);
|
|
7883
|
+
for (const stale of changed) {
|
|
7884
|
+
const legacy = current.find((t) => t.name_hash === void 0 && t.name === stale.name);
|
|
7885
|
+
if (!legacy || legacy.is_deleted) continue;
|
|
7886
|
+
const hash = await codec.hash(await codec.open(legacy));
|
|
7887
|
+
const copy = current.find((t) => t.name_hash !== void 0 && t.name_hash === hash);
|
|
7888
|
+
if (!copy || hash === null) continue;
|
|
7889
|
+
const newer = imported.has(hash) || Date.parse(legacy.server_updated_at) > Date.parse(copy.server_updated_at);
|
|
7890
|
+
if (newer && (copy.is_deleted || legacy.kind !== copy.kind)) {
|
|
7891
|
+
const sealed2 = await codec.encodeCatalog({
|
|
7892
|
+
name: legacy.name,
|
|
7893
|
+
...legacy.kind !== void 0 && { kind: legacy.kind },
|
|
7894
|
+
is_deleted: false
|
|
7895
|
+
});
|
|
7896
|
+
if (!sealed2 || await put(sealed2, copy.version) !== "saved") continue;
|
|
7897
|
+
}
|
|
7898
|
+
await retire(legacy);
|
|
7899
|
+
}
|
|
7900
|
+
}
|
|
7901
|
+
if (failures.length)
|
|
7902
|
+
getLogger().warn(
|
|
7903
|
+
`[memory/remote] Could not retire ${failures.length} upgraded topic catalog entries:`,
|
|
7904
|
+
failures[0]
|
|
7905
|
+
);
|
|
7906
|
+
}
|
|
7907
|
+
async function upgradeLegacyTopicCatalog(request, codec, signal) {
|
|
7908
|
+
const items = await wireTopics(request, signal);
|
|
7909
|
+
const hashed2 = hashesOf(items);
|
|
7910
|
+
const hashes = await Promise.all(
|
|
7911
|
+
items.map(
|
|
7912
|
+
async (item) => item.name_hash === void 0 ? codec.hash(await codec.open(item)) : null
|
|
7913
|
+
)
|
|
7914
|
+
);
|
|
7915
|
+
const sources = /* @__PURE__ */ new Map();
|
|
7916
|
+
const live2 = [];
|
|
7917
|
+
items.forEach((item, i) => {
|
|
7918
|
+
const hash = hashes[i];
|
|
7919
|
+
if (hash === null) return;
|
|
7920
|
+
if (!item.is_deleted) live2.push(item);
|
|
7921
|
+
if (hashed2.has(hash)) return;
|
|
7922
|
+
const source = sources.get(hash);
|
|
7923
|
+
if (!source || source.is_deleted && !item.is_deleted) sources.set(hash, item);
|
|
7924
|
+
});
|
|
7925
|
+
const legacy = [...sources.values()].map((item) => ({
|
|
7926
|
+
name: item.name,
|
|
7927
|
+
...item.kind !== void 0 && { kind: item.kind },
|
|
7928
|
+
...item.is_deleted && { is_deleted: true }
|
|
7929
|
+
}));
|
|
7930
|
+
await sealedImport(request, codec, legacy, signal);
|
|
7931
|
+
await retireLegacyTopics(request, codec, live2, new Set(sources.keys()), signal);
|
|
7932
|
+
return legacy.length;
|
|
7650
7933
|
}
|
|
7651
7934
|
async function createRemoteTopic(persistence, name) {
|
|
7652
|
-
const canonical =
|
|
7935
|
+
const canonical = normalizeTopicName(name);
|
|
7653
7936
|
if (!canonical) return null;
|
|
7654
7937
|
const existing = (await persistence.topics()).find((t) => t.name === canonical);
|
|
7655
7938
|
if (existing && !existing.is_deleted) return canonical;
|
|
@@ -7738,7 +8021,10 @@ var RemoteMemoryError = class extends Error {
|
|
|
7738
8021
|
this.name = "RemoteMemoryError";
|
|
7739
8022
|
}
|
|
7740
8023
|
};
|
|
7741
|
-
var
|
|
8024
|
+
var TOPIC_UPGRADE_PROCESSOR = "topic-hash-v1";
|
|
8025
|
+
var TOPIC_UPGRADE_PAGE = 50;
|
|
8026
|
+
var LEGACY_TOPIC_CURSOR = "legacy-topics:";
|
|
8027
|
+
var LEGACY_TOPIC_RECHECK_MS = 6e4;
|
|
7742
8028
|
var memoryFields = {
|
|
7743
8029
|
memory_id: true,
|
|
7744
8030
|
content: true,
|
|
@@ -7798,7 +8084,8 @@ var queryFields = [
|
|
|
7798
8084
|
"fact_types",
|
|
7799
8085
|
"visibility",
|
|
7800
8086
|
"memory_ids",
|
|
7801
|
-
"
|
|
8087
|
+
"topic_hashes",
|
|
8088
|
+
"topics_legacy",
|
|
7802
8089
|
"updated_after",
|
|
7803
8090
|
"topics_due",
|
|
7804
8091
|
"topics_extracted",
|
|
@@ -7808,11 +8095,17 @@ var queryFields = [
|
|
|
7808
8095
|
"limit",
|
|
7809
8096
|
"include_embeddings"
|
|
7810
8097
|
];
|
|
7811
|
-
function
|
|
8098
|
+
function isVersionConflict(error) {
|
|
8099
|
+
return error instanceof RemoteMemoryError && error.code === "version_conflict";
|
|
8100
|
+
}
|
|
8101
|
+
function isRejectedRow(error) {
|
|
8102
|
+
return error instanceof RemoteMemoryError && error.status === 400;
|
|
8103
|
+
}
|
|
8104
|
+
function record2(value) {
|
|
7812
8105
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7813
8106
|
}
|
|
7814
8107
|
function memoryRecord(value) {
|
|
7815
|
-
if (!
|
|
8108
|
+
if (!record2(value) || !record2(value.memory) || typeof value.memory.memory_id !== "string" || typeof value.memory.content !== "string" || typeof value.memory.scope !== "string" || typeof value.memory.created_at !== "number" || typeof value.memory.updated_at !== "number" || typeof value.memory.is_deleted !== "boolean" || !Number.isSafeInteger(value.version) || value.version < 1 || typeof value.server_updated_at !== "string" || value.score !== void 0 && (typeof value.score !== "number" || !Number.isFinite(value.score))) {
|
|
7816
8109
|
throw new Error("Invalid nearby private-memory response");
|
|
7817
8110
|
}
|
|
7818
8111
|
return value;
|
|
@@ -7892,14 +8185,14 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
|
|
|
7892
8185
|
const body = await response.json().catch(() => null);
|
|
7893
8186
|
const retryAfter = parseRetryAfterMs(response.headers.get("Retry-After"));
|
|
7894
8187
|
const error = new RemoteMemoryError(
|
|
7895
|
-
|
|
8188
|
+
record2(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
|
|
7896
8189
|
response.status,
|
|
7897
|
-
|
|
8190
|
+
record2(body) && typeof body.code === "string" ? body.code : void 0,
|
|
7898
8191
|
retryAfter ?? void 0,
|
|
7899
|
-
|
|
8192
|
+
record2(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
|
|
7900
8193
|
);
|
|
7901
8194
|
if (response.status === 429 && retryAfter !== null && retryAfter > 0 && (!error.code || error.code === "rate_limited")) {
|
|
7902
|
-
const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket :
|
|
8195
|
+
const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record2(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
|
|
7903
8196
|
cooldowns.set(bucket, { until: Date.now() + retryAfter, error });
|
|
7904
8197
|
}
|
|
7905
8198
|
throw error;
|
|
@@ -7922,7 +8215,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
7922
8215
|
throw new Error("A canonical keyId is required");
|
|
7923
8216
|
const request = createNearbyRequest(options);
|
|
7924
8217
|
const account = await request("/account", {}, options.signal);
|
|
7925
|
-
if (!
|
|
8218
|
+
if (!record2(account) || account.state !== "active") {
|
|
7926
8219
|
throw new RemoteMemoryError(
|
|
7927
8220
|
"Complete and verify migration before using remote memories",
|
|
7928
8221
|
409,
|
|
@@ -7936,6 +8229,25 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
7936
8229
|
"key_mismatch"
|
|
7937
8230
|
);
|
|
7938
8231
|
}
|
|
8232
|
+
const codec = createTopicCodec(options);
|
|
8233
|
+
let legacyTopicRows = typeof account.legacy_topic_memories === "number" && account.legacy_topic_memories > 0;
|
|
8234
|
+
if (typeof account.legacy_topic_catalog === "number" && account.legacy_topic_catalog > 0)
|
|
8235
|
+
void upgradeLegacyTopicCatalog(request, codec, options.signal).catch((error) => {
|
|
8236
|
+
if (!options.signal?.aborted)
|
|
8237
|
+
getLogger().warn("[memory/remote] Topic catalog upgrade failed:", error);
|
|
8238
|
+
});
|
|
8239
|
+
let legacyCheckedAt = Date.now();
|
|
8240
|
+
let legacyCheck;
|
|
8241
|
+
const recheckLegacyTopicRows = () => {
|
|
8242
|
+
if (legacyCheck || Date.now() - legacyCheckedAt < LEGACY_TOPIC_RECHECK_MS) return;
|
|
8243
|
+
legacyCheckedAt = Date.now();
|
|
8244
|
+
legacyCheck = request("/account", {}, options.signal).then((current) => {
|
|
8245
|
+
if (record2(current) && current.legacy_topic_memories === 0) legacyTopicRows = false;
|
|
8246
|
+
}).catch(() => {
|
|
8247
|
+
}).finally(() => {
|
|
8248
|
+
legacyCheck = void 0;
|
|
8249
|
+
});
|
|
8250
|
+
};
|
|
7939
8251
|
const snapshots = /* @__PURE__ */ new WeakMap();
|
|
7940
8252
|
const decode = async (value) => {
|
|
7941
8253
|
const item = memoryRecord(value);
|
|
@@ -7953,6 +8265,9 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
7953
8265
|
content: item.memory.is_deleted && item.memory.content === "" ? "" : await decrypt(item.memory.content),
|
|
7954
8266
|
...item.memory.kind_value !== void 0 && {
|
|
7955
8267
|
kind_value: await decrypt(item.memory.kind_value)
|
|
8268
|
+
},
|
|
8269
|
+
...item.memory.topics !== void 0 && {
|
|
8270
|
+
topics: await codec.decodeTopics(item.memory.topics)
|
|
7956
8271
|
}
|
|
7957
8272
|
}
|
|
7958
8273
|
};
|
|
@@ -7964,8 +8279,10 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
7964
8279
|
version: item.version,
|
|
7965
8280
|
content: decoded.memory.content,
|
|
7966
8281
|
kindValue: decoded.memory.kind_value,
|
|
8282
|
+
topics: decoded.memory.topics,
|
|
7967
8283
|
encryptedContent: item.memory.content,
|
|
7968
|
-
encryptedKindValue: item.memory.kind_value
|
|
8284
|
+
encryptedKindValue: item.memory.kind_value,
|
|
8285
|
+
encryptedTopics: item.memory.topics
|
|
7969
8286
|
});
|
|
7970
8287
|
return decoded;
|
|
7971
8288
|
};
|
|
@@ -7987,7 +8304,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
7987
8304
|
};
|
|
7988
8305
|
const decodeCommitted = async (value, write) => {
|
|
7989
8306
|
const item = memoryRecord(value);
|
|
7990
|
-
if (item.memory.memory_id !== write.body.memory.memory_id || item.memory.content !== write.body.memory.content || item.memory.kind_value !== write.body.memory.kind_value)
|
|
8307
|
+
if (item.memory.memory_id !== write.body.memory.memory_id || item.memory.content !== write.body.memory.content || item.memory.kind_value !== write.body.memory.kind_value || item.memory.topics !== write.body.memory.topics)
|
|
7991
8308
|
return decode(item);
|
|
7992
8309
|
return remember(
|
|
7993
8310
|
{
|
|
@@ -7995,7 +8312,8 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
7995
8312
|
memory: {
|
|
7996
8313
|
...item.memory,
|
|
7997
8314
|
content: write.content,
|
|
7998
|
-
...write.kindValue !== void 0 && { kind_value: write.kindValue }
|
|
8315
|
+
...write.kindValue !== void 0 && { kind_value: write.kindValue },
|
|
8316
|
+
...write.topics !== void 0 && { topics: write.topics }
|
|
7999
8317
|
}
|
|
8000
8318
|
},
|
|
8001
8319
|
item
|
|
@@ -8047,13 +8365,21 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
8047
8365
|
const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
|
|
8048
8366
|
const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
|
|
8049
8367
|
const kindValue = memory.kind_value === void 0 ? void 0 : (snapshot?.kindValue ?? decoded?.memory.kind_value) === memory.kind_value ? snapshot?.encryptedKindValue ?? existing.memory.kind_value : await encryptField2(memory.kind_value);
|
|
8368
|
+
const wireTopics2 = snapshot ? snapshot.encryptedTopics : existing?.memory.topics;
|
|
8369
|
+
const topics = memory.topics === void 0 ? void 0 : (snapshot?.topics ?? decoded?.memory.topics) === memory.topics && wireTopics2 !== void 0 && !codec.isLegacy(wireTopics2) ? wireTopics2 : await codec.encodeTopics(memory.topics);
|
|
8050
8370
|
return {
|
|
8051
8371
|
body: {
|
|
8052
8372
|
expected_version: expectedVersion,
|
|
8053
|
-
memory: {
|
|
8373
|
+
memory: {
|
|
8374
|
+
...memory,
|
|
8375
|
+
content,
|
|
8376
|
+
...kindValue !== void 0 && { kind_value: kindValue },
|
|
8377
|
+
...topics !== void 0 && { topics }
|
|
8378
|
+
}
|
|
8054
8379
|
},
|
|
8055
8380
|
content: memory.content,
|
|
8056
|
-
kindValue: memory.kind_value
|
|
8381
|
+
kindValue: memory.kind_value,
|
|
8382
|
+
topics: memory.topics
|
|
8057
8383
|
};
|
|
8058
8384
|
};
|
|
8059
8385
|
const fetchCandidates = async (embedding2, candidateOptions, withCounts) => {
|
|
@@ -8102,32 +8428,72 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
8102
8428
|
},
|
|
8103
8429
|
candidateOptions.signal
|
|
8104
8430
|
);
|
|
8105
|
-
if (!
|
|
8431
|
+
if (!record2(result) || !Array.isArray(result.items))
|
|
8106
8432
|
throw new Error("Invalid nearby candidate response");
|
|
8107
8433
|
return result;
|
|
8108
8434
|
};
|
|
8109
8435
|
const fetchQueryPage = async (queryOptions) => {
|
|
8110
|
-
const { signal, ...
|
|
8111
|
-
if (
|
|
8436
|
+
const { signal, topics: names, ...wire2 } = queryOptions;
|
|
8437
|
+
if (wire2.limit !== void 0 && (!Number.isInteger(wire2.limit) || wire2.limit < 1 || wire2.limit > 200))
|
|
8112
8438
|
throw new Error("Page limit must be 1\u2013200");
|
|
8113
8439
|
for (const [key3, max] of queryListLimits) {
|
|
8114
|
-
const values =
|
|
8440
|
+
const values = queryOptions[key3];
|
|
8115
8441
|
if (values && values.length > max)
|
|
8116
8442
|
throw new Error(`Query ${key3} accepts at most ${max} entries (got ${values.length})`);
|
|
8117
8443
|
}
|
|
8444
|
+
const body = wire2;
|
|
8445
|
+
if (names === void 0) return postQuery(body, signal);
|
|
8446
|
+
const hashes = [
|
|
8447
|
+
...new Set(
|
|
8448
|
+
(await Promise.all(names.map((name) => codec.hash(name)))).filter((h) => h !== null)
|
|
8449
|
+
)
|
|
8450
|
+
];
|
|
8451
|
+
if (names.length > 0 && hashes.length === 0) return { items: [] };
|
|
8452
|
+
if (hashes.length > 0 && wire2.cursor?.startsWith(LEGACY_TOPIC_CURSOR)) {
|
|
8453
|
+
const page2 = await postQuery(
|
|
8454
|
+
{
|
|
8455
|
+
...wire2,
|
|
8456
|
+
cursor: wire2.cursor.slice(LEGACY_TOPIC_CURSOR.length) || void 0,
|
|
8457
|
+
topics_legacy: true
|
|
8458
|
+
},
|
|
8459
|
+
signal
|
|
8460
|
+
);
|
|
8461
|
+
const wanted = new Set(names.map(normalizeTopicName));
|
|
8462
|
+
const hashed2 = new Set(hashes);
|
|
8463
|
+
const matches = await Promise.all(
|
|
8464
|
+
page2.items.map(
|
|
8465
|
+
(item) => codec.matchesLegacy(
|
|
8466
|
+
record2(item) && record2(item.memory) ? item.memory.topics : void 0,
|
|
8467
|
+
wanted,
|
|
8468
|
+
hashed2
|
|
8469
|
+
)
|
|
8470
|
+
)
|
|
8471
|
+
);
|
|
8472
|
+
return {
|
|
8473
|
+
...page2,
|
|
8474
|
+
items: page2.items.filter((_, i) => matches[i]),
|
|
8475
|
+
next_cursor: page2.next_cursor === void 0 ? void 0 : LEGACY_TOPIC_CURSOR + page2.next_cursor
|
|
8476
|
+
};
|
|
8477
|
+
}
|
|
8478
|
+
const page = await postQuery({ ...body, topic_hashes: hashes }, signal);
|
|
8479
|
+
if (hashes.length === 0 || page.next_cursor !== void 0 || !legacyTopicRows) return page;
|
|
8480
|
+
recheckLegacyTopicRows();
|
|
8481
|
+
return { ...page, next_cursor: LEGACY_TOPIC_CURSOR };
|
|
8482
|
+
};
|
|
8483
|
+
const postQuery = async (body, signal) => {
|
|
8118
8484
|
const page = await request(
|
|
8119
8485
|
"/memories/query",
|
|
8120
8486
|
{
|
|
8121
8487
|
method: "POST",
|
|
8122
8488
|
body: JSON.stringify(
|
|
8123
8489
|
Object.fromEntries(
|
|
8124
|
-
queryFields.filter((key3) =>
|
|
8490
|
+
queryFields.filter((key3) => body[key3] !== void 0).map((key3) => [key3, body[key3]])
|
|
8125
8491
|
)
|
|
8126
8492
|
)
|
|
8127
8493
|
},
|
|
8128
8494
|
signal
|
|
8129
8495
|
);
|
|
8130
|
-
if (!
|
|
8496
|
+
if (!record2(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")
|
|
8131
8497
|
throw new Error("Invalid nearby private-memory page");
|
|
8132
8498
|
return page;
|
|
8133
8499
|
};
|
|
@@ -8141,13 +8507,13 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
8141
8507
|
unavailable_count: result.unavailable_count
|
|
8142
8508
|
};
|
|
8143
8509
|
};
|
|
8144
|
-
|
|
8145
|
-
...createRemoteTopicPersistence(request),
|
|
8510
|
+
const persistence = {
|
|
8511
|
+
...createRemoteTopicPersistence(request, codec),
|
|
8146
8512
|
...createRemoteWorkPersistence(request),
|
|
8147
8513
|
supportsRealtimeChanges: account.realtime_changes === true,
|
|
8148
8514
|
counts: async () => {
|
|
8149
8515
|
const result = await request("/counts", {});
|
|
8150
|
-
if (!
|
|
8516
|
+
if (!record2(result) || ["live", "archived", "quarantined"].some(
|
|
8151
8517
|
(key3) => !Number.isSafeInteger(result[key3]) || result[key3] < 0
|
|
8152
8518
|
))
|
|
8153
8519
|
throw new Error("Invalid nearby memory counts");
|
|
@@ -8164,8 +8530,8 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
8164
8530
|
method: "POST",
|
|
8165
8531
|
body: JSON.stringify({ ...window2, limit })
|
|
8166
8532
|
});
|
|
8167
|
-
if (!
|
|
8168
|
-
(item) => !
|
|
8533
|
+
if (!record2(result) || !Array.isArray(result.items) || result.items.some(
|
|
8534
|
+
(item) => !record2(item) || typeof item.memory_id !== "string" || !item.memory_id || typeof item.score !== "number" || !Number.isFinite(item.score) || item.score <= 0 || item.score > 1
|
|
8169
8535
|
))
|
|
8170
8536
|
throw new Error("Invalid nearby temporal candidates");
|
|
8171
8537
|
return result.items.map((item) => item.memory_id);
|
|
@@ -8196,7 +8562,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
8196
8562
|
if (query[key3] !== void 0) params.set(key3, String(query[key3]));
|
|
8197
8563
|
}
|
|
8198
8564
|
const page = await request("/memories?" + params.toString(), {}, signal);
|
|
8199
|
-
if (!
|
|
8565
|
+
if (!record2(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
|
|
8200
8566
|
throw new Error("Invalid nearby private-memory page");
|
|
8201
8567
|
}
|
|
8202
8568
|
return {
|
|
@@ -8236,7 +8602,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
8236
8602
|
},
|
|
8237
8603
|
signal
|
|
8238
8604
|
);
|
|
8239
|
-
if (!
|
|
8605
|
+
if (!record2(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
|
|
8240
8606
|
throw new Error("Invalid nearby batch response");
|
|
8241
8607
|
return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
|
|
8242
8608
|
},
|
|
@@ -8251,20 +8617,87 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
8251
8617
|
queryMetadata: async (queryOptions = {}) => {
|
|
8252
8618
|
const page = await fetchQueryPage(queryOptions);
|
|
8253
8619
|
return {
|
|
8254
|
-
items:
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8620
|
+
items: await Promise.all(
|
|
8621
|
+
page.items.map(async (item) => {
|
|
8622
|
+
const {
|
|
8623
|
+
memory: { content: _content, kind_value: _kindValue, topics, ...memory },
|
|
8624
|
+
version,
|
|
8625
|
+
server_updated_at
|
|
8626
|
+
} = memoryRecord(item);
|
|
8627
|
+
const plain2 = topics === void 0 ? void 0 : await codec.decodeTopics(topics).catch(() => null);
|
|
8628
|
+
return {
|
|
8629
|
+
memory: { ...memory, ...typeof plain2 === "string" && { topics: plain2 } },
|
|
8630
|
+
version,
|
|
8631
|
+
server_updated_at
|
|
8632
|
+
};
|
|
8633
|
+
})
|
|
8634
|
+
),
|
|
8262
8635
|
...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
|
|
8263
8636
|
};
|
|
8264
8637
|
},
|
|
8265
8638
|
candidateSet,
|
|
8266
8639
|
candidates: async (embedding2, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding2, candidateOptions, false)).items)
|
|
8267
8640
|
};
|
|
8641
|
+
let rejectedRows = 0;
|
|
8642
|
+
const rewriteLegacyTopics = async (records, token) => {
|
|
8643
|
+
const write = (batch) => persistence.putMany(
|
|
8644
|
+
batch.map((item) => ({ memory: item.memory, expectedVersion: item })),
|
|
8645
|
+
options.signal,
|
|
8646
|
+
token
|
|
8647
|
+
);
|
|
8648
|
+
try {
|
|
8649
|
+
await write(records);
|
|
8650
|
+
return true;
|
|
8651
|
+
} catch (error) {
|
|
8652
|
+
if (!isVersionConflict(error) && !isRejectedRow(error)) throw error;
|
|
8653
|
+
if (records.length === 1) {
|
|
8654
|
+
if (isRejectedRow(error)) rejectedRows++;
|
|
8655
|
+
return false;
|
|
8656
|
+
}
|
|
8657
|
+
let complete = true;
|
|
8658
|
+
for (const item of records)
|
|
8659
|
+
await write([item]).catch((rowError) => {
|
|
8660
|
+
if (isRejectedRow(rowError)) rejectedRows++;
|
|
8661
|
+
else if (!isVersionConflict(rowError)) throw rowError;
|
|
8662
|
+
complete = false;
|
|
8663
|
+
});
|
|
8664
|
+
return complete;
|
|
8665
|
+
}
|
|
8666
|
+
};
|
|
8667
|
+
const upgradeLegacyTopics = () => withRemoteWorkLease(persistence, "topics", TOPIC_UPGRADE_PROCESSOR, async (token, lease) => {
|
|
8668
|
+
let cursor;
|
|
8669
|
+
let complete = true;
|
|
8670
|
+
do {
|
|
8671
|
+
options.signal?.throwIfAborted();
|
|
8672
|
+
if (lease.aborted) return false;
|
|
8673
|
+
const page = await fetchQueryPage({
|
|
8674
|
+
topics_legacy: true,
|
|
8675
|
+
include_archived: true,
|
|
8676
|
+
include_quarantined: true,
|
|
8677
|
+
include_superseded: true,
|
|
8678
|
+
limit: TOPIC_UPGRADE_PAGE,
|
|
8679
|
+
...cursor !== void 0 && { cursor },
|
|
8680
|
+
signal: options.signal
|
|
8681
|
+
});
|
|
8682
|
+
const { items } = await decodeAll(page.items);
|
|
8683
|
+
const legacy = items.filter((item) => codec.isLegacy(snapshots.get(item)?.encryptedTopics));
|
|
8684
|
+
if (legacy.length && !await rewriteLegacyTopics(legacy, token)) complete = false;
|
|
8685
|
+
cursor = page.next_cursor;
|
|
8686
|
+
} while (cursor);
|
|
8687
|
+
if (rejectedRows)
|
|
8688
|
+
getLogger().warn(
|
|
8689
|
+
`[memory/remote] Nearby rejected ${rejectedRows} rows during the topic upgrade; they keep legacy topics`
|
|
8690
|
+
);
|
|
8691
|
+
return complete;
|
|
8692
|
+
});
|
|
8693
|
+
if (legacyTopicRows)
|
|
8694
|
+
void upgradeLegacyTopics().then((complete) => {
|
|
8695
|
+
if (complete) legacyTopicRows = false;
|
|
8696
|
+
}).catch((error) => {
|
|
8697
|
+
if (!options.signal?.aborted)
|
|
8698
|
+
getLogger().warn("[memory/remote] Topic upgrade failed:", error);
|
|
8699
|
+
});
|
|
8700
|
+
return persistence;
|
|
8268
8701
|
}
|
|
8269
8702
|
|
|
8270
8703
|
// src/lib/chat/inbox.ts
|
|
@@ -8354,6 +8787,67 @@ async function openInboxItem(item, keyPair) {
|
|
|
8354
8787
|
}
|
|
8355
8788
|
return opened;
|
|
8356
8789
|
}
|
|
8790
|
+
function inboxReplaces(row, opened) {
|
|
8791
|
+
if (row.error) return true;
|
|
8792
|
+
return row.wasStopped === true && opened.status === "completed";
|
|
8793
|
+
}
|
|
8794
|
+
async function clearTurnErrors(backend, answer) {
|
|
8795
|
+
const parentId = answer.parentMessageId;
|
|
8796
|
+
if (parentId) {
|
|
8797
|
+
const [parent] = await backend.getMessagesByIds([parentId]);
|
|
8798
|
+
if (parent?.error) await backend.updateMessageError(parentId, null);
|
|
8799
|
+
}
|
|
8800
|
+
if (!answer.error) return answer;
|
|
8801
|
+
return await backend.updateMessageError(answer.uniqueId, null) ?? answer;
|
|
8802
|
+
}
|
|
8803
|
+
async function deliverInboxAnswers(options) {
|
|
8804
|
+
const { inbox, keyPair, backend, store } = options;
|
|
8805
|
+
const results = [];
|
|
8806
|
+
for (const item of await inbox.list()) {
|
|
8807
|
+
let opened;
|
|
8808
|
+
try {
|
|
8809
|
+
opened = await openInboxItem(item, keyPair);
|
|
8810
|
+
} catch (err) {
|
|
8811
|
+
results.push({
|
|
8812
|
+
id: item.id,
|
|
8813
|
+
conversationId: null,
|
|
8814
|
+
status: "unreadable",
|
|
8815
|
+
assistantMessage: null,
|
|
8816
|
+
error: err instanceof Error ? err.message : String(err)
|
|
8817
|
+
});
|
|
8818
|
+
continue;
|
|
8819
|
+
}
|
|
8820
|
+
const base = { id: item.id, conversationId: opened.conversation_id };
|
|
8821
|
+
try {
|
|
8822
|
+
const messageId = opened.assistant_message_id ?? `msg_bg_${opened.inference_id}`;
|
|
8823
|
+
const [found] = await backend.getMessagesByIds([messageId]);
|
|
8824
|
+
const existing = found && inboxReplaces(found, opened) ? void 0 : found;
|
|
8825
|
+
if (!found) {
|
|
8826
|
+
const parent = opened.parent_message_id;
|
|
8827
|
+
const ownsTurn = parent ? (await backend.getMessagesByIds([parent])).length > 0 : await backend.getConversation(opened.conversation_id) !== null;
|
|
8828
|
+
if (!ownsTurn) {
|
|
8829
|
+
results.push({ ...base, status: "elsewhere", assistantMessage: null });
|
|
8830
|
+
continue;
|
|
8831
|
+
}
|
|
8832
|
+
}
|
|
8833
|
+
const stored2 = existing ?? await store(opened, messageId);
|
|
8834
|
+
await inbox.remove(item.id);
|
|
8835
|
+
results.push({
|
|
8836
|
+
...base,
|
|
8837
|
+
status: existing ? "delivered" : "stored",
|
|
8838
|
+
assistantMessage: stored2
|
|
8839
|
+
});
|
|
8840
|
+
} catch (err) {
|
|
8841
|
+
results.push({
|
|
8842
|
+
...base,
|
|
8843
|
+
status: "retry",
|
|
8844
|
+
assistantMessage: null,
|
|
8845
|
+
error: err instanceof Error ? err.message : String(err)
|
|
8846
|
+
});
|
|
8847
|
+
}
|
|
8848
|
+
}
|
|
8849
|
+
return results;
|
|
8850
|
+
}
|
|
8357
8851
|
|
|
8358
8852
|
// src/lib/chat/reservationReceipts.ts
|
|
8359
8853
|
var ACTIONS = [
|
|
@@ -8765,9 +9259,9 @@ function toResponsesFormat(tool) {
|
|
|
8765
9259
|
function getCachedServerTools() {
|
|
8766
9260
|
if (typeof localStorage === "undefined") return null;
|
|
8767
9261
|
try {
|
|
8768
|
-
const
|
|
8769
|
-
if (!
|
|
8770
|
-
const parsed = JSON.parse(
|
|
9262
|
+
const cached2 = localStorage.getItem(SERVER_TOOLS_CACHE_KEY);
|
|
9263
|
+
if (!cached2) return null;
|
|
9264
|
+
const parsed = JSON.parse(cached2);
|
|
8771
9265
|
if (parsed.version !== CACHE_VERSION) {
|
|
8772
9266
|
removeLocalStorageCache();
|
|
8773
9267
|
return null;
|
|
@@ -8811,8 +9305,8 @@ function clearServerToolsCache(cache = localStorageToolsCache) {
|
|
|
8811
9305
|
return cache.clear?.();
|
|
8812
9306
|
}
|
|
8813
9307
|
function getToolsChecksum2(cache = localStorageToolsCache) {
|
|
8814
|
-
const
|
|
8815
|
-
return
|
|
9308
|
+
const cached2 = cache.get();
|
|
9309
|
+
return cached2 instanceof Promise ? cached2.then((c) => c?.checksum) : cached2?.checksum;
|
|
8816
9310
|
}
|
|
8817
9311
|
function shouldRefreshTools(responseChecksum, cache = localStorageToolsCache) {
|
|
8818
9312
|
if (!responseChecksum) {
|
|
@@ -8875,33 +9369,33 @@ async function getServerTools(options) {
|
|
|
8875
9369
|
} catch (error) {
|
|
8876
9370
|
getLogger().warn("[serverTools] Cache read failed; falling through to server fetch:", error);
|
|
8877
9371
|
}
|
|
8878
|
-
const
|
|
8879
|
-
const cacheValid = !isCacheExpired(
|
|
8880
|
-
if (
|
|
8881
|
-
return
|
|
9372
|
+
const cached2 = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
|
|
9373
|
+
const cacheValid = !isCacheExpired(cached2, cacheExpirationMs);
|
|
9374
|
+
if (cached2 && cacheValid && !forceRefresh) {
|
|
9375
|
+
return cached2.tools;
|
|
8882
9376
|
}
|
|
8883
9377
|
try {
|
|
8884
9378
|
const { BASE_URL: BASE_URL2 } = await Promise.resolve().then(() => (init_clientConfig(), clientConfig_exports));
|
|
8885
9379
|
const effectiveBaseUrl = baseUrl ?? BASE_URL2;
|
|
8886
|
-
const validator =
|
|
9380
|
+
const validator = cached2 && !forceRefresh ? cached2.etag : void 0;
|
|
8887
9381
|
let authHeaders;
|
|
8888
9382
|
if (apiKey) {
|
|
8889
9383
|
authHeaders = { "X-API-Key": apiKey };
|
|
8890
9384
|
} else {
|
|
8891
9385
|
if (!getToken) {
|
|
8892
9386
|
getLogger().warn("[serverTools] No auth method available for fetching tools");
|
|
8893
|
-
return
|
|
9387
|
+
return cached2?.tools ?? [];
|
|
8894
9388
|
}
|
|
8895
9389
|
const token = await getToken();
|
|
8896
9390
|
if (!token) {
|
|
8897
9391
|
getLogger().warn("[serverTools] No auth token available for fetching tools");
|
|
8898
|
-
return
|
|
9392
|
+
return cached2?.tools ?? [];
|
|
8899
9393
|
}
|
|
8900
9394
|
authHeaders = { Authorization: `Bearer ${token}` };
|
|
8901
9395
|
}
|
|
8902
9396
|
const result = await fetchServerToolsFromApi(effectiveBaseUrl, authHeaders, validator);
|
|
8903
9397
|
if (result.notModified) {
|
|
8904
|
-
const confirmed =
|
|
9398
|
+
const confirmed = cached2;
|
|
8905
9399
|
await persistCache({ ...confirmed, timestamp: Date.now() });
|
|
8906
9400
|
return confirmed.tools;
|
|
8907
9401
|
}
|
|
@@ -8909,9 +9403,9 @@ async function getServerTools(options) {
|
|
|
8909
9403
|
return result.tools;
|
|
8910
9404
|
} catch (error) {
|
|
8911
9405
|
getLogger().error("[serverTools] Failed to fetch server tools:", error);
|
|
8912
|
-
if (
|
|
9406
|
+
if (cached2?.tools) {
|
|
8913
9407
|
getLogger().warn("[serverTools] Using stale cached tools due to fetch error");
|
|
8914
|
-
return
|
|
9408
|
+
return cached2.tools;
|
|
8915
9409
|
}
|
|
8916
9410
|
return [];
|
|
8917
9411
|
}
|
|
@@ -9845,6 +10339,13 @@ function createErrorResult(message, onError) {
|
|
|
9845
10339
|
function isAbortError(err) {
|
|
9846
10340
|
return err instanceof Error && err.name === "AbortError";
|
|
9847
10341
|
}
|
|
10342
|
+
var ProviderStreamError = class extends Error {
|
|
10343
|
+
constructor(message, code) {
|
|
10344
|
+
super(message);
|
|
10345
|
+
this.name = "ProviderStreamError";
|
|
10346
|
+
this.code = code;
|
|
10347
|
+
}
|
|
10348
|
+
};
|
|
9848
10349
|
function getInStreamErrorMessage(chunk) {
|
|
9849
10350
|
if (!chunk || typeof chunk !== "object") return null;
|
|
9850
10351
|
const obj = chunk;
|
|
@@ -10042,13 +10543,13 @@ function extractParamGroups(content) {
|
|
|
10042
10543
|
}
|
|
10043
10544
|
function mergeXaiInlineParameterTags(content, toolCalls) {
|
|
10044
10545
|
if (!content || !content.includes(PARAM_MARKER)) return content;
|
|
10045
|
-
const
|
|
10046
|
-
if (
|
|
10546
|
+
const entries2 = Array.from(toolCalls.values());
|
|
10547
|
+
if (entries2.length === 0) return content;
|
|
10047
10548
|
const groups = extractParamGroups(content);
|
|
10048
10549
|
if (groups.length === 0) return content;
|
|
10049
|
-
const pairCount = Math.min(groups.length,
|
|
10550
|
+
const pairCount = Math.min(groups.length, entries2.length);
|
|
10050
10551
|
for (let i = 0; i < pairCount; i++) {
|
|
10051
|
-
const target =
|
|
10552
|
+
const target = entries2[i];
|
|
10052
10553
|
const params = groups[i];
|
|
10053
10554
|
if (!target || !params) continue;
|
|
10054
10555
|
let args = {};
|
|
@@ -10131,7 +10632,7 @@ var CompletionsStrategy = class {
|
|
|
10131
10632
|
processStreamChunk(chunk, accumulator) {
|
|
10132
10633
|
const result = { content: null, thinking: null };
|
|
10133
10634
|
const inStreamErr = getInStreamErrorMessage(chunk);
|
|
10134
|
-
if (inStreamErr) throw new
|
|
10635
|
+
if (inStreamErr) throw new ProviderStreamError(inStreamErr);
|
|
10135
10636
|
const rawChunk = chunk;
|
|
10136
10637
|
const typedChunk = rawChunk.response && rawChunk.type === "response" ? rawChunk.response : chunk;
|
|
10137
10638
|
if (typedChunk.id && !accumulator.responseId) {
|
|
@@ -10982,7 +11483,7 @@ var ResponsesStrategy = class {
|
|
|
10982
11483
|
const result = { content: null, thinking: null };
|
|
10983
11484
|
const typedChunk = chunk;
|
|
10984
11485
|
const inStreamErr = getInStreamErrorMessage(chunk);
|
|
10985
|
-
if (inStreamErr) throw new
|
|
11486
|
+
if (inStreamErr) throw new ProviderStreamError(inStreamErr);
|
|
10986
11487
|
if (typedChunk.type === "response.failed") {
|
|
10987
11488
|
const resp = typedChunk.response;
|
|
10988
11489
|
const err = resp?.error;
|
|
@@ -10999,9 +11500,12 @@ var ResponsesStrategy = class {
|
|
|
10999
11500
|
}
|
|
11000
11501
|
}
|
|
11001
11502
|
const label = code ? `[${code}] ` : "";
|
|
11002
|
-
throw new
|
|
11503
|
+
throw new ProviderStreamError(
|
|
11504
|
+
`${label}${message || "Upstream request failed"}`,
|
|
11505
|
+
code || void 0
|
|
11506
|
+
);
|
|
11003
11507
|
}
|
|
11004
|
-
throw new
|
|
11508
|
+
throw new ProviderStreamError("Upstream request failed (response.failed)");
|
|
11005
11509
|
}
|
|
11006
11510
|
if (typedChunk.type === "response" && typedChunk.response) {
|
|
11007
11511
|
const resp = typedChunk.response;
|
|
@@ -11625,13 +12129,6 @@ function isRetriableStreamError(err) {
|
|
|
11625
12129
|
if (msg.includes("connection refused") || msg.includes("connect error")) return true;
|
|
11626
12130
|
return false;
|
|
11627
12131
|
}
|
|
11628
|
-
var ProviderStreamError = class extends Error {
|
|
11629
|
-
constructor(message, code) {
|
|
11630
|
-
super(message);
|
|
11631
|
-
this.name = "ProviderStreamError";
|
|
11632
|
-
this.code = code;
|
|
11633
|
-
}
|
|
11634
|
-
};
|
|
11635
12132
|
function extractProviderStreamError(chunk) {
|
|
11636
12133
|
if (!chunk || typeof chunk !== "object") return null;
|
|
11637
12134
|
const errField = chunk.error;
|
|
@@ -12012,6 +12509,7 @@ async function runToolLoop(options) {
|
|
|
12012
12509
|
thinking: redactor.deAnonymize(acc.thinking)
|
|
12013
12510
|
}) : strategy.buildFinalResponse(acc);
|
|
12014
12511
|
const finalContentText = (acc) => redactor ? redactor.deAnonymize(acc.content) : acc.content;
|
|
12512
|
+
let streamingAccumulator = null;
|
|
12015
12513
|
try {
|
|
12016
12514
|
let sseError = null;
|
|
12017
12515
|
let apiTools = toolsToApiFormat(tools, resolved);
|
|
@@ -12163,6 +12661,7 @@ async function runToolLoop(options) {
|
|
|
12163
12661
|
}
|
|
12164
12662
|
});
|
|
12165
12663
|
accumulator = createStreamAccumulator(model || void 0);
|
|
12664
|
+
streamingAccumulator = accumulator;
|
|
12166
12665
|
contentSmoother = new StreamSmoother((text16) => {
|
|
12167
12666
|
if (emitData) emitData(text16);
|
|
12168
12667
|
}, smoothing);
|
|
@@ -12673,6 +13172,7 @@ Executing tool: ${toolInfo}
|
|
|
12673
13172
|
}
|
|
12674
13173
|
});
|
|
12675
13174
|
currentAccumulator = createStreamAccumulator(model || void 0);
|
|
13175
|
+
streamingAccumulator = currentAccumulator;
|
|
12676
13176
|
contContentSmoother = new StreamSmoother((text16) => {
|
|
12677
13177
|
if (emitData) emitData(text16);
|
|
12678
13178
|
}, smoothing);
|
|
@@ -12870,7 +13370,7 @@ Executing tool: ${toolInfo}
|
|
|
12870
13370
|
const statusCode = err instanceof Error && "statusCode" in err ? err.statusCode : void 0;
|
|
12871
13371
|
const connectionLost = !(err instanceof ProviderStreamError) && !(err instanceof SseError);
|
|
12872
13372
|
return {
|
|
12873
|
-
data: null,
|
|
13373
|
+
data: connectionLost && streamingAccumulator ? buildResponseFinal(streamingAccumulator) : null,
|
|
12874
13374
|
error: errorMsg,
|
|
12875
13375
|
statusCode,
|
|
12876
13376
|
...connectionLost ? { connectionLost: true } : {}
|
|
@@ -13371,21 +13871,21 @@ function contextFields(context) {
|
|
|
13371
13871
|
);
|
|
13372
13872
|
}
|
|
13373
13873
|
function conversationContext(data) {
|
|
13374
|
-
const
|
|
13375
|
-
return
|
|
13874
|
+
const entries2 = Object.entries(data).filter(([field10]) => field10.startsWith(CONTEXT_FIELD_PREFIX)).map(([field10, value]) => [field10.slice(CONTEXT_FIELD_PREFIX.length), value]);
|
|
13875
|
+
return entries2.length > 0 ? plain(Object.fromEntries(entries2)) : void 0;
|
|
13376
13876
|
}
|
|
13377
|
-
function toConversation(
|
|
13378
|
-
const pinnedAt = number(
|
|
13379
|
-
const projectId = text3(
|
|
13380
|
-
const context = conversationContext(
|
|
13877
|
+
function toConversation(record3) {
|
|
13878
|
+
const pinnedAt = number(record3.data.pinnedAt);
|
|
13879
|
+
const projectId = text3(record3.data.projectId);
|
|
13880
|
+
const context = conversationContext(record3.data);
|
|
13381
13881
|
return {
|
|
13382
|
-
uniqueId:
|
|
13383
|
-
conversationId:
|
|
13384
|
-
title: text3(
|
|
13882
|
+
uniqueId: record3.id,
|
|
13883
|
+
conversationId: record3.id,
|
|
13884
|
+
title: text3(record3.data.title) ?? "",
|
|
13385
13885
|
...projectId ? { projectId } : {},
|
|
13386
|
-
createdAt: new Date(
|
|
13387
|
-
updatedAt: new Date(
|
|
13388
|
-
isDeleted:
|
|
13886
|
+
createdAt: new Date(record3.createdAt),
|
|
13887
|
+
updatedAt: new Date(record3.updatedAt),
|
|
13888
|
+
isDeleted: record3.isDeleted,
|
|
13389
13889
|
pinnedAt: pinnedAt ? new Date(pinnedAt) : null,
|
|
13390
13890
|
...context ? { context } : {}
|
|
13391
13891
|
};
|
|
@@ -13407,21 +13907,21 @@ function messageData(options) {
|
|
|
13407
13907
|
...anuma ? { anuma } : {}
|
|
13408
13908
|
});
|
|
13409
13909
|
}
|
|
13410
|
-
function toMessage(
|
|
13411
|
-
const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } =
|
|
13910
|
+
function toMessage(record3) {
|
|
13911
|
+
const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } = record3.data;
|
|
13412
13912
|
const anuma = readAnumaTurn(rawAnuma);
|
|
13413
13913
|
return {
|
|
13414
13914
|
...anuma ? { anuma } : {},
|
|
13415
13915
|
...fields,
|
|
13416
|
-
uniqueId:
|
|
13417
|
-
messageId:
|
|
13418
|
-
conversationId:
|
|
13419
|
-
createdAt: new Date(
|
|
13420
|
-
updatedAt: new Date(
|
|
13916
|
+
uniqueId: record3.id,
|
|
13917
|
+
messageId: record3.sortKey,
|
|
13918
|
+
conversationId: record3.conversationId,
|
|
13919
|
+
createdAt: new Date(record3.createdAt),
|
|
13920
|
+
updatedAt: new Date(record3.updatedAt)
|
|
13421
13921
|
};
|
|
13422
13922
|
}
|
|
13423
|
-
function chunkOffsets(
|
|
13424
|
-
const offsets =
|
|
13923
|
+
function chunkOffsets(record3) {
|
|
13924
|
+
const offsets = record3.data.chunkOffsets;
|
|
13425
13925
|
return Array.isArray(offsets) ? offsets : void 0;
|
|
13426
13926
|
}
|
|
13427
13927
|
function toSkeletons(records) {
|
|
@@ -13442,15 +13942,15 @@ function toSkeletons(records) {
|
|
|
13442
13942
|
};
|
|
13443
13943
|
});
|
|
13444
13944
|
}
|
|
13445
|
-
function toSummary(
|
|
13945
|
+
function toSummary(record3) {
|
|
13446
13946
|
return {
|
|
13447
|
-
uniqueId:
|
|
13448
|
-
conversationId:
|
|
13449
|
-
summary: text3(
|
|
13450
|
-
summarizedUpTo: text3(
|
|
13451
|
-
tokenCount: number(
|
|
13452
|
-
createdAt: new Date(
|
|
13453
|
-
updatedAt: new Date(
|
|
13947
|
+
uniqueId: record3.id,
|
|
13948
|
+
conversationId: record3.id,
|
|
13949
|
+
summary: text3(record3.data.summary) ?? "",
|
|
13950
|
+
summarizedUpTo: text3(record3.data.summarizedUpTo) ?? "",
|
|
13951
|
+
tokenCount: number(record3.data.tokenCount) ?? 0,
|
|
13952
|
+
createdAt: new Date(record3.createdAt),
|
|
13953
|
+
updatedAt: new Date(record3.updatedAt)
|
|
13454
13954
|
};
|
|
13455
13955
|
}
|
|
13456
13956
|
function links(data) {
|
|
@@ -13476,10 +13976,10 @@ function applyLinkOps(data, ops) {
|
|
|
13476
13976
|
}
|
|
13477
13977
|
return plain({ links: current });
|
|
13478
13978
|
}
|
|
13479
|
-
function toLinks(
|
|
13480
|
-
return links(
|
|
13481
|
-
uniqueId: `${
|
|
13482
|
-
conversationId:
|
|
13979
|
+
function toLinks(record3) {
|
|
13980
|
+
return links(record3.data).map((l) => ({
|
|
13981
|
+
uniqueId: `${record3.id}:${l.memoryId}`,
|
|
13982
|
+
conversationId: record3.id,
|
|
13483
13983
|
memoryId: l.memoryId,
|
|
13484
13984
|
score: l.score,
|
|
13485
13985
|
createdAt: new Date(l.createdAt)
|
|
@@ -13488,24 +13988,24 @@ function toLinks(record2) {
|
|
|
13488
13988
|
function bytes(value) {
|
|
13489
13989
|
return new TextEncoder().encode(JSON.stringify(value)).length;
|
|
13490
13990
|
}
|
|
13491
|
-
function fitRecord(
|
|
13492
|
-
if (
|
|
13493
|
-
const data = { ...
|
|
13991
|
+
function fitRecord(record3) {
|
|
13992
|
+
if (record3.kind !== "message" || bytes(record3) <= recordBudgetBytes) return record3;
|
|
13993
|
+
const data = { ...record3.data };
|
|
13494
13994
|
const truncated = [];
|
|
13495
13995
|
for (const field10 of droppable) {
|
|
13496
|
-
if (bytes({ ...
|
|
13996
|
+
if (bytes({ ...record3, data }) <= recordBudgetBytes) break;
|
|
13497
13997
|
if (data[field10] === void 0) continue;
|
|
13498
13998
|
delete data[field10];
|
|
13499
13999
|
truncated.push(field10);
|
|
13500
14000
|
}
|
|
13501
14001
|
const content = text3(data.content) ?? "";
|
|
13502
|
-
const over = bytes({ ...
|
|
14002
|
+
const over = bytes({ ...record3, data }) - recordBudgetBytes;
|
|
13503
14003
|
if (over > 0) {
|
|
13504
14004
|
const encoded = new TextEncoder().encode(content);
|
|
13505
14005
|
data.content = new TextDecoder().decode(encoded.slice(0, Math.max(0, encoded.length - over - 64))).replace(/�$/, "");
|
|
13506
14006
|
truncated.push("content");
|
|
13507
14007
|
}
|
|
13508
|
-
return { ...
|
|
14008
|
+
return { ...record3, data: { ...data, truncated } };
|
|
13509
14009
|
}
|
|
13510
14010
|
function acceptedVector(vector2) {
|
|
13511
14011
|
if (!vector2 || !acceptedDims.has(vector2.length)) return void 0;
|
|
@@ -13549,8 +14049,8 @@ function anumaTurnContent(bubbles) {
|
|
|
13549
14049
|
return bubbles.join("\n\n");
|
|
13550
14050
|
}
|
|
13551
14051
|
function anumaLastReadSortKey(conversation) {
|
|
13552
|
-
const
|
|
13553
|
-
const state =
|
|
14052
|
+
const record3 = conversation && "record" in conversation ? conversation.record : conversation;
|
|
14053
|
+
const state = record3?.data.anuma;
|
|
13554
14054
|
if (!isObject(state)) return 0;
|
|
13555
14055
|
const sortKey = state.lastReadSortKey;
|
|
13556
14056
|
return Number.isSafeInteger(sortKey) && sortKey > 0 ? sortKey : 0;
|
|
@@ -13603,19 +14103,19 @@ async function markAnumaRead(store, sortKey, options = {}) {
|
|
|
13603
14103
|
const current = await ensureAnumaConversation(store, options);
|
|
13604
14104
|
const read = anumaLastReadSortKey(current);
|
|
13605
14105
|
if (sortKey <= read) return current;
|
|
13606
|
-
const
|
|
13607
|
-
const state = isObject(
|
|
13608
|
-
const data = plain({ ...
|
|
14106
|
+
const record3 = current.record;
|
|
14107
|
+
const state = isObject(record3.data.anuma) ? record3.data.anuma : {};
|
|
14108
|
+
const data = plain({ ...record3.data, anuma: { ...state, lastReadSortKey: sortKey } });
|
|
13609
14109
|
try {
|
|
13610
14110
|
const [written] = await store.putMany(
|
|
13611
14111
|
[
|
|
13612
14112
|
{
|
|
13613
14113
|
expectedVersion: current.version,
|
|
13614
14114
|
record: {
|
|
13615
|
-
...
|
|
14115
|
+
...record3,
|
|
13616
14116
|
data,
|
|
13617
|
-
sortKey: conversationSortKey(data,
|
|
13618
|
-
updatedAt: Math.max(
|
|
14117
|
+
sortKey: conversationSortKey(data, record3.createdAt),
|
|
14118
|
+
updatedAt: Math.max(record3.updatedAt, now())
|
|
13619
14119
|
}
|
|
13620
14120
|
}
|
|
13621
14121
|
],
|
|
@@ -13651,22 +14151,22 @@ function createSummaryContext(database, encryption = {}) {
|
|
|
13651
14151
|
summariesCollection: database.get("conversation_summaries")
|
|
13652
14152
|
};
|
|
13653
14153
|
}
|
|
13654
|
-
function modelToStored(
|
|
14154
|
+
function modelToStored(record3, summary) {
|
|
13655
14155
|
return {
|
|
13656
|
-
uniqueId:
|
|
13657
|
-
conversationId:
|
|
14156
|
+
uniqueId: record3.id,
|
|
14157
|
+
conversationId: record3.conversationId,
|
|
13658
14158
|
summary,
|
|
13659
|
-
summarizedUpTo:
|
|
13660
|
-
tokenCount:
|
|
13661
|
-
createdAt:
|
|
13662
|
-
updatedAt:
|
|
14159
|
+
summarizedUpTo: record3.summarizedUpTo,
|
|
14160
|
+
tokenCount: record3.tokenCount,
|
|
14161
|
+
createdAt: record3.createdAt,
|
|
14162
|
+
updatedAt: record3.updatedAt
|
|
13663
14163
|
};
|
|
13664
14164
|
}
|
|
13665
14165
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
13666
14166
|
const results = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
|
|
13667
14167
|
if (results.length === 0) return null;
|
|
13668
|
-
const
|
|
13669
|
-
const stored2 = modelToStored(
|
|
14168
|
+
const record3 = results[0];
|
|
14169
|
+
const stored2 = modelToStored(record3, record3.summary);
|
|
13670
14170
|
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
13671
14171
|
if (ctx.signMessage) {
|
|
13672
14172
|
try {
|
|
@@ -13685,7 +14185,7 @@ async function getConversationSummaryOp(ctx, conversationId) {
|
|
|
13685
14185
|
ctx.embeddedWalletSigner
|
|
13686
14186
|
);
|
|
13687
14187
|
await ctx.database.write(async () => {
|
|
13688
|
-
const current = await ctx.summariesCollection.query(import_watermelondb6.Q.where("id",
|
|
14188
|
+
const current = await ctx.summariesCollection.query(import_watermelondb6.Q.where("id", record3.id)).fetch();
|
|
13689
14189
|
if (current[0]?.summary === stored2.summary) {
|
|
13690
14190
|
await current[0].update((rec) => {
|
|
13691
14191
|
rec.summary = encryptedSummary;
|
|
@@ -13700,19 +14200,19 @@ async function getConversationSummaryOp(ctx, conversationId) {
|
|
|
13700
14200
|
}
|
|
13701
14201
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
13702
14202
|
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
13703
|
-
let
|
|
14203
|
+
let record3;
|
|
13704
14204
|
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
13705
14205
|
await ctx.database.write(async () => {
|
|
13706
14206
|
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
13707
14207
|
const existing = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
|
|
13708
14208
|
if (existing.length > 0) {
|
|
13709
|
-
|
|
14209
|
+
record3 = await existing[0].update((rec) => {
|
|
13710
14210
|
rec.summary = encryptedSummary;
|
|
13711
14211
|
rec.summarizedUpTo = summarizedUpTo;
|
|
13712
14212
|
rec.tokenCount = tokenCount;
|
|
13713
14213
|
});
|
|
13714
14214
|
} else {
|
|
13715
|
-
|
|
14215
|
+
record3 = await ctx.summariesCollection.create((rec) => {
|
|
13716
14216
|
rec.conversationId = conversationId;
|
|
13717
14217
|
rec.summary = encryptedSummary;
|
|
13718
14218
|
rec.summarizedUpTo = summarizedUpTo;
|
|
@@ -13720,13 +14220,13 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
|
|
|
13720
14220
|
});
|
|
13721
14221
|
}
|
|
13722
14222
|
});
|
|
13723
|
-
return modelToStored(
|
|
14223
|
+
return modelToStored(record3, summary);
|
|
13724
14224
|
}
|
|
13725
14225
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
13726
14226
|
await ctx.database.write(async () => {
|
|
13727
14227
|
const existing = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
|
|
13728
|
-
for (const
|
|
13729
|
-
await
|
|
14228
|
+
for (const record3 of existing) {
|
|
14229
|
+
await record3.destroyPermanently();
|
|
13730
14230
|
}
|
|
13731
14231
|
});
|
|
13732
14232
|
}
|
|
@@ -13802,7 +14302,7 @@ function messageRecord(message) {
|
|
|
13802
14302
|
const fitted = chunks3?.length ? fitChunks(chunks3) : void 0;
|
|
13803
14303
|
const single = fitted ? void 0 : acceptedVector(vector2);
|
|
13804
14304
|
const embeddings2 = fitted?.map((c) => c.vector) ?? (single ? [single] : void 0);
|
|
13805
|
-
const
|
|
14305
|
+
const record3 = fitRecord({
|
|
13806
14306
|
kind: "message",
|
|
13807
14307
|
id: message.uniqueId,
|
|
13808
14308
|
conversationId: message.conversationId,
|
|
@@ -13816,7 +14316,7 @@ function messageRecord(message) {
|
|
|
13816
14316
|
}
|
|
13817
14317
|
});
|
|
13818
14318
|
return {
|
|
13819
|
-
record:
|
|
14319
|
+
record: record3,
|
|
13820
14320
|
...embeddings2 ? { embeddings: embeddings2 } : {},
|
|
13821
14321
|
...embeddings2 && message.embeddingModel ? { embeddingModel: message.embeddingModel } : {}
|
|
13822
14322
|
};
|
|
@@ -13964,15 +14464,15 @@ function ref(value) {
|
|
|
13964
14464
|
function sameMetadata(a, b) {
|
|
13965
14465
|
return metadata.every((key3) => a[key3] === b[key3]);
|
|
13966
14466
|
}
|
|
13967
|
-
function wire(
|
|
14467
|
+
function wire(record3, payload) {
|
|
13968
14468
|
return {
|
|
13969
|
-
kind:
|
|
13970
|
-
id:
|
|
13971
|
-
conversation_id:
|
|
13972
|
-
sort_key:
|
|
13973
|
-
created_at:
|
|
13974
|
-
updated_at:
|
|
13975
|
-
is_deleted:
|
|
14469
|
+
kind: record3.kind,
|
|
14470
|
+
id: record3.id,
|
|
14471
|
+
conversation_id: record3.conversationId,
|
|
14472
|
+
sort_key: record3.sortKey,
|
|
14473
|
+
created_at: record3.createdAt,
|
|
14474
|
+
updated_at: record3.updatedAt,
|
|
14475
|
+
is_deleted: record3.isDeleted,
|
|
13976
14476
|
payload
|
|
13977
14477
|
};
|
|
13978
14478
|
}
|
|
@@ -14029,10 +14529,10 @@ async function createRemoteChatStore(options) {
|
|
|
14029
14529
|
serverUpdatedAt: value.server_updated_at
|
|
14030
14530
|
};
|
|
14031
14531
|
};
|
|
14032
|
-
const seal = async (
|
|
14033
|
-
if (
|
|
14532
|
+
const seal = async (record3, signal) => {
|
|
14533
|
+
if (record3.isDeleted) return "";
|
|
14034
14534
|
const payload = await encrypt(
|
|
14035
|
-
JSON.stringify({ schema: 1, account_id: accountId, key_id: keyId, record:
|
|
14535
|
+
JSON.stringify({ schema: 1, account_id: accountId, key_id: keyId, record: record3 })
|
|
14036
14536
|
);
|
|
14037
14537
|
signal?.throwIfAborted();
|
|
14038
14538
|
if (!cipherPattern.test(payload) || payload.length > maxPayload) invalid();
|
|
@@ -14396,8 +14896,8 @@ var emptyMessage = {
|
|
|
14396
14896
|
var maxPasses = 5;
|
|
14397
14897
|
var verifyBatch = 1e3;
|
|
14398
14898
|
var writeBatch = 25;
|
|
14399
|
-
function key(
|
|
14400
|
-
return `${
|
|
14899
|
+
function key(record3) {
|
|
14900
|
+
return `${record3.kind}/${record3.id}`;
|
|
14401
14901
|
}
|
|
14402
14902
|
function sealed(value) {
|
|
14403
14903
|
if (typeof value === "string") return isEncrypted(value);
|
|
@@ -14526,11 +15026,11 @@ async function missing(store, records, signal) {
|
|
|
14526
15026
|
const out = /* @__PURE__ */ new Set();
|
|
14527
15027
|
for (let i = 0; i < records.length; i += verifyBatch) {
|
|
14528
15028
|
const refs = await store.verify(
|
|
14529
|
-
records.slice(i, i + verifyBatch).map(({ record:
|
|
14530
|
-
kind:
|
|
14531
|
-
id:
|
|
14532
|
-
updatedAt:
|
|
14533
|
-
isDeleted:
|
|
15029
|
+
records.slice(i, i + verifyBatch).map(({ record: record3 }) => ({
|
|
15030
|
+
kind: record3.kind,
|
|
15031
|
+
id: record3.id,
|
|
15032
|
+
updatedAt: record3.updatedAt,
|
|
15033
|
+
isDeleted: record3.isDeleted
|
|
14534
15034
|
})),
|
|
14535
15035
|
signal
|
|
14536
15036
|
);
|
|
@@ -14570,14 +15070,14 @@ async function deletedSinceUpload(store, journal, local, signal) {
|
|
|
14570
15070
|
const live2 = (await store.getMany(gone.map(ref2), signal)).filter((s) => !s.record.isDeleted);
|
|
14571
15071
|
const tombstoning = new Set(live2.map((s) => key(s.record)));
|
|
14572
15072
|
await journal.drop(gone.filter((k) => !tombstoning.has(k)));
|
|
14573
|
-
return live2.map(({ record:
|
|
14574
|
-
const empty = emptied[
|
|
15073
|
+
return live2.map(({ record: record3, version }) => {
|
|
15074
|
+
const empty = emptied[record3.kind];
|
|
14575
15075
|
return {
|
|
14576
15076
|
record: {
|
|
14577
|
-
...
|
|
15077
|
+
...record3,
|
|
14578
15078
|
isDeleted: !empty,
|
|
14579
15079
|
data: empty ?? {},
|
|
14580
|
-
updatedAt: Math.max(Date.now(),
|
|
15080
|
+
updatedAt: Math.max(Date.now(), record3.updatedAt + 1)
|
|
14581
15081
|
},
|
|
14582
15082
|
expectedVersion: version
|
|
14583
15083
|
};
|
|
@@ -14926,8 +15426,8 @@ function createVaultAttachments(options) {
|
|
|
14926
15426
|
},
|
|
14927
15427
|
async read(attachmentId, signal) {
|
|
14928
15428
|
if (!attachmentIdPattern2.test(attachmentId)) invalidAttachment();
|
|
14929
|
-
const
|
|
14930
|
-
if (
|
|
15429
|
+
const cached2 = await cache?.get(attachmentId).catch(() => null);
|
|
15430
|
+
if (cached2) return cached2;
|
|
14931
15431
|
for (let attempt = 0; ; attempt++) {
|
|
14932
15432
|
const found = await withRetry(() => store.attachments.get(attachmentId, signal), signal);
|
|
14933
15433
|
if (!found?.download) return null;
|
|
@@ -14956,8 +15456,8 @@ function validRef(value) {
|
|
|
14956
15456
|
const ref3 = value;
|
|
14957
15457
|
return typeof ref3.attachmentId === "string" && attachmentIdPattern2.test(ref3.attachmentId) && typeof ref3.fileId === "string" && ref3.fileId.length > 0 && typeof ref3.name === "string" && typeof ref3.type === "string" && Number.isSafeInteger(ref3.size) && ref3.size >= 0;
|
|
14958
15458
|
}
|
|
14959
|
-
function vaultAttachmentRefs(
|
|
14960
|
-
const refs =
|
|
15459
|
+
function vaultAttachmentRefs(record3) {
|
|
15460
|
+
const refs = record3.data.vaultAttachments;
|
|
14961
15461
|
return Array.isArray(refs) ? refs.filter(validRef) : [];
|
|
14962
15462
|
}
|
|
14963
15463
|
function journalKey(messageId, fileId) {
|
|
@@ -15165,14 +15665,14 @@ function sameRecord(a, b) {
|
|
|
15165
15665
|
return a.sortKey === b.sortKey && a.isDeleted === b.isDeleted && sameJson(a.data, b.data);
|
|
15166
15666
|
}
|
|
15167
15667
|
function toWrite(base, patch) {
|
|
15168
|
-
const
|
|
15169
|
-
if (!
|
|
15170
|
-
if (base && patch.embeddings === void 0 && sameRecord(base.record,
|
|
15668
|
+
const record3 = applyPatch(base?.record, patch);
|
|
15669
|
+
if (!record3) return void 0;
|
|
15670
|
+
if (base && patch.embeddings === void 0 && sameRecord(base.record, record3)) return null;
|
|
15171
15671
|
return {
|
|
15172
|
-
record: fitRecord(
|
|
15672
|
+
record: fitRecord(record3),
|
|
15173
15673
|
expectedVersion: base?.version ?? 0,
|
|
15174
|
-
...patch.embeddings !== void 0 && !
|
|
15175
|
-
...patch.embeddingModel !== void 0 && !
|
|
15674
|
+
...patch.embeddings !== void 0 && !record3.isDeleted ? { embeddings: patch.embeddings } : {},
|
|
15675
|
+
...patch.embeddingModel !== void 0 && !record3.isDeleted ? { embeddingModel: patch.embeddingModel } : {}
|
|
15176
15676
|
};
|
|
15177
15677
|
}
|
|
15178
15678
|
var maxWrites = 25;
|
|
@@ -15306,11 +15806,11 @@ function createVaultChatBackend(options) {
|
|
|
15306
15806
|
for (const listener of [...listeners]) listener(event);
|
|
15307
15807
|
};
|
|
15308
15808
|
const view = (k) => {
|
|
15309
|
-
let
|
|
15809
|
+
let record3 = confirmed.get(k)?.record;
|
|
15310
15810
|
for (const patch of [inflight.get(k), pending.get(k)]) {
|
|
15311
|
-
if (patch)
|
|
15811
|
+
if (patch) record3 = applyPatch(record3, patch) ?? record3;
|
|
15312
15812
|
}
|
|
15313
|
-
return
|
|
15813
|
+
return record3;
|
|
15314
15814
|
};
|
|
15315
15815
|
const conversationLive = (conversationId) => {
|
|
15316
15816
|
const conversation2 = view(key2("conversation", conversationId));
|
|
@@ -15321,10 +15821,10 @@ function createVaultChatBackend(options) {
|
|
|
15321
15821
|
const out = [];
|
|
15322
15822
|
for (const k of keys) {
|
|
15323
15823
|
if (!k.startsWith(`${kind}/`)) continue;
|
|
15324
|
-
const
|
|
15325
|
-
if (!
|
|
15326
|
-
if (conversationId !== void 0 &&
|
|
15327
|
-
out.push(
|
|
15824
|
+
const record3 = view(k);
|
|
15825
|
+
if (!record3 || record3.isDeleted && !includeDeleted) continue;
|
|
15826
|
+
if (conversationId !== void 0 && record3.conversationId !== conversationId) continue;
|
|
15827
|
+
out.push(record3);
|
|
15328
15828
|
}
|
|
15329
15829
|
return out;
|
|
15330
15830
|
};
|
|
@@ -15335,7 +15835,7 @@ function createVaultChatBackend(options) {
|
|
|
15335
15835
|
account: cache.account,
|
|
15336
15836
|
cursor: cursor ?? "",
|
|
15337
15837
|
records: [...confirmed.values()].filter(
|
|
15338
|
-
({ record:
|
|
15838
|
+
({ record: record3 }) => record3.kind === "conversation" || record3.kind !== "project" && keep.has(record3.conversationId)
|
|
15339
15839
|
),
|
|
15340
15840
|
threads: kept,
|
|
15341
15841
|
absent: [...checked].filter((k) => {
|
|
@@ -15649,17 +16149,17 @@ function createVaultChatBackend(options) {
|
|
|
15649
16149
|
return loading;
|
|
15650
16150
|
};
|
|
15651
16151
|
const applyRemote = (snapshot) => {
|
|
15652
|
-
const { record:
|
|
15653
|
-
const k = key2(
|
|
15654
|
-
if (
|
|
16152
|
+
const { record: record3 } = snapshot;
|
|
16153
|
+
const k = key2(record3.kind, record3.id);
|
|
16154
|
+
if (record3.kind === "conversation") {
|
|
15655
16155
|
if (!merge(snapshot)) return;
|
|
15656
|
-
if (
|
|
15657
|
-
announce([
|
|
16156
|
+
if (record3.isDeleted) forgetConversation(record3.id);
|
|
16157
|
+
announce([record3]);
|
|
15658
16158
|
return;
|
|
15659
16159
|
}
|
|
15660
|
-
if (
|
|
15661
|
-
const relevant2 = threads.has(
|
|
15662
|
-
if (relevant2 && merge(snapshot)) announce([
|
|
16160
|
+
if (record3.kind === "project") return;
|
|
16161
|
+
const relevant2 = threads.has(record3.conversationId) || confirmed.has(k) || checked.has(k) && record3.kind !== "message";
|
|
16162
|
+
if (relevant2 && merge(snapshot)) announce([record3]);
|
|
15663
16163
|
};
|
|
15664
16164
|
const listIndex = async (source) => {
|
|
15665
16165
|
const index = [];
|
|
@@ -15810,8 +16310,8 @@ function createVaultChatBackend(options) {
|
|
|
15810
16310
|
checked.add(k);
|
|
15811
16311
|
if (found) merge(found);
|
|
15812
16312
|
}
|
|
15813
|
-
const
|
|
15814
|
-
return
|
|
16313
|
+
const record3 = view(k);
|
|
16314
|
+
return record3 && !record3.isDeleted && conversationLive(record3.conversationId) ? record3 : void 0;
|
|
15815
16315
|
};
|
|
15816
16316
|
const child = async (kind, conversationId) => {
|
|
15817
16317
|
await available2();
|
|
@@ -15848,19 +16348,19 @@ function createVaultChatBackend(options) {
|
|
|
15848
16348
|
await backend.deleteSummary(conversationId);
|
|
15849
16349
|
};
|
|
15850
16350
|
const storedMessage = async (uniqueId) => {
|
|
15851
|
-
const
|
|
15852
|
-
return
|
|
16351
|
+
const record3 = await message(uniqueId);
|
|
16352
|
+
return record3 ? toMessage(record3) : null;
|
|
15853
16353
|
};
|
|
15854
16354
|
const patchMessage = async (uniqueId, patch) => {
|
|
15855
|
-
const
|
|
15856
|
-
if (!
|
|
16355
|
+
const record3 = await message(uniqueId);
|
|
16356
|
+
if (!record3) return null;
|
|
15857
16357
|
await enqueue({
|
|
15858
16358
|
kind: "message",
|
|
15859
16359
|
id: uniqueId,
|
|
15860
|
-
conversationId:
|
|
16360
|
+
conversationId: record3.conversationId,
|
|
15861
16361
|
...patch
|
|
15862
16362
|
});
|
|
15863
|
-
emit({ type: "messages", conversationId:
|
|
16363
|
+
emit({ type: "messages", conversationId: record3.conversationId, origin: "local" });
|
|
15864
16364
|
const updated = view(key2("message", uniqueId));
|
|
15865
16365
|
return updated && !updated.isDeleted ? toMessage(updated) : null;
|
|
15866
16366
|
};
|
|
@@ -15885,12 +16385,12 @@ function createVaultChatBackend(options) {
|
|
|
15885
16385
|
});
|
|
15886
16386
|
const backend = {
|
|
15887
16387
|
async getConversation(conversationId) {
|
|
15888
|
-
const
|
|
15889
|
-
return
|
|
16388
|
+
const record3 = await conversation(conversationId);
|
|
16389
|
+
return record3 && !record3.isDeleted ? toConversation(record3) : null;
|
|
15890
16390
|
},
|
|
15891
16391
|
async getConversations(query) {
|
|
15892
16392
|
await available2();
|
|
15893
|
-
return all("conversation").filter((
|
|
16393
|
+
return all("conversation").filter((record3) => record3.id !== ANUMA_CONVERSATION_ID).map(toConversation).filter(
|
|
15894
16394
|
(c) => query?.projectId === void 0 || (query.projectId === null ? !c.projectId : c.projectId === query.projectId)
|
|
15895
16395
|
).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
15896
16396
|
},
|
|
@@ -15929,13 +16429,13 @@ function createVaultChatBackend(options) {
|
|
|
15929
16429
|
async updateConversationContext(conversationId, context) {
|
|
15930
16430
|
const set = contextFields(context);
|
|
15931
16431
|
if (Object.keys(set).length > 0) return updateConversation(conversationId, set);
|
|
15932
|
-
const
|
|
15933
|
-
return !!
|
|
16432
|
+
const record3 = await conversation(conversationId);
|
|
16433
|
+
return !!record3 && !record3.isDeleted;
|
|
15934
16434
|
},
|
|
15935
16435
|
async deleteConversation(conversationId) {
|
|
15936
16436
|
if (conversationId === ANUMA_CONVERSATION_ID) return false;
|
|
15937
|
-
const
|
|
15938
|
-
if (!
|
|
16437
|
+
const record3 = await conversation(conversationId);
|
|
16438
|
+
if (!record3 || record3.isDeleted) return false;
|
|
15939
16439
|
for (const [k, patch] of pending)
|
|
15940
16440
|
if (patch.conversationId === conversationId) pending.delete(k);
|
|
15941
16441
|
await enqueue({ kind: "conversation", id: conversationId, conversationId: "", delete: true });
|
|
@@ -15971,8 +16471,8 @@ function createVaultChatBackend(options) {
|
|
|
15971
16471
|
const unknown = ids.map((id2) => key2("message", id2)).filter((k) => !view(k) && !checked.has(k));
|
|
15972
16472
|
await refresh(unknown);
|
|
15973
16473
|
return ids.flatMap((id2) => {
|
|
15974
|
-
const
|
|
15975
|
-
return
|
|
16474
|
+
const record3 = view(key2("message", id2));
|
|
16475
|
+
return record3 && !record3.isDeleted && conversationLive(record3.conversationId) ? [toMessage(record3)] : [];
|
|
15976
16476
|
});
|
|
15977
16477
|
},
|
|
15978
16478
|
async getMessageCount(conversationId) {
|
|
@@ -15980,8 +16480,8 @@ function createVaultChatBackend(options) {
|
|
|
15980
16480
|
},
|
|
15981
16481
|
async getToolCallEventIds(conversationId) {
|
|
15982
16482
|
const ids = /* @__PURE__ */ new Set();
|
|
15983
|
-
for (const
|
|
15984
|
-
const events =
|
|
16483
|
+
for (const record3 of await thread(conversationId)) {
|
|
16484
|
+
const events = record3.data.toolCallEvents;
|
|
15985
16485
|
if (!Array.isArray(events)) continue;
|
|
15986
16486
|
for (const event of events)
|
|
15987
16487
|
if (event && typeof event === "object" && !Array.isArray(event) && typeof event.id === "string")
|
|
@@ -16074,21 +16574,21 @@ function createVaultChatBackend(options) {
|
|
|
16074
16574
|
},
|
|
16075
16575
|
async clearMessages(conversationId) {
|
|
16076
16576
|
await invalidateSummary(conversationId);
|
|
16077
|
-
for (const
|
|
16078
|
-
await enqueue({ kind: "message", id:
|
|
16577
|
+
for (const record3 of await thread(conversationId))
|
|
16578
|
+
await enqueue({ kind: "message", id: record3.id, conversationId, delete: true });
|
|
16079
16579
|
emit({ type: "messages", conversationId, origin: "local" });
|
|
16080
16580
|
},
|
|
16081
16581
|
async deleteMessage(uniqueId) {
|
|
16082
|
-
const
|
|
16083
|
-
if (!
|
|
16084
|
-
await invalidateSummary(
|
|
16582
|
+
const record3 = await message(uniqueId);
|
|
16583
|
+
if (!record3) return null;
|
|
16584
|
+
await invalidateSummary(record3.conversationId, record3);
|
|
16085
16585
|
await enqueue({
|
|
16086
16586
|
kind: "message",
|
|
16087
16587
|
id: uniqueId,
|
|
16088
|
-
conversationId:
|
|
16588
|
+
conversationId: record3.conversationId,
|
|
16089
16589
|
delete: true
|
|
16090
16590
|
});
|
|
16091
|
-
emit({ type: "messages", conversationId:
|
|
16591
|
+
emit({ type: "messages", conversationId: record3.conversationId, origin: "local" });
|
|
16092
16592
|
return uniqueId;
|
|
16093
16593
|
},
|
|
16094
16594
|
observeMessages(conversationId) {
|
|
@@ -16101,13 +16601,13 @@ function createVaultChatBackend(options) {
|
|
|
16101
16601
|
await available2();
|
|
16102
16602
|
if (query?.conversationId) await loadThread(query.conversationId);
|
|
16103
16603
|
const files = [];
|
|
16104
|
-
for (const
|
|
16105
|
-
if (!conversationLive(
|
|
16106
|
-
const stored2 = toMessage(
|
|
16604
|
+
for (const record3 of all("message", query?.conversationId)) {
|
|
16605
|
+
if (!conversationLive(record3.conversationId)) continue;
|
|
16606
|
+
const stored2 = toMessage(record3);
|
|
16107
16607
|
for (const file of stored2.files ?? [])
|
|
16108
16608
|
files.push({
|
|
16109
16609
|
...file,
|
|
16110
|
-
conversationId:
|
|
16610
|
+
conversationId: record3.conversationId,
|
|
16111
16611
|
createdAt: stored2.createdAt,
|
|
16112
16612
|
messageRole: stored2.role
|
|
16113
16613
|
});
|
|
@@ -16146,8 +16646,8 @@ function createVaultChatBackend(options) {
|
|
|
16146
16646
|
return results;
|
|
16147
16647
|
},
|
|
16148
16648
|
async getSummary(conversationId) {
|
|
16149
|
-
const
|
|
16150
|
-
return
|
|
16649
|
+
const record3 = await child("summary", conversationId);
|
|
16650
|
+
return record3 && !record3.isDeleted && record3.data.summarizedUpTo ? toSummary(record3) : null;
|
|
16151
16651
|
},
|
|
16152
16652
|
async upsertSummary(conversationId, summary, summarizedUpTo, tokenCount) {
|
|
16153
16653
|
await child("summary", conversationId);
|
|
@@ -16163,8 +16663,8 @@ function createVaultChatBackend(options) {
|
|
|
16163
16663
|
return toSummary(view(key2("summary", conversationId)));
|
|
16164
16664
|
},
|
|
16165
16665
|
async deleteSummary(conversationId) {
|
|
16166
|
-
const
|
|
16167
|
-
if (!
|
|
16666
|
+
const record3 = await child("summary", conversationId);
|
|
16667
|
+
if (!record3 || record3.isDeleted) return;
|
|
16168
16668
|
await enqueue({
|
|
16169
16669
|
kind: "summary",
|
|
16170
16670
|
id: conversationId,
|
|
@@ -16174,8 +16674,8 @@ function createVaultChatBackend(options) {
|
|
|
16174
16674
|
emit({ type: "summary", conversationId, origin: "local" });
|
|
16175
16675
|
},
|
|
16176
16676
|
async getMemoryLinks(conversationId) {
|
|
16177
|
-
const
|
|
16178
|
-
return
|
|
16677
|
+
const record3 = await child("memory_links", conversationId);
|
|
16678
|
+
return record3 && !record3.isDeleted ? toLinks(record3) : [];
|
|
16179
16679
|
},
|
|
16180
16680
|
async addMemoryLinks(conversationId, items) {
|
|
16181
16681
|
if (!conversationId || items.length === 0) return;
|
|
@@ -16190,8 +16690,8 @@ function createVaultChatBackend(options) {
|
|
|
16190
16690
|
emit({ type: "links", conversationId, origin: "local" });
|
|
16191
16691
|
},
|
|
16192
16692
|
async clearMemoryLinks(conversationId) {
|
|
16193
|
-
const
|
|
16194
|
-
if (!
|
|
16693
|
+
const record3 = await child("memory_links", conversationId);
|
|
16694
|
+
if (!record3 || record3.isDeleted) return;
|
|
16195
16695
|
await enqueue({
|
|
16196
16696
|
kind: "memory_links",
|
|
16197
16697
|
id: conversationId,
|
|
@@ -16209,8 +16709,8 @@ function createVaultChatBackend(options) {
|
|
|
16209
16709
|
async importChats(chats) {
|
|
16210
16710
|
await ready();
|
|
16211
16711
|
const seen = /* @__PURE__ */ new Set();
|
|
16212
|
-
const unique = (items) => items.filter(({ record:
|
|
16213
|
-
const k = key2(
|
|
16712
|
+
const unique = (items) => items.filter(({ record: record3 }) => {
|
|
16713
|
+
const k = key2(record3.kind, record3.id);
|
|
16214
16714
|
if (seen.has(k)) return false;
|
|
16215
16715
|
seen.add(k);
|
|
16216
16716
|
return true;
|
|
@@ -16234,15 +16734,15 @@ function createVaultChatBackend(options) {
|
|
|
16234
16734
|
for (const batch of batches(messages))
|
|
16235
16735
|
messageCount += await connected.importRecords(batch);
|
|
16236
16736
|
} finally {
|
|
16237
|
-
for (const { record:
|
|
16238
|
-
await refresh(conversations.map(({ record:
|
|
16737
|
+
for (const { record: record3 } of messages) checked.delete(key2("message", record3.id));
|
|
16738
|
+
await refresh(conversations.map(({ record: record3 }) => key2("conversation", record3.id))).catch(
|
|
16239
16739
|
() => void 0
|
|
16240
16740
|
);
|
|
16241
|
-
for (const { record:
|
|
16741
|
+
for (const { record: record3 } of conversations) threads.delete(record3.id);
|
|
16242
16742
|
channel?.postMessage("changed");
|
|
16243
16743
|
emit({ type: "conversations", origin: "local" });
|
|
16244
|
-
for (const { record:
|
|
16245
|
-
emit({ type: "messages", conversationId:
|
|
16744
|
+
for (const { record: record3 } of conversations)
|
|
16745
|
+
emit({ type: "messages", conversationId: record3.id, origin: "local" });
|
|
16246
16746
|
}
|
|
16247
16747
|
return { conversations: conversationCount, messages: messageCount };
|
|
16248
16748
|
},
|
|
@@ -16261,8 +16761,8 @@ function createVaultChatBackend(options) {
|
|
|
16261
16761
|
}
|
|
16262
16762
|
};
|
|
16263
16763
|
const updateConversation = async (conversationId, set) => {
|
|
16264
|
-
const
|
|
16265
|
-
if (!
|
|
16764
|
+
const record3 = await conversation(conversationId);
|
|
16765
|
+
if (!record3 || record3.isDeleted) return false;
|
|
16266
16766
|
await enqueue({ kind: "conversation", id: conversationId, conversationId: "", set });
|
|
16267
16767
|
emit({ type: "conversations", origin: "local" });
|
|
16268
16768
|
return true;
|
|
@@ -16438,10 +16938,10 @@ async function decryptConversationTitle(encryptedTitle, address) {
|
|
|
16438
16938
|
);
|
|
16439
16939
|
}
|
|
16440
16940
|
const cacheKey = buildCacheKey(address, encryptedTitle);
|
|
16441
|
-
const
|
|
16442
|
-
if (
|
|
16443
|
-
touchEntry(cacheKey,
|
|
16444
|
-
return
|
|
16941
|
+
const cached2 = titleCache.get(cacheKey);
|
|
16942
|
+
if (cached2 !== void 0) {
|
|
16943
|
+
touchEntry(cacheKey, cached2);
|
|
16944
|
+
return cached2;
|
|
16445
16945
|
}
|
|
16446
16946
|
const inFlight = pendingDecrypts.get(cacheKey);
|
|
16447
16947
|
if (inFlight) return inFlight;
|
|
@@ -16700,25 +17200,25 @@ async function upsertEntitiesInWrite(ctx, entities) {
|
|
|
16700
17200
|
const kindBackfills = existing.filter((e) => {
|
|
16701
17201
|
const incoming = kindByName.get(e.canonicalName);
|
|
16702
17202
|
return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
|
|
16703
|
-
}).map((
|
|
17203
|
+
}).map((record3) => ({ record: record3, kind: kindByName.get(record3.canonicalName) }));
|
|
16704
17204
|
const missing2 = unique.filter((n) => !existingNames.has(n));
|
|
16705
17205
|
const created = missing2.map(
|
|
16706
|
-
(name) => ctx.entityCollection.prepareCreate((
|
|
16707
|
-
|
|
17206
|
+
(name) => ctx.entityCollection.prepareCreate((record3) => {
|
|
17207
|
+
record3._setRaw("canonical_name", name);
|
|
16708
17208
|
const kind = kindByName.get(name);
|
|
16709
|
-
if (kind !== void 0)
|
|
17209
|
+
if (kind !== void 0) record3._setRaw("kind", kind);
|
|
16710
17210
|
})
|
|
16711
17211
|
);
|
|
16712
17212
|
for (const e of existing) out.set(e.canonicalName, entityToStored(e));
|
|
16713
|
-
for (const
|
|
16714
|
-
for (const { record:
|
|
16715
|
-
out.set(
|
|
17213
|
+
for (const record3 of created) out.set(record3.canonicalName, entityToStored(record3));
|
|
17214
|
+
for (const { record: record3, kind } of kindBackfills) {
|
|
17215
|
+
out.set(record3.canonicalName, { ...entityToStored(record3), kind });
|
|
16716
17216
|
}
|
|
16717
17217
|
return { entities: out, operations: created, kindBackfills };
|
|
16718
17218
|
}
|
|
16719
17219
|
function prepareKindBackfills(backfills) {
|
|
16720
17220
|
return backfills.map(
|
|
16721
|
-
({ record:
|
|
17221
|
+
({ record: record3, kind }) => record3.prepareUpdate((r) => {
|
|
16722
17222
|
r._setRaw("kind", kind);
|
|
16723
17223
|
})
|
|
16724
17224
|
);
|
|
@@ -16846,10 +17346,10 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
16846
17346
|
return;
|
|
16847
17347
|
}
|
|
16848
17348
|
const linkOps = toCreate.map(
|
|
16849
|
-
(e) => ctx.memoryEntityCollection.prepareCreate((
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
if (userId !== void 0)
|
|
17349
|
+
(e) => ctx.memoryEntityCollection.prepareCreate((record3) => {
|
|
17350
|
+
record3._setRaw("memory_id", memoryId);
|
|
17351
|
+
record3._setRaw("entity_id", e.uniqueId);
|
|
17352
|
+
if (userId !== void 0) record3._setRaw("user_id", userId);
|
|
16853
17353
|
})
|
|
16854
17354
|
);
|
|
16855
17355
|
await ctx.database.batch(
|
|
@@ -16919,10 +17419,10 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
16919
17419
|
...entityOps,
|
|
16920
17420
|
...prepareKindBackfills(kindBackfills),
|
|
16921
17421
|
...toCreate.map(
|
|
16922
|
-
(e) => ctx.memoryEntityCollection.prepareCreate((
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
if (userId !== void 0)
|
|
17422
|
+
(e) => ctx.memoryEntityCollection.prepareCreate((record3) => {
|
|
17423
|
+
record3._setRaw("memory_id", memoryId);
|
|
17424
|
+
record3._setRaw("entity_id", e.uniqueId);
|
|
17425
|
+
if (userId !== void 0) record3._setRaw("user_id", userId);
|
|
16926
17426
|
})
|
|
16927
17427
|
),
|
|
16928
17428
|
...toDestroy.map((l) => l.prepareDestroyPermanently()),
|
|
@@ -18251,9 +18751,9 @@ var DatabaseManager = class {
|
|
|
18251
18751
|
*/
|
|
18252
18752
|
getDatabase(walletAddress) {
|
|
18253
18753
|
const dbName = this.getDbName(walletAddress);
|
|
18254
|
-
const
|
|
18255
|
-
if (
|
|
18256
|
-
return
|
|
18754
|
+
const cached2 = this.databases.get(dbName);
|
|
18755
|
+
if (cached2) {
|
|
18756
|
+
return cached2;
|
|
18257
18757
|
}
|
|
18258
18758
|
const needsMigration = this.handleSchemaMigration(walletAddress);
|
|
18259
18759
|
if (needsMigration) {
|
|
@@ -19393,8 +19893,8 @@ function visibilityConditions(requested) {
|
|
|
19393
19893
|
if (excluded.length === 0) return [];
|
|
19394
19894
|
return [import_watermelondb24.Q.or(import_watermelondb24.Q.where("visibility", null), import_watermelondb24.Q.where("visibility", import_watermelondb24.Q.notIn(excluded)))];
|
|
19395
19895
|
}
|
|
19396
|
-
function isKinded(
|
|
19397
|
-
return
|
|
19896
|
+
function isKinded(record3) {
|
|
19897
|
+
return record3.kind !== null && record3.kind !== void 0;
|
|
19398
19898
|
}
|
|
19399
19899
|
async function assertCanWrite2(ctx) {
|
|
19400
19900
|
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
@@ -19448,8 +19948,8 @@ function levelConditions(requested) {
|
|
|
19448
19948
|
}
|
|
19449
19949
|
return [byLevel];
|
|
19450
19950
|
}
|
|
19451
|
-
function isOwnedByCtxUser(ctx,
|
|
19452
|
-
return ctx.userId === void 0 ||
|
|
19951
|
+
function isOwnedByCtxUser(ctx, record3) {
|
|
19952
|
+
return ctx.userId === void 0 || record3.userId === ctx.userId;
|
|
19453
19953
|
}
|
|
19454
19954
|
function baseVaultConditions(ctx, options) {
|
|
19455
19955
|
return [
|
|
@@ -19532,43 +20032,43 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
|
|
|
19532
20032
|
}
|
|
19533
20033
|
return raw;
|
|
19534
20034
|
}
|
|
19535
|
-
function populateNewVaultMemory(
|
|
20035
|
+
function populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue) {
|
|
19536
20036
|
const { level, scope } = resolveCreateLevel(opts);
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19544
|
-
|
|
20037
|
+
record3._setRaw("content", encryptedContent);
|
|
20038
|
+
record3._setRaw("scope", scope);
|
|
20039
|
+
record3._setRaw("level", level);
|
|
20040
|
+
record3._setRaw("kind", opts.kind ?? null);
|
|
20041
|
+
record3._setRaw("kind_value", encryptedKindValue ?? null);
|
|
20042
|
+
record3._setRaw("folder_id", opts.folderId ?? null);
|
|
20043
|
+
record3._setRaw("user_id", ctx.userId ?? null);
|
|
20044
|
+
record3._setRaw("is_deleted", false);
|
|
19545
20045
|
if (opts.embedding !== void 0) {
|
|
19546
|
-
|
|
19547
|
-
|
|
20046
|
+
record3._setRaw("embedding", opts.embedding);
|
|
20047
|
+
record3._setRaw("embedding_model", opts.embeddingModel ?? null);
|
|
19548
20048
|
}
|
|
19549
20049
|
if (opts.sourceChunkIds !== void 0) {
|
|
19550
|
-
|
|
20050
|
+
record3._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
|
|
19551
20051
|
}
|
|
19552
|
-
|
|
19553
|
-
|
|
20052
|
+
record3._setRaw("proof_count", opts.proofCount ?? 1);
|
|
20053
|
+
record3._setRaw("source", opts.source ?? "manual");
|
|
19554
20054
|
if (opts.eventTime) {
|
|
19555
|
-
|
|
19556
|
-
|
|
19557
|
-
|
|
20055
|
+
record3._setRaw("event_time_start", opts.eventTime.start ?? null);
|
|
20056
|
+
record3._setRaw("event_time_end", opts.eventTime.end ?? null);
|
|
20057
|
+
record3._setRaw("event_time_kind", opts.eventTime.kind ?? null);
|
|
19558
20058
|
}
|
|
19559
20059
|
if (opts.factType !== void 0) {
|
|
19560
|
-
|
|
20060
|
+
record3._setRaw("fact_type", opts.factType);
|
|
19561
20061
|
}
|
|
19562
20062
|
if (opts.trustTier !== void 0) {
|
|
19563
|
-
|
|
20063
|
+
record3._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
|
|
19564
20064
|
}
|
|
19565
|
-
|
|
19566
|
-
|
|
20065
|
+
record3._setRaw("visibility", opts.visibility ?? "private");
|
|
20066
|
+
record3._setRaw(
|
|
19567
20067
|
"published_at",
|
|
19568
20068
|
opts.visibility && opts.visibility !== "private" ? opts.publishedAt ?? Date.now() : null
|
|
19569
20069
|
);
|
|
19570
20070
|
if (opts.geohash !== void 0) {
|
|
19571
|
-
|
|
20071
|
+
record3._setRaw("geohash", opts.geohash);
|
|
19572
20072
|
}
|
|
19573
20073
|
}
|
|
19574
20074
|
async function createVaultMemoryOp(ctx, opts) {
|
|
@@ -19583,7 +20083,7 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
19583
20083
|
const created = await ctx.database.write(async () => {
|
|
19584
20084
|
await assertCanWrite2(ctx);
|
|
19585
20085
|
return ctx.vaultMemoryCollection.create(
|
|
19586
|
-
(
|
|
20086
|
+
(record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue)
|
|
19587
20087
|
);
|
|
19588
20088
|
});
|
|
19589
20089
|
return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
@@ -19610,7 +20110,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
19610
20110
|
if (target.isDeleted || target.supersededBy || isKinded(target) || !isOwnedByCtxUser(ctx, target))
|
|
19611
20111
|
return;
|
|
19612
20112
|
createdRecord = await ctx.vaultMemoryCollection.create(
|
|
19613
|
-
(
|
|
20113
|
+
(record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue)
|
|
19614
20114
|
);
|
|
19615
20115
|
await target.update((r) => {
|
|
19616
20116
|
r._setRaw("superseded_by", createdRecord.id);
|
|
@@ -19695,7 +20195,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
19695
20195
|
await assertCanWrite2(ctx);
|
|
19696
20196
|
const prepared = optionsArray.map(
|
|
19697
20197
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate(
|
|
19698
|
-
(
|
|
20198
|
+
(record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContents[i], encryptedKindValues[i])
|
|
19699
20199
|
)
|
|
19700
20200
|
);
|
|
19701
20201
|
await ctx.database.batch(...prepared);
|
|
@@ -19703,16 +20203,16 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
19703
20203
|
});
|
|
19704
20204
|
return Promise.all(
|
|
19705
20205
|
created.map(
|
|
19706
|
-
(
|
|
20206
|
+
(record3) => vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
19707
20207
|
)
|
|
19708
20208
|
);
|
|
19709
20209
|
}
|
|
19710
20210
|
async function getVaultMemoryOp(ctx, id2) {
|
|
19711
20211
|
try {
|
|
19712
|
-
const
|
|
19713
|
-
if (
|
|
20212
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
20213
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
|
|
19714
20214
|
return vaultMemoryToStored(
|
|
19715
|
-
|
|
20215
|
+
record3,
|
|
19716
20216
|
ctx.walletAddress,
|
|
19717
20217
|
ctx.signMessage,
|
|
19718
20218
|
ctx.embeddedWalletSigner
|
|
@@ -20051,29 +20551,29 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
20051
20551
|
ctx.embeddedWalletSigner
|
|
20052
20552
|
) : opts.content;
|
|
20053
20553
|
let stale = false;
|
|
20054
|
-
const
|
|
20554
|
+
const record3 = probe;
|
|
20055
20555
|
await ctx.database.write(async () => {
|
|
20056
20556
|
await assertCanWrite2(ctx);
|
|
20057
|
-
if (
|
|
20557
|
+
if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3) || opts.freeFormOnly && isKinded(record3) || opts.expectedContent !== void 0 && record3._getRaw("content") !== readStoredContent) {
|
|
20058
20558
|
stale = true;
|
|
20059
20559
|
return;
|
|
20060
20560
|
}
|
|
20061
|
-
const originalUpdatedAt =
|
|
20062
|
-
const nextKind = opts.kind !== void 0 ? opts.kind :
|
|
20063
|
-
const nextLevel = levelAfter(
|
|
20561
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
20562
|
+
const nextKind = opts.kind !== void 0 ? opts.kind : record3.kind;
|
|
20563
|
+
const nextLevel = levelAfter(record3);
|
|
20064
20564
|
assertValidKindLevel(nextKind, nextLevel);
|
|
20065
20565
|
let observedSources = [];
|
|
20066
20566
|
let replayedObservation = false;
|
|
20067
20567
|
if (opts.observationSourceIds?.length) {
|
|
20068
20568
|
try {
|
|
20069
|
-
const parsed = JSON.parse(
|
|
20569
|
+
const parsed = JSON.parse(record3.sourceChunkIds ?? "[]");
|
|
20070
20570
|
if (Array.isArray(parsed))
|
|
20071
20571
|
observedSources = parsed.filter((id3) => typeof id3 === "string");
|
|
20072
20572
|
} catch {
|
|
20073
20573
|
}
|
|
20074
20574
|
replayedObservation = opts.observationSourceIds.every((id3) => observedSources.includes(id3));
|
|
20075
20575
|
}
|
|
20076
|
-
await
|
|
20576
|
+
await record3.update((r) => {
|
|
20077
20577
|
if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
|
|
20078
20578
|
if (opts.level !== void 0) {
|
|
20079
20579
|
r._setRaw("level", nextLevel);
|
|
@@ -20140,7 +20640,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
20140
20640
|
});
|
|
20141
20641
|
if (stale) return null;
|
|
20142
20642
|
return vaultMemoryToStored(
|
|
20143
|
-
|
|
20643
|
+
record3,
|
|
20144
20644
|
ctx.walletAddress,
|
|
20145
20645
|
ctx.signMessage,
|
|
20146
20646
|
ctx.embeddedWalletSigner
|
|
@@ -20155,22 +20655,22 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
20155
20655
|
if (!entityCtx) {
|
|
20156
20656
|
throw new Error("setMemoryEntitiesOp requires ctx.entityCtx (entity collections)");
|
|
20157
20657
|
}
|
|
20158
|
-
let
|
|
20658
|
+
let record3;
|
|
20159
20659
|
try {
|
|
20160
|
-
|
|
20660
|
+
record3 = await ctx.vaultMemoryCollection.find(memoryId);
|
|
20161
20661
|
} catch {
|
|
20162
20662
|
return null;
|
|
20163
20663
|
}
|
|
20164
|
-
if (
|
|
20664
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
|
|
20165
20665
|
let stale = false;
|
|
20166
|
-
const originalUpdatedAt =
|
|
20666
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
20167
20667
|
await ctx.database.write(async (writer) => {
|
|
20168
20668
|
await assertCanWrite2(ctx);
|
|
20169
|
-
if (
|
|
20669
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
|
|
20170
20670
|
stale = true;
|
|
20171
20671
|
return;
|
|
20172
20672
|
}
|
|
20173
|
-
await
|
|
20673
|
+
await record3.update((r) => {
|
|
20174
20674
|
r._setRaw("topics_user_managed", true);
|
|
20175
20675
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
20176
20676
|
});
|
|
@@ -20194,26 +20694,26 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
20194
20694
|
);
|
|
20195
20695
|
});
|
|
20196
20696
|
if (stale) return null;
|
|
20197
|
-
return vaultMemoryToStored(
|
|
20697
|
+
return vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
20198
20698
|
}
|
|
20199
20699
|
async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
20200
|
-
let
|
|
20700
|
+
let record3;
|
|
20201
20701
|
try {
|
|
20202
|
-
|
|
20702
|
+
record3 = await ctx.vaultMemoryCollection.find(memoryId);
|
|
20203
20703
|
} catch {
|
|
20204
20704
|
return false;
|
|
20205
20705
|
}
|
|
20206
|
-
if (
|
|
20207
|
-
const originalUpdatedAt =
|
|
20706
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
20707
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
20208
20708
|
let cleared = false;
|
|
20209
20709
|
await ctx.database.write(async () => {
|
|
20210
20710
|
await assertCanWrite2(ctx);
|
|
20211
|
-
if (options?.unlessTopicsRecorded && parseTopics(
|
|
20711
|
+
if (options?.unlessTopicsRecorded && parseTopics(record3.topics) !== null) return;
|
|
20212
20712
|
cleared = true;
|
|
20213
|
-
await
|
|
20713
|
+
await record3.update((r) => {
|
|
20214
20714
|
r._setRaw("topics_user_managed", false);
|
|
20215
20715
|
r._setRaw("topics_extracted_version", null);
|
|
20216
|
-
if (
|
|
20716
|
+
if (record3.topicsExtractedAt === null) {
|
|
20217
20717
|
r._setRaw("topics_extracted_at", originalUpdatedAt);
|
|
20218
20718
|
}
|
|
20219
20719
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
@@ -20222,23 +20722,23 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
|
20222
20722
|
return cleared;
|
|
20223
20723
|
}
|
|
20224
20724
|
async function setMemoryVisibilityOp(ctx, id2, opts) {
|
|
20225
|
-
let
|
|
20725
|
+
let record3;
|
|
20226
20726
|
try {
|
|
20227
|
-
|
|
20727
|
+
record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
20228
20728
|
} catch {
|
|
20229
20729
|
return null;
|
|
20230
20730
|
}
|
|
20231
|
-
if (
|
|
20731
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
|
|
20232
20732
|
let stale = false;
|
|
20233
20733
|
await ctx.database.write(async () => {
|
|
20234
20734
|
await assertCanWrite2(ctx);
|
|
20235
|
-
if (
|
|
20735
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
|
|
20236
20736
|
stale = true;
|
|
20237
20737
|
return;
|
|
20238
20738
|
}
|
|
20239
|
-
const currentUpdatedAt =
|
|
20240
|
-
const currentPublishedAt =
|
|
20241
|
-
await
|
|
20739
|
+
const currentUpdatedAt = record3.updatedAt.getTime();
|
|
20740
|
+
const currentPublishedAt = record3.publishedAt ?? null;
|
|
20741
|
+
await record3.update((r) => {
|
|
20242
20742
|
r._setRaw("visibility", opts.visibility);
|
|
20243
20743
|
if (opts.visibility === "private") {
|
|
20244
20744
|
r._setRaw("published_at", null);
|
|
@@ -20252,20 +20752,20 @@ async function setMemoryVisibilityOp(ctx, id2, opts) {
|
|
|
20252
20752
|
});
|
|
20253
20753
|
});
|
|
20254
20754
|
if (stale) return null;
|
|
20255
|
-
return vaultMemoryToStored(
|
|
20755
|
+
return vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
20256
20756
|
}
|
|
20257
20757
|
async function deleteVaultMemoryOp(ctx, id2) {
|
|
20258
20758
|
try {
|
|
20259
|
-
const
|
|
20260
|
-
if (
|
|
20759
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
20760
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
20261
20761
|
let stale = false;
|
|
20262
20762
|
await ctx.database.write(async () => {
|
|
20263
20763
|
await assertCanWrite2(ctx);
|
|
20264
|
-
if (
|
|
20764
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
|
|
20265
20765
|
stale = true;
|
|
20266
20766
|
return;
|
|
20267
20767
|
}
|
|
20268
|
-
await
|
|
20768
|
+
await record3.update((r) => {
|
|
20269
20769
|
r._setRaw("is_deleted", true);
|
|
20270
20770
|
});
|
|
20271
20771
|
});
|
|
@@ -20284,9 +20784,9 @@ async function deleteVaultMemoryOp(ctx, id2) {
|
|
|
20284
20784
|
async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
|
|
20285
20785
|
if (id2 === supersededById) return false;
|
|
20286
20786
|
try {
|
|
20287
|
-
const
|
|
20288
|
-
if (
|
|
20289
|
-
if (isKinded(
|
|
20787
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
20788
|
+
if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
20789
|
+
if (isKinded(record3)) return false;
|
|
20290
20790
|
let successor;
|
|
20291
20791
|
try {
|
|
20292
20792
|
successor = await ctx.vaultMemoryCollection.find(supersededById);
|
|
@@ -20299,7 +20799,7 @@ async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
|
|
|
20299
20799
|
let stale = false;
|
|
20300
20800
|
await ctx.database.write(async () => {
|
|
20301
20801
|
await assertCanWrite2(ctx);
|
|
20302
|
-
if (
|
|
20802
|
+
if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3)) {
|
|
20303
20803
|
stale = true;
|
|
20304
20804
|
return;
|
|
20305
20805
|
}
|
|
@@ -20307,7 +20807,7 @@ async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
|
|
|
20307
20807
|
stale = true;
|
|
20308
20808
|
return;
|
|
20309
20809
|
}
|
|
20310
|
-
await
|
|
20810
|
+
await record3.update((r) => {
|
|
20311
20811
|
r._setRaw("superseded_by", supersededById);
|
|
20312
20812
|
r._setRaw("superseded_at", Date.now());
|
|
20313
20813
|
});
|
|
@@ -20326,7 +20826,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
|
|
|
20326
20826
|
const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
|
|
20327
20827
|
return mapInBatches(
|
|
20328
20828
|
results,
|
|
20329
|
-
(
|
|
20829
|
+
(record3) => vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
20330
20830
|
);
|
|
20331
20831
|
}
|
|
20332
20832
|
var TOPICS_EXTRACTION_VERSION = 3;
|
|
@@ -20487,17 +20987,17 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
|
|
|
20487
20987
|
}
|
|
20488
20988
|
}
|
|
20489
20989
|
const eligible = records.filter(
|
|
20490
|
-
(
|
|
20990
|
+
(record3) => !record3.isDeleted && isOwnedByCtxUser(ctx, record3) && !record3.topicsUserManaged
|
|
20491
20991
|
);
|
|
20492
|
-
const prepared = eligible.map((
|
|
20493
|
-
const originalUpdatedAt =
|
|
20494
|
-
return
|
|
20992
|
+
const prepared = eligible.map((record3) => {
|
|
20993
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
20994
|
+
return record3.prepareUpdate((r) => {
|
|
20495
20995
|
r._setRaw("topics_extracted_at", extractedAt);
|
|
20496
20996
|
r._setRaw("topics_extracted_version", version);
|
|
20497
20997
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
20498
20998
|
});
|
|
20499
20999
|
});
|
|
20500
|
-
for (const
|
|
21000
|
+
for (const record3 of eligible) stamped.push(record3.id);
|
|
20501
21001
|
if (prepared.length > 0) await ctx.database.batch(...prepared);
|
|
20502
21002
|
});
|
|
20503
21003
|
}
|
|
@@ -20513,14 +21013,14 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
|
|
|
20513
21013
|
try {
|
|
20514
21014
|
await ctx.database.write(async (writer) => {
|
|
20515
21015
|
await assertCanWrite2(ctx);
|
|
20516
|
-
let
|
|
21016
|
+
let record3;
|
|
20517
21017
|
try {
|
|
20518
|
-
|
|
21018
|
+
record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
20519
21019
|
} catch {
|
|
20520
21020
|
return;
|
|
20521
21021
|
}
|
|
20522
|
-
if (
|
|
20523
|
-
const topics = parseTopics(
|
|
21022
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return;
|
|
21023
|
+
const topics = parseTopics(record3.topics);
|
|
20524
21024
|
if (topics === null) return;
|
|
20525
21025
|
await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id2, topics));
|
|
20526
21026
|
relinked.push(id2);
|
|
@@ -20546,18 +21046,18 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
20546
21046
|
await assertCanWrite2(ctx);
|
|
20547
21047
|
const records = [];
|
|
20548
21048
|
for (const id2 of chunkIds) {
|
|
20549
|
-
let
|
|
21049
|
+
let record3;
|
|
20550
21050
|
try {
|
|
20551
|
-
|
|
21051
|
+
record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
20552
21052
|
} catch {
|
|
20553
21053
|
continue;
|
|
20554
21054
|
}
|
|
20555
|
-
if (
|
|
20556
|
-
if (parseTopics(
|
|
20557
|
-
records.push(
|
|
21055
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) continue;
|
|
21056
|
+
if (parseTopics(record3.topics) !== null) continue;
|
|
21057
|
+
records.push(record3);
|
|
20558
21058
|
}
|
|
20559
21059
|
if (records.length === 0) return;
|
|
20560
|
-
const links2 = await entityCtx.memoryEntityCollection.query(import_watermelondb24.Q.where("memory_id", import_watermelondb24.Q.oneOf(records.map((
|
|
21060
|
+
const links2 = await entityCtx.memoryEntityCollection.query(import_watermelondb24.Q.where("memory_id", import_watermelondb24.Q.oneOf(records.map((record3) => record3.id)))).unsafeFetchRaw();
|
|
20561
21061
|
const entityIds = Array.from(new Set(links2.map((link) => String(link.entity_id))));
|
|
20562
21062
|
const entitiesById = /* @__PURE__ */ new Map();
|
|
20563
21063
|
for (let j = 0; j < entityIds.length; j += CHUNK) {
|
|
@@ -20577,13 +21077,13 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
20577
21077
|
entities.add(entity);
|
|
20578
21078
|
}
|
|
20579
21079
|
const writes = [];
|
|
20580
|
-
for (const
|
|
20581
|
-
const entities = entitiesByMemory.get(
|
|
21080
|
+
for (const record3 of records) {
|
|
21081
|
+
const entities = entitiesByMemory.get(record3.id);
|
|
20582
21082
|
if (!entities?.size) continue;
|
|
20583
|
-
const source =
|
|
21083
|
+
const source = record3.topicsUserManaged ? "user" : "auto";
|
|
20584
21084
|
const write = await resolveMemoryTopicsWrite(
|
|
20585
21085
|
entityCtx,
|
|
20586
|
-
|
|
21086
|
+
record3.id,
|
|
20587
21087
|
Array.from(entities),
|
|
20588
21088
|
[],
|
|
20589
21089
|
source
|
|
@@ -20605,7 +21105,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
|
20605
21105
|
await ctx.database.write(async () => {
|
|
20606
21106
|
await assertCanWrite2(ctx);
|
|
20607
21107
|
const prepared = records.map(
|
|
20608
|
-
(
|
|
21108
|
+
(record3) => record3.prepareUpdate((r) => {
|
|
20609
21109
|
r._setRaw("is_deleted", true);
|
|
20610
21110
|
})
|
|
20611
21111
|
);
|
|
@@ -20676,22 +21176,22 @@ async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
|
20676
21176
|
import_watermelondb24.Q.where("id", import_watermelondb24.Q.oneOf(ids.slice(i, i + CHUNK))),
|
|
20677
21177
|
...ctx.userId !== void 0 ? [import_watermelondb24.Q.where("user_id", ctx.userId)] : []
|
|
20678
21178
|
).fetch();
|
|
20679
|
-
const eligible = records.filter((
|
|
20680
|
-
if (
|
|
21179
|
+
const eligible = records.filter((record3) => {
|
|
21180
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
20681
21181
|
if (opts.transition === "delete") {
|
|
20682
|
-
return
|
|
21182
|
+
return record3.archivedAt !== null && opts.now - record3.archivedAt > opts.hardDeleteWindowMs;
|
|
20683
21183
|
}
|
|
20684
|
-
const candidate = byId.get(
|
|
20685
|
-
return
|
|
21184
|
+
const candidate = byId.get(record3.id);
|
|
21185
|
+
return record3.archivedAt === null && record3.updatedAt.getTime() === candidate.updatedAt && (record3.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
|
|
20686
21186
|
});
|
|
20687
21187
|
const prepared = eligible.map(
|
|
20688
|
-
(
|
|
21188
|
+
(record3) => record3.prepareUpdate((row) => {
|
|
20689
21189
|
if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
|
|
20690
21190
|
else row._setRaw("is_deleted", true);
|
|
20691
21191
|
})
|
|
20692
21192
|
);
|
|
20693
21193
|
if (prepared.length > 0) await ctx.database.batch(prepared);
|
|
20694
|
-
applied = eligible.map((
|
|
21194
|
+
applied = eligible.map((record3) => record3.id);
|
|
20695
21195
|
});
|
|
20696
21196
|
} catch {
|
|
20697
21197
|
continue;
|
|
@@ -20709,21 +21209,21 @@ async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
|
20709
21209
|
}
|
|
20710
21210
|
async function archiveVaultMemoryOp(ctx, id2, opts) {
|
|
20711
21211
|
try {
|
|
20712
|
-
const
|
|
20713
|
-
if (
|
|
21212
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
21213
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
20714
21214
|
let stale = false;
|
|
20715
21215
|
const archivedAtValue = opts?.now ?? Date.now();
|
|
20716
21216
|
await ctx.database.write(async () => {
|
|
20717
21217
|
await assertCanWrite2(ctx);
|
|
20718
|
-
if (
|
|
21218
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3) || record3.archivedAt !== null) {
|
|
20719
21219
|
stale = true;
|
|
20720
21220
|
return;
|
|
20721
21221
|
}
|
|
20722
|
-
if (opts?.expectedUpdatedAt !== void 0 &&
|
|
21222
|
+
if (opts?.expectedUpdatedAt !== void 0 && record3.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record3.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
|
|
20723
21223
|
stale = true;
|
|
20724
21224
|
return;
|
|
20725
21225
|
}
|
|
20726
|
-
await
|
|
21226
|
+
await record3.update((r) => {
|
|
20727
21227
|
r._setRaw("archived_at", archivedAtValue);
|
|
20728
21228
|
});
|
|
20729
21229
|
});
|
|
@@ -20734,16 +21234,16 @@ async function archiveVaultMemoryOp(ctx, id2, opts) {
|
|
|
20734
21234
|
}
|
|
20735
21235
|
async function restoreVaultMemoryOp(ctx, id2) {
|
|
20736
21236
|
try {
|
|
20737
|
-
const
|
|
20738
|
-
if (
|
|
21237
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
21238
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
20739
21239
|
let stale = false;
|
|
20740
21240
|
await ctx.database.write(async () => {
|
|
20741
21241
|
await assertCanWrite2(ctx);
|
|
20742
|
-
if (
|
|
21242
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
|
|
20743
21243
|
stale = true;
|
|
20744
21244
|
return;
|
|
20745
21245
|
}
|
|
20746
|
-
await
|
|
21246
|
+
await record3.update((r) => {
|
|
20747
21247
|
r._setRaw("archived_at", null);
|
|
20748
21248
|
});
|
|
20749
21249
|
});
|
|
@@ -20754,18 +21254,18 @@ async function restoreVaultMemoryOp(ctx, id2) {
|
|
|
20754
21254
|
}
|
|
20755
21255
|
async function hardDeleteDecayedOp(ctx, id2, opts) {
|
|
20756
21256
|
try {
|
|
20757
|
-
const
|
|
20758
|
-
if (
|
|
21257
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
21258
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
20759
21259
|
const now = opts.now ?? Date.now();
|
|
20760
21260
|
let stale = false;
|
|
20761
21261
|
await ctx.database.write(async () => {
|
|
20762
21262
|
await assertCanWrite2(ctx);
|
|
20763
|
-
const archivedAt =
|
|
20764
|
-
if (
|
|
21263
|
+
const archivedAt = record3.archivedAt;
|
|
21264
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
|
|
20765
21265
|
stale = true;
|
|
20766
21266
|
return;
|
|
20767
21267
|
}
|
|
20768
|
-
await
|
|
21268
|
+
await record3.update((r) => {
|
|
20769
21269
|
r._setRaw("is_deleted", true);
|
|
20770
21270
|
});
|
|
20771
21271
|
});
|
|
@@ -20783,14 +21283,14 @@ async function hardDeleteDecayedOp(ctx, id2, opts) {
|
|
|
20783
21283
|
}
|
|
20784
21284
|
async function updateVaultMemoryEmbeddingOp(ctx, id2, embedding2, embeddingModel, expected) {
|
|
20785
21285
|
try {
|
|
20786
|
-
const
|
|
20787
|
-
if (
|
|
20788
|
-
const readUpdatedAt =
|
|
20789
|
-
const readStoredContent =
|
|
21286
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
21287
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
21288
|
+
const readUpdatedAt = record3.updatedAt.getTime();
|
|
21289
|
+
const readStoredContent = record3._getRaw("content");
|
|
20790
21290
|
if (expected?.updatedAt !== void 0 && expected.updatedAt !== readUpdatedAt) return false;
|
|
20791
21291
|
if (expected?.content !== void 0) {
|
|
20792
21292
|
const current = await vaultMemoryToStored(
|
|
20793
|
-
|
|
21293
|
+
record3,
|
|
20794
21294
|
ctx.walletAddress,
|
|
20795
21295
|
ctx.signMessage,
|
|
20796
21296
|
ctx.embeddedWalletSigner
|
|
@@ -20800,11 +21300,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id2, embedding2, embeddingModel
|
|
|
20800
21300
|
let written = false;
|
|
20801
21301
|
await ctx.database.write(async () => {
|
|
20802
21302
|
await assertCanWrite2(ctx);
|
|
20803
|
-
if (
|
|
20804
|
-
const originalUpdatedAt =
|
|
20805
|
-
if (originalUpdatedAt !== readUpdatedAt ||
|
|
21303
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return;
|
|
21304
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
21305
|
+
if (originalUpdatedAt !== readUpdatedAt || record3._getRaw("content") !== readStoredContent)
|
|
20806
21306
|
return;
|
|
20807
|
-
await
|
|
21307
|
+
await record3.update((r) => {
|
|
20808
21308
|
r._setRaw("embedding", embedding2);
|
|
20809
21309
|
r._setRaw("embedding_model", embeddingModel);
|
|
20810
21310
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
@@ -20969,26 +21469,26 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
|
|
|
20969
21469
|
inserted = writable.length;
|
|
20970
21470
|
if (writable.length === 0) return;
|
|
20971
21471
|
const prepared = writable.map(
|
|
20972
|
-
({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
|
|
20976
|
-
|
|
20977
|
-
|
|
20978
|
-
|
|
20979
|
-
|
|
20980
|
-
|
|
20981
|
-
|
|
20982
|
-
|
|
21472
|
+
({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record3) => {
|
|
21473
|
+
record3._raw.id = row.memoryId;
|
|
21474
|
+
record3._setRaw("content", content);
|
|
21475
|
+
record3._setRaw("scope", "shared");
|
|
21476
|
+
record3._setRaw("level", "matching");
|
|
21477
|
+
record3._setRaw("folder_id", null);
|
|
21478
|
+
record3._setRaw("user_id", ctx.userId ?? null);
|
|
21479
|
+
record3._setRaw("is_deleted", false);
|
|
21480
|
+
record3._setRaw("proof_count", 1);
|
|
21481
|
+
record3._setRaw("source", SOURCE_PHOTO);
|
|
21482
|
+
record3._setRaw(
|
|
20983
21483
|
"media",
|
|
20984
21484
|
row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
|
|
20985
21485
|
);
|
|
20986
|
-
|
|
20987
|
-
|
|
21486
|
+
record3._setRaw("visibility", "public");
|
|
21487
|
+
record3._setRaw("published_at", now);
|
|
20988
21488
|
if (row.eventTime) {
|
|
20989
|
-
|
|
20990
|
-
|
|
20991
|
-
|
|
21489
|
+
record3._setRaw("event_time_start", row.eventTime.start ?? null);
|
|
21490
|
+
record3._setRaw("event_time_end", row.eventTime.end ?? null);
|
|
21491
|
+
record3._setRaw("event_time_kind", row.eventTime.kind ?? null);
|
|
20992
21492
|
}
|
|
20993
21493
|
})
|
|
20994
21494
|
);
|
|
@@ -21820,11 +22320,11 @@ function folderToStored(folder) {
|
|
|
21820
22320
|
}
|
|
21821
22321
|
async function createVaultFolderOp(ctx, opts) {
|
|
21822
22322
|
const created = await ctx.database.write(async () => {
|
|
21823
|
-
return ctx.vaultFolderCollection.create((
|
|
21824
|
-
|
|
21825
|
-
|
|
21826
|
-
|
|
21827
|
-
|
|
22323
|
+
return ctx.vaultFolderCollection.create((record3) => {
|
|
22324
|
+
record3._setRaw("name", opts.name);
|
|
22325
|
+
record3._setRaw("scope", opts.scope ?? "private");
|
|
22326
|
+
record3._setRaw("is_system", opts.isSystem ?? false);
|
|
22327
|
+
record3._setRaw("is_deleted", false);
|
|
21828
22328
|
});
|
|
21829
22329
|
});
|
|
21830
22330
|
return folderToStored(created);
|
|
@@ -21835,14 +22335,14 @@ async function getAllVaultFoldersOp(ctx) {
|
|
|
21835
22335
|
}
|
|
21836
22336
|
async function updateVaultFolderOp(ctx, id2, opts) {
|
|
21837
22337
|
try {
|
|
21838
|
-
const
|
|
21839
|
-
if (
|
|
21840
|
-
const scopeChanged = opts.scope !== void 0 && opts.scope !==
|
|
22338
|
+
const record3 = await ctx.vaultFolderCollection.find(id2);
|
|
22339
|
+
if (record3.isDeleted) return null;
|
|
22340
|
+
const scopeChanged = opts.scope !== void 0 && opts.scope !== record3.scope;
|
|
21841
22341
|
const updated = await ctx.database.write(async () => {
|
|
21842
22342
|
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb32.Q.where("folder_id", id2), import_watermelondb32.Q.where("is_deleted", false)).fetch() : [];
|
|
21843
22343
|
const updates = [];
|
|
21844
22344
|
updates.push(
|
|
21845
|
-
|
|
22345
|
+
record3.prepareUpdate((r) => {
|
|
21846
22346
|
if (opts.name !== void 0) r._setRaw("name", opts.name);
|
|
21847
22347
|
if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
|
|
21848
22348
|
})
|
|
@@ -21865,8 +22365,8 @@ async function updateVaultFolderOp(ctx, id2, opts) {
|
|
|
21865
22365
|
}
|
|
21866
22366
|
async function deleteVaultFolderOp(ctx, id2) {
|
|
21867
22367
|
try {
|
|
21868
|
-
const
|
|
21869
|
-
if (
|
|
22368
|
+
const record3 = await ctx.vaultFolderCollection.find(id2);
|
|
22369
|
+
if (record3.isDeleted) return false;
|
|
21870
22370
|
await ctx.database.write(async () => {
|
|
21871
22371
|
const memories = await ctx.vaultMemoryCollection.query(import_watermelondb32.Q.where("folder_id", id2), import_watermelondb32.Q.where("is_deleted", false)).fetch();
|
|
21872
22372
|
const preparedMemories = memories.map(
|
|
@@ -21876,7 +22376,7 @@ async function deleteVaultFolderOp(ctx, id2) {
|
|
|
21876
22376
|
r._setRaw("scope", "private");
|
|
21877
22377
|
})
|
|
21878
22378
|
);
|
|
21879
|
-
const preparedFolder =
|
|
22379
|
+
const preparedFolder = record3.prepareUpdate((r) => {
|
|
21880
22380
|
r._setRaw("is_deleted", true);
|
|
21881
22381
|
});
|
|
21882
22382
|
await ctx.database.batch(...preparedMemories, preparedFolder);
|
|
@@ -21923,11 +22423,11 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
|
|
|
21923
22423
|
}
|
|
21924
22424
|
async function updateVaultFolderContextOp(ctx, id2, context) {
|
|
21925
22425
|
try {
|
|
21926
|
-
const
|
|
21927
|
-
if (
|
|
22426
|
+
const record3 = await ctx.vaultFolderCollection.find(id2);
|
|
22427
|
+
if (record3.isDeleted) return null;
|
|
21928
22428
|
const updated = await ctx.database.write(async () => {
|
|
21929
22429
|
await ctx.database.batch(
|
|
21930
|
-
|
|
22430
|
+
record3.prepareUpdate((r) => {
|
|
21931
22431
|
r._setRaw("context", context);
|
|
21932
22432
|
})
|
|
21933
22433
|
);
|
|
@@ -23046,9 +23546,9 @@ function loadVaultCorpus(ctx, options, preparation) {
|
|
|
23046
23546
|
const key3 = JSON.stringify(options ?? {});
|
|
23047
23547
|
let request = pending.get(key3);
|
|
23048
23548
|
if (!request) {
|
|
23049
|
-
const
|
|
23549
|
+
const entries2 = pending;
|
|
23050
23550
|
request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
|
|
23051
|
-
|
|
23551
|
+
entries2.delete(key3);
|
|
23052
23552
|
throw error;
|
|
23053
23553
|
});
|
|
23054
23554
|
pending.set(key3, request);
|
|
@@ -23089,7 +23589,7 @@ function embedVaultRows(ctx, options, rows, preparation) {
|
|
|
23089
23589
|
if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing2.set(keys[index], row);
|
|
23090
23590
|
});
|
|
23091
23591
|
if (missing2.size > 0) {
|
|
23092
|
-
const
|
|
23592
|
+
const entries2 = pending;
|
|
23093
23593
|
const batch = Promise.resolve().then(
|
|
23094
23594
|
() => generateEmbeddings(
|
|
23095
23595
|
[...missing2.values()].map((row) => row.content),
|
|
@@ -23106,16 +23606,16 @@ function embedVaultRows(ctx, options, rows, preparation) {
|
|
|
23106
23606
|
});
|
|
23107
23607
|
return vector2;
|
|
23108
23608
|
}).finally(() => {
|
|
23109
|
-
|
|
23110
|
-
if (
|
|
23609
|
+
entries2.delete(key3);
|
|
23610
|
+
if (entries2.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
|
|
23111
23611
|
});
|
|
23112
23612
|
pending.set(key3, request);
|
|
23113
23613
|
});
|
|
23114
23614
|
}
|
|
23115
23615
|
return Promise.all(
|
|
23116
23616
|
keys.map((key3) => {
|
|
23117
|
-
const
|
|
23118
|
-
if (
|
|
23617
|
+
const cached2 = prepared?.get(key3);
|
|
23618
|
+
if (cached2) return cached2;
|
|
23119
23619
|
const request = pending.get(key3);
|
|
23120
23620
|
if (!prepared) return request;
|
|
23121
23621
|
const retained = request.catch((error) => {
|
|
@@ -23815,10 +24315,10 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
23815
24315
|
const resolvedThisCall = /* @__PURE__ */ new Set();
|
|
23816
24316
|
if (!embeddingsDegraded) {
|
|
23817
24317
|
for (const k2 of keys) {
|
|
23818
|
-
const
|
|
23819
|
-
if (
|
|
24318
|
+
const cached2 = cachedRowVector(cache, k2.uniqueId, k2.updatedAt);
|
|
24319
|
+
if (cached2 && cached2.length === queryEmbedding.length) {
|
|
23820
24320
|
corpusStats.cacheHits++;
|
|
23821
|
-
vectored.push({ uniqueId: k2.uniqueId, embedding:
|
|
24321
|
+
vectored.push({ uniqueId: k2.uniqueId, embedding: cached2, updatedAt: k2.updatedAt });
|
|
23822
24322
|
continue;
|
|
23823
24323
|
}
|
|
23824
24324
|
corpusStats.cacheMisses++;
|
|
@@ -24116,12 +24616,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
24116
24616
|
for (let i = 0; queryEmbedding.length > 0 && i < memories.length; i++) {
|
|
24117
24617
|
const content = memories[i].content;
|
|
24118
24618
|
const memoryId = memories[i].uniqueId;
|
|
24119
|
-
const
|
|
24120
|
-
if (
|
|
24121
|
-
resolvedVectors.set(memoryId,
|
|
24619
|
+
const cached2 = cachedRowVector(cache, memoryId, memories[i].updatedAt, content);
|
|
24620
|
+
if (cached2 && cached2.length === queryEmbedding.length) {
|
|
24621
|
+
resolvedVectors.set(memoryId, cached2);
|
|
24122
24622
|
continue;
|
|
24123
24623
|
}
|
|
24124
|
-
if (
|
|
24624
|
+
if (cached2) cache.delete(memoryId);
|
|
24125
24625
|
const storedModel = memories[i].embeddingModel;
|
|
24126
24626
|
const modelCompatible = (storedModel ?? currentModel) === currentModel;
|
|
24127
24627
|
if (memories[i].embedding && modelCompatible) {
|
|
@@ -25812,9 +26312,9 @@ function createDecaySweeperOver(backend, options) {
|
|
|
25812
26312
|
if (ruleVerdict !== "keep") return rule;
|
|
25813
26313
|
if (!classifier || !isBorderline(input)) return rule;
|
|
25814
26314
|
if (input.id) {
|
|
25815
|
-
const
|
|
25816
|
-
if (
|
|
25817
|
-
return { verdict:
|
|
26315
|
+
const cached2 = classifierCache.get(input.id);
|
|
26316
|
+
if (cached2 && cached2.activityAt === lastActivityAt(input))
|
|
26317
|
+
return { verdict: cached2.verdict, source: "classifierDriven" };
|
|
25818
26318
|
}
|
|
25819
26319
|
if (sweep.classifierCalls >= maxClassifierCalls) {
|
|
25820
26320
|
sweep.classifierCapHits++;
|
|
@@ -27678,21 +28178,21 @@ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
|
|
|
27678
28178
|
};
|
|
27679
28179
|
const inputs = [];
|
|
27680
28180
|
for (const id2 of new Set(memoryIds)) {
|
|
27681
|
-
let
|
|
28181
|
+
let record3;
|
|
27682
28182
|
try {
|
|
27683
|
-
|
|
28183
|
+
record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
27684
28184
|
} catch (err) {
|
|
27685
28185
|
log.warn("[memory/topics] vault lookup failed for extraction", err);
|
|
27686
28186
|
skip(id2, "not-found");
|
|
27687
28187
|
continue;
|
|
27688
28188
|
}
|
|
27689
|
-
if (
|
|
28189
|
+
if (record3.isDeleted || ctx.userId !== void 0 && record3.userId !== ctx.userId || record3.topicsUserManaged) {
|
|
27690
28190
|
skip(id2, "excluded");
|
|
27691
28191
|
continue;
|
|
27692
28192
|
}
|
|
27693
28193
|
try {
|
|
27694
28194
|
const stored2 = await vaultMemoryToStored(
|
|
27695
|
-
|
|
28195
|
+
record3,
|
|
27696
28196
|
ctx.walletAddress,
|
|
27697
28197
|
ctx.signMessage,
|
|
27698
28198
|
ctx.embeddedWalletSigner
|
|
@@ -27999,6 +28499,7 @@ function createLocalMemoryStore(options) {
|
|
|
27999
28499
|
|
|
28000
28500
|
// src/lib/memory/store/memoryKeys.ts
|
|
28001
28501
|
var KEY_ID_DOMAIN = "anuma-private-memory-key-id-v1";
|
|
28502
|
+
var TOPIC_HASH_INFO = "anuma-private-memory-topic-hash-v1";
|
|
28002
28503
|
var MemoryKeyError = class extends Error {
|
|
28003
28504
|
constructor(message) {
|
|
28004
28505
|
super(message);
|
|
@@ -28014,17 +28515,40 @@ async function importAesKey(hex) {
|
|
|
28014
28515
|
["encrypt", "decrypt"]
|
|
28015
28516
|
);
|
|
28016
28517
|
}
|
|
28518
|
+
async function deriveTopicHashKey(hex) {
|
|
28519
|
+
const material = await crypto.subtle.importKey(
|
|
28520
|
+
"raw",
|
|
28521
|
+
hexToBytes(hex).buffer,
|
|
28522
|
+
{ name: "HKDF" },
|
|
28523
|
+
false,
|
|
28524
|
+
["deriveBits"]
|
|
28525
|
+
);
|
|
28526
|
+
const bits = await crypto.subtle.deriveBits(
|
|
28527
|
+
{
|
|
28528
|
+
name: "HKDF",
|
|
28529
|
+
hash: "SHA-256",
|
|
28530
|
+
salt: new Uint8Array(32),
|
|
28531
|
+
info: new TextEncoder().encode(TOPIC_HASH_INFO)
|
|
28532
|
+
},
|
|
28533
|
+
material,
|
|
28534
|
+
256
|
|
28535
|
+
);
|
|
28536
|
+
return crypto.subtle.importKey("raw", bits, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
28537
|
+
}
|
|
28538
|
+
function toHex(bytes4) {
|
|
28539
|
+
return Array.from(new Uint8Array(bytes4), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
28540
|
+
}
|
|
28017
28541
|
async function deriveMemoryKeyRing(signatureHex) {
|
|
28018
28542
|
const v3Hex = await deriveKeyFromSignatureV3(signatureHex);
|
|
28019
28543
|
const digest = await crypto.subtle.digest(
|
|
28020
28544
|
"SHA-256",
|
|
28021
28545
|
new TextEncoder().encode(`${KEY_ID_DOMAIN}:${v3Hex}`)
|
|
28022
28546
|
);
|
|
28023
|
-
const keyId = "v3:" + Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
28024
28547
|
return {
|
|
28025
|
-
keyId,
|
|
28548
|
+
keyId: "v3:" + toHex(digest),
|
|
28026
28549
|
v3: await importAesKey(v3Hex),
|
|
28027
|
-
v2: await importAesKey(await deriveKeyFromSignature(signatureHex))
|
|
28550
|
+
v2: await importAesKey(await deriveKeyFromSignature(signatureHex)),
|
|
28551
|
+
topicHash: await deriveTopicHashKey(v3Hex)
|
|
28028
28552
|
};
|
|
28029
28553
|
}
|
|
28030
28554
|
async function decryptWith(value, rings) {
|
|
@@ -28045,7 +28569,10 @@ function memoryCipher(canonical) {
|
|
|
28045
28569
|
if (!ciphertext.startsWith("enc:v3:") || !isEncrypted(ciphertext))
|
|
28046
28570
|
throw new MemoryKeyError("Remote memory content must be enc:v3 ciphertext");
|
|
28047
28571
|
return decryptWith(ciphertext, [canonical]);
|
|
28048
|
-
}
|
|
28572
|
+
},
|
|
28573
|
+
hashTopic: async (normalized2) => toHex(
|
|
28574
|
+
await crypto.subtle.sign("HMAC", canonical.topicHash, new TextEncoder().encode(normalized2))
|
|
28575
|
+
)
|
|
28049
28576
|
};
|
|
28050
28577
|
}
|
|
28051
28578
|
async function reencryptMemoryField(value, canonical, fallbacks = []) {
|
|
@@ -28481,8 +29008,9 @@ var DEFAULT_RATE_LIMIT_WAIT_MS = 1e4;
|
|
|
28481
29008
|
var MAX_ID_BYTES = 128;
|
|
28482
29009
|
var MAX_CONTENT_BYTES = 32 << 10;
|
|
28483
29010
|
var MAX_TEXT_BYTES = 16 << 10;
|
|
29011
|
+
var MAX_TOPICS_BYTES = 32 << 10;
|
|
28484
29012
|
var MAX_SHORT_BYTES = 256;
|
|
28485
|
-
var TEXT_FIELDS = ["
|
|
29013
|
+
var TEXT_FIELDS = ["media", "source_chunk_ids"];
|
|
28486
29014
|
var SHORT_FIELDS = [
|
|
28487
29015
|
"scope",
|
|
28488
29016
|
"kind",
|
|
@@ -28585,7 +29113,7 @@ function bytes3(value) {
|
|
|
28585
29113
|
return value === void 0 ? 0 : utf82.encode(value).length;
|
|
28586
29114
|
}
|
|
28587
29115
|
function fitsNearby(row) {
|
|
28588
|
-
return bytes3(row.memory_id) <= MAX_ID_BYTES && bytes3(row.content) <= MAX_CONTENT_BYTES && bytes3(row.kind_value) <= MAX_CONTENT_BYTES && TEXT_FIELDS.every((field10) => bytes3(row[field10]) <= MAX_TEXT_BYTES) && SHORT_FIELDS.every((field10) => bytes3(row[field10]) <= MAX_SHORT_BYTES);
|
|
29116
|
+
return bytes3(row.memory_id) <= MAX_ID_BYTES && bytes3(row.content) <= MAX_CONTENT_BYTES && bytes3(row.kind_value) <= MAX_CONTENT_BYTES && bytes3(row.topics) <= MAX_TOPICS_BYTES && sealedTopicNamesFit(row.topics) && TEXT_FIELDS.every((field10) => bytes3(row[field10]) <= MAX_TEXT_BYTES) && SHORT_FIELDS.every((field10) => bytes3(row[field10]) <= MAX_SHORT_BYTES);
|
|
28589
29117
|
}
|
|
28590
29118
|
function invalid2(raw) {
|
|
28591
29119
|
const id2 = raw.id;
|
|
@@ -28629,7 +29157,7 @@ function defined(value) {
|
|
|
28629
29157
|
Object.entries(value).filter(([, field10]) => field10 !== void 0)
|
|
28630
29158
|
);
|
|
28631
29159
|
}
|
|
28632
|
-
async function prepareRow(raw, canonical, rings, model, updatedAt) {
|
|
29160
|
+
async function prepareRow(raw, canonical, codec, rings, model, updatedAt) {
|
|
28633
29161
|
const deleted = bool(raw.is_deleted) ?? false;
|
|
28634
29162
|
const { encrypt } = memoryCipher(canonical);
|
|
28635
29163
|
const localKindValue = text15(raw.kind_value);
|
|
@@ -28643,10 +29171,12 @@ async function prepareRow(raw, canonical, rings, model, updatedAt) {
|
|
|
28643
29171
|
plaintext = void 0;
|
|
28644
29172
|
kindValue = void 0;
|
|
28645
29173
|
}
|
|
29174
|
+
const fields = metadata2(raw, model);
|
|
28646
29175
|
const row = {
|
|
28647
29176
|
...defined({
|
|
28648
|
-
...
|
|
28649
|
-
kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue)
|
|
29177
|
+
...fields,
|
|
29178
|
+
kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue),
|
|
29179
|
+
topics: fields.topics === void 0 ? void 0 : await codec.encodeTopics(fields.topics)
|
|
28650
29180
|
}),
|
|
28651
29181
|
memory_id: raw.id,
|
|
28652
29182
|
content: await encrypt(plaintext ?? ""),
|
|
@@ -28690,6 +29220,8 @@ function sameMetadata2(local, remote, model) {
|
|
|
28690
29220
|
if (field10 === "visibility") return (a ?? "private") === (b ?? "private");
|
|
28691
29221
|
if (field10 === "is_deleted" || field10 === "topics_user_managed" || field10 === "twin_opt_in")
|
|
28692
29222
|
return (a ?? false) === (b ?? false);
|
|
29223
|
+
if (field10 === "topics")
|
|
29224
|
+
return JSON.stringify(parseTopics(a)) === JSON.stringify(parseTopics(b));
|
|
28693
29225
|
return a === b;
|
|
28694
29226
|
});
|
|
28695
29227
|
}
|
|
@@ -28745,7 +29277,7 @@ async function missingIds(request, revisions, signal) {
|
|
|
28745
29277
|
}
|
|
28746
29278
|
return missing2;
|
|
28747
29279
|
}
|
|
28748
|
-
async function remoteMetadata(request, ids, signal) {
|
|
29280
|
+
async function remoteMetadata(request, codec, ids, signal) {
|
|
28749
29281
|
const rows = /* @__PURE__ */ new Map();
|
|
28750
29282
|
for (const batch of chunks(ids, QUERY_IDS)) {
|
|
28751
29283
|
let cursor;
|
|
@@ -28769,7 +29301,12 @@ async function remoteMetadata(request, ids, signal) {
|
|
|
28769
29301
|
if (!Array.isArray(page.items)) throw new Error("Invalid nearby private-memory page");
|
|
28770
29302
|
for (const item of page.items)
|
|
28771
29303
|
if (item.memory && typeof item.memory.memory_id === "string")
|
|
28772
|
-
rows.set(item.memory.memory_id,
|
|
29304
|
+
rows.set(item.memory.memory_id, {
|
|
29305
|
+
...item.memory,
|
|
29306
|
+
...typeof item.memory.topics === "string" && {
|
|
29307
|
+
topics: await codec.decodeTopics(item.memory.topics).catch(() => null)
|
|
29308
|
+
}
|
|
29309
|
+
});
|
|
28773
29310
|
cursor = typeof page.next_cursor === "string" ? page.next_cursor : void 0;
|
|
28774
29311
|
} while (cursor);
|
|
28775
29312
|
}
|
|
@@ -28787,6 +29324,7 @@ async function migrateMemoriesToRemote(options) {
|
|
|
28787
29324
|
const rings = [canonical, ...options.fallbacks ?? []];
|
|
28788
29325
|
const model = options.embeddingOptions?.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
28789
29326
|
const request = createNearbyRequest(options);
|
|
29327
|
+
const codec = createTopicCodec(memoryCipher(canonical));
|
|
28790
29328
|
const account = await request("/account", {}, signal);
|
|
28791
29329
|
if (typeof account.key_id === "string" && account.key_id !== canonical.keyId)
|
|
28792
29330
|
throw new RemoteMemoryError(
|
|
@@ -28803,7 +29341,7 @@ async function migrateMemoriesToRemote(options) {
|
|
|
28803
29341
|
...typeof t.kind === "string" && { kind: t.kind }
|
|
28804
29342
|
})).filter((t) => t.name.length > 0) : []);
|
|
28805
29343
|
if (localTopics.length)
|
|
28806
|
-
await createRemoteTopicPersistence(request).importTopics(localTopics, signal);
|
|
29344
|
+
await createRemoteTopicPersistence(request, codec).importTopics(localTopics, signal);
|
|
28807
29345
|
const skipped = /* @__PURE__ */ new Map();
|
|
28808
29346
|
const reembedded = /* @__PURE__ */ new Set();
|
|
28809
29347
|
const unembedded = /* @__PURE__ */ new Set();
|
|
@@ -28822,6 +29360,7 @@ async function migrateMemoriesToRemote(options) {
|
|
|
28822
29360
|
if (pending.size === 0 && !active) {
|
|
28823
29361
|
const remote = await remoteMetadata(
|
|
28824
29362
|
request,
|
|
29363
|
+
codec,
|
|
28825
29364
|
candidates.map((raw) => raw.id),
|
|
28826
29365
|
signal
|
|
28827
29366
|
);
|
|
@@ -28866,7 +29405,7 @@ async function migrateMemoriesToRemote(options) {
|
|
|
28866
29405
|
const updatedAt = pending.get(raw.id);
|
|
28867
29406
|
if (updatedAt === void 0) continue;
|
|
28868
29407
|
try {
|
|
28869
|
-
prepared.push(await prepareRow(raw, canonical, rings, model, updatedAt));
|
|
29408
|
+
prepared.push(await prepareRow(raw, canonical, codec, rings, model, updatedAt));
|
|
28870
29409
|
} catch (error) {
|
|
28871
29410
|
if (!(error instanceof MemoryKeyError)) throw error;
|
|
28872
29411
|
skipped.set(raw.id, "unreadable");
|
|
@@ -29026,7 +29565,7 @@ function topicInputs(topics, source) {
|
|
|
29026
29565
|
function mergeTopics(existing, added) {
|
|
29027
29566
|
const byName = /* @__PURE__ */ new Map();
|
|
29028
29567
|
for (const topic2 of [...existing, ...added]) {
|
|
29029
|
-
const key3 =
|
|
29568
|
+
const key3 = normalizeTopicName(topic2.name);
|
|
29030
29569
|
const kept = byName.get(key3);
|
|
29031
29570
|
if (!kept) byName.set(key3, topic2);
|
|
29032
29571
|
else if (kept.weight !== void 0 && topic2.weight !== void 0 && topic2.weight > kept.weight)
|
|
@@ -29041,7 +29580,7 @@ function sameTopics(stored2, next) {
|
|
|
29041
29580
|
return next.every((t) => keys.has(key3(t)));
|
|
29042
29581
|
}
|
|
29043
29582
|
function canonicalTopics(row) {
|
|
29044
|
-
return new Set((parseTopics(row.topics) ?? []).map((topic2) =>
|
|
29583
|
+
return new Set((parseTopics(row.topics) ?? []).map((topic2) => normalizeTopicName(topic2.name)));
|
|
29045
29584
|
}
|
|
29046
29585
|
function createRemoteMemoryStore(options) {
|
|
29047
29586
|
const { persistence, embeddingOptions } = options;
|
|
@@ -29088,10 +29627,10 @@ function createRemoteMemoryStore(options) {
|
|
|
29088
29627
|
const notify = (change, records = []) => {
|
|
29089
29628
|
invalidateReads();
|
|
29090
29629
|
if (subscribers.size)
|
|
29091
|
-
for (const
|
|
29092
|
-
const previous = seen.get(
|
|
29093
|
-
if ((previous?.version ?? 0) + 1 ===
|
|
29094
|
-
seen.set(
|
|
29630
|
+
for (const record3 of records) {
|
|
29631
|
+
const previous = seen.get(record3.memory.memory_id);
|
|
29632
|
+
if ((previous?.version ?? 0) + 1 === record3.version)
|
|
29633
|
+
seen.set(record3.memory.memory_id, subscriptionState(record3));
|
|
29095
29634
|
}
|
|
29096
29635
|
for (const subscriber of [...subscribers])
|
|
29097
29636
|
if (relevant(change, subscriber.options)) safely(subscriber.onChange);
|
|
@@ -29144,7 +29683,7 @@ function createRemoteMemoryStore(options) {
|
|
|
29144
29683
|
};
|
|
29145
29684
|
const enumerate = (filters, max = Infinity) => pages(decrypted, filters, max);
|
|
29146
29685
|
const memoriesByTopics = async (names) => {
|
|
29147
|
-
const wanted = new Set(names.map(
|
|
29686
|
+
const wanted = new Set(names.map(normalizeTopicName).filter(Boolean));
|
|
29148
29687
|
const out = /* @__PURE__ */ new Map();
|
|
29149
29688
|
const pages2 = await Promise.all(
|
|
29150
29689
|
chunks2([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
|
|
@@ -29156,7 +29695,7 @@ function createRemoteMemoryStore(options) {
|
|
|
29156
29695
|
return out;
|
|
29157
29696
|
};
|
|
29158
29697
|
const topicGraphRanking = async (query, recallOptions = {}) => {
|
|
29159
|
-
const wanted = new Set(extractQueryEntities(query).map(
|
|
29698
|
+
const wanted = new Set(extractQueryEntities(query).map(normalizeTopicName).filter(Boolean));
|
|
29160
29699
|
if (wanted.size === 0 || recallOptions.memoryIds?.length === 0) return [];
|
|
29161
29700
|
const rows = await pages(
|
|
29162
29701
|
metadata3,
|
|
@@ -29214,25 +29753,25 @@ function createRemoteMemoryStore(options) {
|
|
|
29214
29753
|
return run;
|
|
29215
29754
|
};
|
|
29216
29755
|
const live2 = async (id2) => {
|
|
29217
|
-
const
|
|
29218
|
-
return
|
|
29756
|
+
const record3 = await persistence.get(id2);
|
|
29757
|
+
return record3 && !record3.memory.is_deleted ? record3 : null;
|
|
29219
29758
|
};
|
|
29220
29759
|
const mutateLocked = async (id2, change, edit, writeOptions) => {
|
|
29221
29760
|
writeOptions?.signal?.throwIfAborted();
|
|
29222
|
-
const
|
|
29223
|
-
if (!
|
|
29224
|
-
if (
|
|
29761
|
+
const record3 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await live2(id2);
|
|
29762
|
+
if (!record3) return null;
|
|
29763
|
+
if (record3.memory.is_deleted) return null;
|
|
29225
29764
|
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
29226
29765
|
throw new MemorySourceIneligibleError();
|
|
29227
29766
|
writeOptions?.signal?.throwIfAborted();
|
|
29228
|
-
const next = edit(structuredClone(
|
|
29767
|
+
const next = edit(structuredClone(record3.memory));
|
|
29229
29768
|
if (!next) return null;
|
|
29230
29769
|
const saved = writeOptions?.leaseToken ? (await persistence.putMany(
|
|
29231
|
-
[{ memory: next, expectedVersion:
|
|
29770
|
+
[{ memory: next, expectedVersion: record3 }],
|
|
29232
29771
|
writeOptions.signal,
|
|
29233
29772
|
writeOptions.leaseToken
|
|
29234
|
-
))[0] : writeOptions?.signal ? await persistence.put(next,
|
|
29235
|
-
notify(typeof change === "function" ? change(
|
|
29773
|
+
))[0] : writeOptions?.signal ? await persistence.put(next, record3, writeOptions.signal) : await persistence.put(next, record3);
|
|
29774
|
+
notify(typeof change === "function" ? change(record3.memory) : change, [saved]);
|
|
29236
29775
|
return saved;
|
|
29237
29776
|
};
|
|
29238
29777
|
const mutate = (id2, change, edit, writeOptions) => serialized(id2, () => mutateLocked(id2, change, edit, writeOptions));
|
|
@@ -29254,12 +29793,12 @@ function createRemoteMemoryStore(options) {
|
|
|
29254
29793
|
}
|
|
29255
29794
|
const { records, unreadable } = read;
|
|
29256
29795
|
for (const id2 of slice) {
|
|
29257
|
-
const
|
|
29796
|
+
const record3 = records.get(id2);
|
|
29258
29797
|
if (unreadable.has(id2)) failed.set(id2, new Error(`Memory ${id2} could not be decrypted`));
|
|
29259
|
-
else if (!
|
|
29260
|
-
else if (!
|
|
29261
|
-
const memory = edit(structuredClone(
|
|
29262
|
-
if (memory) writes.push({ before:
|
|
29798
|
+
else if (!record3) failed.set(id2, new Error(`Memory ${id2} was not found`));
|
|
29799
|
+
else if (!record3.memory.is_deleted) {
|
|
29800
|
+
const memory = edit(structuredClone(record3.memory));
|
|
29801
|
+
if (memory) writes.push({ before: record3, memory });
|
|
29263
29802
|
}
|
|
29264
29803
|
}
|
|
29265
29804
|
if (writes.length === 0) return;
|
|
@@ -29270,10 +29809,10 @@ function createRemoteMemoryStore(options) {
|
|
|
29270
29809
|
leaseToken
|
|
29271
29810
|
);
|
|
29272
29811
|
const byChange = /* @__PURE__ */ new Map();
|
|
29273
|
-
written.forEach((
|
|
29274
|
-
saved.set(
|
|
29812
|
+
written.forEach((record3, i) => {
|
|
29813
|
+
saved.set(record3.memory.memory_id, record3);
|
|
29275
29814
|
const kind = change(writes[i].before.memory);
|
|
29276
|
-
byChange.set(kind, [...byChange.get(kind) ?? [],
|
|
29815
|
+
byChange.set(kind, [...byChange.get(kind) ?? [], record3]);
|
|
29277
29816
|
});
|
|
29278
29817
|
for (const [kind, changed] of byChange) notify(kind, changed);
|
|
29279
29818
|
} catch (error) {
|
|
@@ -29287,13 +29826,13 @@ function createRemoteMemoryStore(options) {
|
|
|
29287
29826
|
continue;
|
|
29288
29827
|
}
|
|
29289
29828
|
try {
|
|
29290
|
-
const
|
|
29829
|
+
const record3 = await mutateLocked(
|
|
29291
29830
|
id2,
|
|
29292
29831
|
change,
|
|
29293
29832
|
edit,
|
|
29294
29833
|
leaseToken || signal ? { leaseToken, signal } : void 0
|
|
29295
29834
|
);
|
|
29296
|
-
if (
|
|
29835
|
+
if (record3) saved.set(id2, record3);
|
|
29297
29836
|
} catch (rowError) {
|
|
29298
29837
|
signal?.throwIfAborted();
|
|
29299
29838
|
if (isRemoteWorkLeaseExpired(rowError)) throw rowError;
|
|
@@ -29389,12 +29928,12 @@ function createRemoteMemoryStore(options) {
|
|
|
29389
29928
|
const created = (records, inputs) => {
|
|
29390
29929
|
embedInBackground(records.filter((_, i) => inputs[i].embedding === void 0));
|
|
29391
29930
|
notify("membership", records);
|
|
29392
|
-
return records.map((
|
|
29931
|
+
return records.map((record3) => stored(record3.memory));
|
|
29393
29932
|
};
|
|
29394
|
-
const asStored = (
|
|
29933
|
+
const asStored = (record3) => record3 ? stored(record3.memory) : null;
|
|
29395
29934
|
const knownKinds = async (topics, signal) => {
|
|
29396
29935
|
const unkinded = [
|
|
29397
|
-
...new Set(topics.filter((t) => !t.kind).map((t) =>
|
|
29936
|
+
...new Set(topics.filter((t) => !t.kind).map((t) => normalizeTopicName(t.name)))
|
|
29398
29937
|
];
|
|
29399
29938
|
const kinds2 = /* @__PURE__ */ new Map();
|
|
29400
29939
|
for (const names of chunks2(unkinded, MAX_QUERY_TOPICS)) {
|
|
@@ -29406,13 +29945,13 @@ function createRemoteMemoryStore(options) {
|
|
|
29406
29945
|
...signal && { signal }
|
|
29407
29946
|
})) {
|
|
29408
29947
|
for (const topic2 of parseTopics(memory.topics) ?? []) {
|
|
29409
|
-
const name =
|
|
29948
|
+
const name = normalizeTopicName(topic2.name);
|
|
29410
29949
|
if (topic2.kind && !kinds2.has(name)) kinds2.set(name, topic2.kind);
|
|
29411
29950
|
}
|
|
29412
29951
|
}
|
|
29413
29952
|
}
|
|
29414
29953
|
return (topic2) => {
|
|
29415
|
-
const kind = topic2.kind ?? kinds2.get(
|
|
29954
|
+
const kind = topic2.kind ?? kinds2.get(normalizeTopicName(topic2.name));
|
|
29416
29955
|
return kind ? { ...topic2, kind } : topic2;
|
|
29417
29956
|
};
|
|
29418
29957
|
};
|
|
@@ -29435,7 +29974,7 @@ function createRemoteMemoryStore(options) {
|
|
|
29435
29974
|
...cursor2 && { cursor: cursor2 }
|
|
29436
29975
|
});
|
|
29437
29976
|
warnFailed(page.failed);
|
|
29438
|
-
for (const
|
|
29977
|
+
for (const record3 of page.items) records.set(record3.memory.memory_id, record3);
|
|
29439
29978
|
for (const failure of page.failed) unreadable.add(failure.memory_id);
|
|
29440
29979
|
cursor2 = page.next_cursor;
|
|
29441
29980
|
} while (cursor2);
|
|
@@ -29631,8 +30170,8 @@ function createRemoteMemoryStore(options) {
|
|
|
29631
30170
|
const failed = /* @__PURE__ */ new Map();
|
|
29632
30171
|
const collect = (page) => {
|
|
29633
30172
|
warnFailed(page.failed);
|
|
29634
|
-
for (const
|
|
29635
|
-
records.push({ id:
|
|
30173
|
+
for (const record3 of page.items)
|
|
30174
|
+
records.push({ id: record3.memory.memory_id, state: subscriptionState(record3) });
|
|
29636
30175
|
for (const failure of page.failed) failed.set(failure.memory_id, failure.version);
|
|
29637
30176
|
};
|
|
29638
30177
|
let resume = cursor2;
|
|
@@ -29837,7 +30376,7 @@ function createRemoteMemoryStore(options) {
|
|
|
29837
30376
|
result.failed += targets.length;
|
|
29838
30377
|
return finish();
|
|
29839
30378
|
}
|
|
29840
|
-
const writes = targets.flatMap((
|
|
30379
|
+
const writes = targets.flatMap((record3, i) => {
|
|
29841
30380
|
const vector2 = vectors[i];
|
|
29842
30381
|
if (!vector2) {
|
|
29843
30382
|
result.failed++;
|
|
@@ -29847,11 +30386,11 @@ function createRemoteMemoryStore(options) {
|
|
|
29847
30386
|
return [
|
|
29848
30387
|
{
|
|
29849
30388
|
memory: {
|
|
29850
|
-
...
|
|
30389
|
+
...record3.memory,
|
|
29851
30390
|
embedding: storedVector(vector2),
|
|
29852
30391
|
embedding_model: model
|
|
29853
30392
|
},
|
|
29854
|
-
expectedVersion:
|
|
30393
|
+
expectedVersion: record3
|
|
29855
30394
|
}
|
|
29856
30395
|
];
|
|
29857
30396
|
} catch {
|
|
@@ -29866,7 +30405,7 @@ function createRemoteMemoryStore(options) {
|
|
|
29866
30405
|
signal?.throwIfAborted();
|
|
29867
30406
|
const commit = async (slice) => {
|
|
29868
30407
|
const saved = await persistence.putMany(slice, signal, leaseToken);
|
|
29869
|
-
for (const
|
|
30408
|
+
for (const record3 of saved) repaired.add(record3.memory.memory_id);
|
|
29870
30409
|
result.reembedded += saved.length;
|
|
29871
30410
|
notify("embedding", saved);
|
|
29872
30411
|
};
|
|
@@ -29950,7 +30489,7 @@ function createRemoteMemoryStore(options) {
|
|
|
29950
30489
|
if (!topics.length) return;
|
|
29951
30490
|
const existing = new Set((await readTopics()).map((topic2) => topic2.name));
|
|
29952
30491
|
const missing2 = topics.flatMap((topic2) => {
|
|
29953
|
-
const name =
|
|
30492
|
+
const name = normalizeTopicName(topic2.name);
|
|
29954
30493
|
if (existing.has(name)) return [];
|
|
29955
30494
|
existing.add(name);
|
|
29956
30495
|
return [{ ...topic2, name }];
|
|
@@ -29981,7 +30520,7 @@ function createRemoteMemoryStore(options) {
|
|
|
29981
30520
|
include_superseded: true
|
|
29982
30521
|
})) {
|
|
29983
30522
|
for (const topic2 of parseTopics(memory.topics) ?? []) {
|
|
29984
|
-
const name =
|
|
30523
|
+
const name = normalizeTopicName(topic2.name);
|
|
29985
30524
|
if (!name) continue;
|
|
29986
30525
|
const entry = topics.get(name) ?? {
|
|
29987
30526
|
name,
|
|
@@ -30019,7 +30558,7 @@ function createRemoteMemoryStore(options) {
|
|
|
30019
30558
|
},
|
|
30020
30559
|
get: async (id2) => asStored(await live2(id2)),
|
|
30021
30560
|
listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
|
|
30022
|
-
(
|
|
30561
|
+
(record3) => stored(record3.memory)
|
|
30023
30562
|
),
|
|
30024
30563
|
memoriesByTopics,
|
|
30025
30564
|
topicsByMemories: async (memoryIds) => {
|
|
@@ -30035,8 +30574,8 @@ function createRemoteMemoryStore(options) {
|
|
|
30035
30574
|
return out;
|
|
30036
30575
|
},
|
|
30037
30576
|
create: async (input) => {
|
|
30038
|
-
const
|
|
30039
|
-
return created([
|
|
30577
|
+
const record3 = await persistence.put(newRow(input), 0);
|
|
30578
|
+
return created([record3], [input])[0];
|
|
30040
30579
|
},
|
|
30041
30580
|
createMany: async (inputs) => {
|
|
30042
30581
|
const out = [];
|
|
@@ -30123,12 +30662,12 @@ function createRemoteMemoryStore(options) {
|
|
|
30123
30662
|
(memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
|
|
30124
30663
|
),
|
|
30125
30664
|
restore: (id2) => serialized(id2, async () => {
|
|
30126
|
-
const
|
|
30127
|
-
if (!
|
|
30128
|
-
if (
|
|
30665
|
+
const record3 = await live2(id2);
|
|
30666
|
+
if (!record3) return false;
|
|
30667
|
+
if (record3.memory.archived_at === void 0 || record3.memory.archived_at === null)
|
|
30129
30668
|
return true;
|
|
30130
|
-
const { archived_at: _archivedAt, ...memory } =
|
|
30131
|
-
notify("edit", [await persistence.put(memory,
|
|
30669
|
+
const { archived_at: _archivedAt, ...memory } = record3.memory;
|
|
30670
|
+
notify("edit", [await persistence.put(memory, record3)]);
|
|
30132
30671
|
return true;
|
|
30133
30672
|
}),
|
|
30134
30673
|
setTopics: async (memoryId, topics) => {
|
|
@@ -30161,8 +30700,8 @@ function createRemoteMemoryStore(options) {
|
|
|
30161
30700
|
const now = /* @__PURE__ */ new Date();
|
|
30162
30701
|
return mergeTopics([], added).map(
|
|
30163
30702
|
(topic2) => ({
|
|
30164
|
-
uniqueId:
|
|
30165
|
-
canonicalName:
|
|
30703
|
+
uniqueId: normalizeTopicName(topic2.name),
|
|
30704
|
+
canonicalName: normalizeTopicName(topic2.name),
|
|
30166
30705
|
kind: topic2.kind ?? null,
|
|
30167
30706
|
createdAt: now,
|
|
30168
30707
|
updatedAt: now
|
|
@@ -33539,16 +34078,16 @@ var ZipProcessor = class {
|
|
|
33539
34078
|
try {
|
|
33540
34079
|
const arrayBuffer = await dataUrlToArrayBuffer(file.dataUrl);
|
|
33541
34080
|
const zip = await import_jszip.default.loadAsync(arrayBuffer);
|
|
33542
|
-
const
|
|
34081
|
+
const entries2 = [];
|
|
33543
34082
|
const processedContents = [];
|
|
33544
34083
|
zip.forEach((relativePath, zipEntry) => {
|
|
33545
|
-
|
|
34084
|
+
entries2.push({
|
|
33546
34085
|
path: relativePath,
|
|
33547
34086
|
isDirectory: zipEntry.dir,
|
|
33548
34087
|
zipObject: zipEntry
|
|
33549
34088
|
});
|
|
33550
34089
|
});
|
|
33551
|
-
const visibleEntries = this.includeHidden ?
|
|
34090
|
+
const visibleEntries = this.includeHidden ? entries2 : entries2.filter((entry) => !this.isHidden(entry.path));
|
|
33552
34091
|
visibleEntries.sort((a, b) => {
|
|
33553
34092
|
if (a.isDirectory !== b.isDirectory) {
|
|
33554
34093
|
return a.isDirectory ? -1 : 1;
|
|
@@ -33662,17 +34201,17 @@ var ZipProcessor = class {
|
|
|
33662
34201
|
/**
|
|
33663
34202
|
* Format the output with file listing and processed contents
|
|
33664
34203
|
*/
|
|
33665
|
-
formatOutput(
|
|
34204
|
+
formatOutput(entries2, processedContents) {
|
|
33666
34205
|
const lines = [];
|
|
33667
34206
|
lines.push("## Archive Contents\n");
|
|
33668
34207
|
lines.push("```");
|
|
33669
|
-
for (const entry of
|
|
34208
|
+
for (const entry of entries2) {
|
|
33670
34209
|
const icon = entry.isDirectory ? "\u{1F4C1}" : "\u{1F4C4}";
|
|
33671
34210
|
lines.push(`${icon} ${entry.path}`);
|
|
33672
34211
|
}
|
|
33673
34212
|
lines.push("```\n");
|
|
33674
|
-
const fileCount =
|
|
33675
|
-
const dirCount =
|
|
34213
|
+
const fileCount = entries2.filter((e) => !e.isDirectory).length;
|
|
34214
|
+
const dirCount = entries2.filter((e) => e.isDirectory).length;
|
|
33676
34215
|
lines.push(
|
|
33677
34216
|
`**Summary:** ${fileCount} file${fileCount !== 1 ? "s" : ""}, ${dirCount} director${dirCount !== 1 ? "ies" : "y"}
|
|
33678
34217
|
`
|
|
@@ -34856,13 +35395,13 @@ function serializeInline(node) {
|
|
|
34856
35395
|
function openTag(node, indent, depth, selfClose, maxLineWidth) {
|
|
34857
35396
|
const head = `<${tagName(node.tag)}`;
|
|
34858
35397
|
const tail = selfClose ? " />" : ">";
|
|
34859
|
-
const
|
|
34860
|
-
if (
|
|
34861
|
-
const single = `${head} ${
|
|
35398
|
+
const entries2 = Object.entries(node.attrs);
|
|
35399
|
+
if (entries2.length === 0) return `${head}${tail}`;
|
|
35400
|
+
const single = `${head} ${entries2.map(([k, v]) => formatAttr(k, v)).join(" ")}${tail}`;
|
|
34862
35401
|
if (single.length <= maxLineWidth) return single;
|
|
34863
35402
|
const attrPad = indent.repeat(depth + 1);
|
|
34864
35403
|
const closePad = indent.repeat(depth);
|
|
34865
|
-
const body =
|
|
35404
|
+
const body = entries2.map(([k, v]) => `${attrPad}${formatAttr(k, v)}`).join("\n");
|
|
34866
35405
|
return `${head}
|
|
34867
35406
|
${body}
|
|
34868
35407
|
${closePad}${selfClose ? "/>" : ">"}`;
|
|
@@ -34874,13 +35413,13 @@ function formatAttr(name, value) {
|
|
|
34874
35413
|
return `${name}={${formatObjectAttr(value)}}`;
|
|
34875
35414
|
}
|
|
34876
35415
|
function formatObjectAttr(obj) {
|
|
34877
|
-
const
|
|
35416
|
+
const entries2 = Object.entries(obj).map(([k, v]) => {
|
|
34878
35417
|
const key3 = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k) ? k : JSON.stringify(k);
|
|
34879
35418
|
if (typeof v === "string") return `${key3}: ${JSON.stringify(v)}`;
|
|
34880
35419
|
if (typeof v === "number") return `${key3}: ${String(v)}`;
|
|
34881
35420
|
return `${key3}: ${v ? "true" : "false"}`;
|
|
34882
35421
|
});
|
|
34883
|
-
return `{ ${
|
|
35422
|
+
return `{ ${entries2.join(", ")} }`;
|
|
34884
35423
|
}
|
|
34885
35424
|
function isSafeJsxText(text16) {
|
|
34886
35425
|
if (/[<>{}&]/.test(text16)) return false;
|
|
@@ -36267,7 +36806,7 @@ async function uploadFileToICloud(filename, content, backupRevision) {
|
|
|
36267
36806
|
const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
36268
36807
|
const arrayBuffer = await content.arrayBuffer();
|
|
36269
36808
|
const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
|
|
36270
|
-
const
|
|
36809
|
+
const record3 = {
|
|
36271
36810
|
recordType: RECORD_TYPE,
|
|
36272
36811
|
recordName,
|
|
36273
36812
|
fields: {
|
|
@@ -36278,7 +36817,7 @@ async function uploadFileToICloud(filename, content, backupRevision) {
|
|
|
36278
36817
|
...backupRevision ? { backupRevision: { value: backupRevision } } : {}
|
|
36279
36818
|
}
|
|
36280
36819
|
};
|
|
36281
|
-
const response = await database.saveRecords(
|
|
36820
|
+
const response = await database.saveRecords(record3);
|
|
36282
36821
|
if (!response.records || response.records.length === 0) {
|
|
36283
36822
|
throw new Error("Failed to upload file to iCloud");
|
|
36284
36823
|
}
|
|
@@ -36305,12 +36844,12 @@ async function listICloudFiles() {
|
|
|
36305
36844
|
while (response.continuationMarker) {
|
|
36306
36845
|
break;
|
|
36307
36846
|
}
|
|
36308
|
-
const files = allRecords.map((
|
|
36309
|
-
recordName:
|
|
36310
|
-
filename:
|
|
36311
|
-
modifiedAt: new Date(
|
|
36312
|
-
backupRevision:
|
|
36313
|
-
size: typeof
|
|
36847
|
+
const files = allRecords.map((record3) => ({
|
|
36848
|
+
recordName: record3.recordName,
|
|
36849
|
+
filename: record3.fields.filename?.value ?? "",
|
|
36850
|
+
modifiedAt: new Date(record3.modified?.timestamp ?? Date.now()),
|
|
36851
|
+
backupRevision: record3.fields.backupRevision?.value,
|
|
36852
|
+
size: typeof record3.fields.data?.value === "object" && record3.fields.data?.value !== null ? record3.fields.data.value.size : 0
|
|
36314
36853
|
}));
|
|
36315
36854
|
return files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
|
|
36316
36855
|
}
|
|
@@ -36323,8 +36862,8 @@ async function downloadICloudFile(recordName) {
|
|
|
36323
36862
|
if (!response.records || response.records.length === 0) {
|
|
36324
36863
|
throw new Error(`File not found: ${recordName}`);
|
|
36325
36864
|
}
|
|
36326
|
-
const
|
|
36327
|
-
const dataField =
|
|
36865
|
+
const record3 = response.records[0];
|
|
36866
|
+
const dataField = record3.fields.data?.value;
|
|
36328
36867
|
if (!dataField) {
|
|
36329
36868
|
throw new Error("No data in record");
|
|
36330
36869
|
}
|
|
@@ -36358,13 +36897,13 @@ async function findICloudFile(filename) {
|
|
|
36358
36897
|
if (!response.records || response.records.length === 0) {
|
|
36359
36898
|
return null;
|
|
36360
36899
|
}
|
|
36361
|
-
const
|
|
36900
|
+
const record3 = response.records[0];
|
|
36362
36901
|
return {
|
|
36363
|
-
recordName:
|
|
36364
|
-
filename:
|
|
36365
|
-
modifiedAt: new Date(
|
|
36366
|
-
backupRevision:
|
|
36367
|
-
size: typeof
|
|
36902
|
+
recordName: record3.recordName,
|
|
36903
|
+
filename: record3.fields.filename?.value ?? "",
|
|
36904
|
+
modifiedAt: new Date(record3.modified?.timestamp ?? Date.now()),
|
|
36905
|
+
backupRevision: record3.fields.backupRevision?.value,
|
|
36906
|
+
size: typeof record3.fields.data?.value === "object" && record3.fields.data?.value !== null ? record3.fields.data.value.size : 0
|
|
36368
36907
|
};
|
|
36369
36908
|
}
|
|
36370
36909
|
|
|
@@ -37720,13 +38259,13 @@ function useConversationRedactors(database, account, storage, secondaryStorage)
|
|
|
37720
38259
|
return (0, import_react5.useCallback)(
|
|
37721
38260
|
(conversationId, nerDetector) => {
|
|
37722
38261
|
if (!scope.active) return retiredRedactor;
|
|
37723
|
-
const
|
|
37724
|
-
if (
|
|
38262
|
+
const cached2 = scope.redactors.get(conversationId);
|
|
38263
|
+
if (cached2 && cached2.detector === nerDetector) {
|
|
37725
38264
|
scope.redactors.delete(conversationId);
|
|
37726
|
-
scope.redactors.set(conversationId,
|
|
37727
|
-
return
|
|
38265
|
+
scope.redactors.set(conversationId, cached2);
|
|
38266
|
+
return cached2.redactor;
|
|
37728
38267
|
}
|
|
37729
|
-
if (
|
|
38268
|
+
if (cached2) scope.evicted.push(cached2.redactor);
|
|
37730
38269
|
const redactor = new PiiRedactor({ nerDetector });
|
|
37731
38270
|
scope.redactors.set(conversationId, { redactor, detector: nerDetector });
|
|
37732
38271
|
if (scope.redactors.size > REDACTOR_LIMIT) {
|
|
@@ -40184,82 +40723,45 @@ function useChatStorage(options) {
|
|
|
40184
40723
|
await inbox.putPublicKey(publicKey);
|
|
40185
40724
|
registeredInboxKeyRef.current = { inbox, publicKey };
|
|
40186
40725
|
}
|
|
40187
|
-
|
|
40188
|
-
|
|
40189
|
-
|
|
40190
|
-
|
|
40191
|
-
|
|
40192
|
-
|
|
40193
|
-
|
|
40194
|
-
|
|
40195
|
-
|
|
40196
|
-
|
|
40197
|
-
|
|
40198
|
-
|
|
40726
|
+
return deliverInboxAnswers({
|
|
40727
|
+
inbox,
|
|
40728
|
+
keyPair,
|
|
40729
|
+
backend,
|
|
40730
|
+
store: async (opened, messageId) => {
|
|
40731
|
+
const { redactor } = resolveCallPii(
|
|
40732
|
+
void 0,
|
|
40733
|
+
piiRedaction,
|
|
40734
|
+
() => getConversationRedactor(opened.conversation_id, nerDetectorRef.current)
|
|
40735
|
+
);
|
|
40736
|
+
const knownToolCallEventIds = await backend.getToolCallEventIds(opened.conversation_id);
|
|
40737
|
+
const { fields, fileIds } = await toAssistantMessageFields(
|
|
40738
|
+
opened.response,
|
|
40739
|
+
opened.conversation_id,
|
|
40740
|
+
knownToolCallEventIds
|
|
40741
|
+
);
|
|
40742
|
+
const upserted = await backend.upsertMessage({
|
|
40743
|
+
...fields,
|
|
40744
|
+
content: redactor ? redactor.deAnonymize(fields.content) : fields.content,
|
|
40745
|
+
thinking: redactor && fields.thinking ? redactor.deAnonymize(fields.thinking) : fields.thinking,
|
|
40746
|
+
conversationId: opened.conversation_id,
|
|
40747
|
+
role: "assistant",
|
|
40748
|
+
model: opened.model,
|
|
40749
|
+
parentMessageId: opened.parent_message_id ?? void 0,
|
|
40750
|
+
wasStopped: opened.status === "tool_request",
|
|
40751
|
+
uniqueId: messageId
|
|
40199
40752
|
});
|
|
40200
|
-
|
|
40201
|
-
|
|
40202
|
-
|
|
40203
|
-
|
|
40204
|
-
|
|
40205
|
-
|
|
40206
|
-
if (!existing) {
|
|
40207
|
-
const parent = opened.parent_message_id;
|
|
40208
|
-
const ownsTurn = parent ? (await backend.getMessagesByIds([parent])).length > 0 : await backend.getConversation(opened.conversation_id) !== null;
|
|
40209
|
-
if (!ownsTurn) {
|
|
40210
|
-
results.push({ ...base, status: "elsewhere", assistantMessage: null });
|
|
40211
|
-
continue;
|
|
40212
|
-
}
|
|
40213
|
-
}
|
|
40214
|
-
let stored2 = existing;
|
|
40215
|
-
if (!stored2) {
|
|
40216
|
-
const { redactor } = resolveCallPii(
|
|
40217
|
-
void 0,
|
|
40218
|
-
piiRedaction,
|
|
40219
|
-
() => getConversationRedactor(opened.conversation_id, nerDetectorRef.current)
|
|
40220
|
-
);
|
|
40221
|
-
const knownToolCallEventIds = await backend.getToolCallEventIds(opened.conversation_id);
|
|
40222
|
-
const { fields, fileIds } = await toAssistantMessageFields(
|
|
40223
|
-
opened.response,
|
|
40224
|
-
opened.conversation_id,
|
|
40225
|
-
knownToolCallEventIds
|
|
40226
|
-
);
|
|
40227
|
-
stored2 = await backend.createMessage({
|
|
40228
|
-
...fields,
|
|
40229
|
-
content: redactor ? redactor.deAnonymize(fields.content) : fields.content,
|
|
40230
|
-
thinking: redactor && fields.thinking ? redactor.deAnonymize(fields.thinking) : fields.thinking,
|
|
40231
|
-
conversationId: opened.conversation_id,
|
|
40232
|
-
role: "assistant",
|
|
40233
|
-
model: opened.model,
|
|
40234
|
-
parentMessageId: opened.parent_message_id ?? void 0,
|
|
40235
|
-
wasStopped: opened.status === "tool_request" ? true : void 0,
|
|
40236
|
-
uniqueId: messageId
|
|
40237
|
-
});
|
|
40238
|
-
if (fileIds.length > 0) {
|
|
40239
|
-
try {
|
|
40240
|
-
await updateMediaMessageIdBatchOp(mediaCtx, fileIds, stored2.uniqueId);
|
|
40241
|
-
} catch (err) {
|
|
40242
|
-
getLogger().warn("[useChatStorage] Failed to link inbox media:", err);
|
|
40243
|
-
}
|
|
40753
|
+
const stored2 = await clearTurnErrors(backend, upserted);
|
|
40754
|
+
if (fileIds.length > 0) {
|
|
40755
|
+
try {
|
|
40756
|
+
await updateMediaMessageIdBatchOp(mediaCtx, fileIds, stored2.uniqueId);
|
|
40757
|
+
} catch (err) {
|
|
40758
|
+
getLogger().warn("[useChatStorage] Failed to link inbox media:", err);
|
|
40244
40759
|
}
|
|
40245
|
-
void embedMessageAsync(stored2, (text16) => redactor ? redactor.maskText(text16) : text16);
|
|
40246
40760
|
}
|
|
40247
|
-
|
|
40248
|
-
|
|
40249
|
-
...base,
|
|
40250
|
-
status: existing ? "delivered" : "stored",
|
|
40251
|
-
assistantMessage: stored2
|
|
40252
|
-
});
|
|
40253
|
-
} catch (err) {
|
|
40254
|
-
results.push({
|
|
40255
|
-
...base,
|
|
40256
|
-
status: "retry",
|
|
40257
|
-
assistantMessage: null,
|
|
40258
|
-
error: err instanceof Error ? err.message : String(err)
|
|
40259
|
-
});
|
|
40761
|
+
void embedMessageAsync(stored2, (text16) => redactor ? redactor.maskText(text16) : text16);
|
|
40762
|
+
return stored2;
|
|
40260
40763
|
}
|
|
40261
|
-
}
|
|
40262
|
-
return results;
|
|
40764
|
+
});
|
|
40263
40765
|
}, [
|
|
40264
40766
|
inbox,
|
|
40265
40767
|
walletAddress,
|
|
@@ -41255,11 +41757,11 @@ async function fetchAllModelPages(baseUrl, provider, headers, previous, signal)
|
|
|
41255
41757
|
return { pages, models, fetchedAt: Date.now() };
|
|
41256
41758
|
}
|
|
41257
41759
|
function loadModels(key3, baseUrl, provider, headers, force, signal) {
|
|
41258
|
-
const
|
|
41259
|
-
if (
|
|
41260
|
-
return Promise.resolve([...
|
|
41760
|
+
const cached2 = modelsCache.get(key3);
|
|
41761
|
+
if (cached2 && !force && Date.now() - cached2.fetchedAt < MODELS_CACHE_TTL_MS) {
|
|
41762
|
+
return Promise.resolve([...cached2.models]);
|
|
41261
41763
|
}
|
|
41262
|
-
const shared = (force ? void 0 : modelsInFlight.get(key3)) ?? startSharedRequest(key3, baseUrl, provider, headers,
|
|
41764
|
+
const shared = (force ? void 0 : modelsInFlight.get(key3)) ?? startSharedRequest(key3, baseUrl, provider, headers, cached2);
|
|
41263
41765
|
return waitForSharedRequest(key3, shared, signal).then((models) => [...models]);
|
|
41264
41766
|
}
|
|
41265
41767
|
function startSharedRequest(key3, baseUrl, provider, headers, previous) {
|
|
@@ -42116,20 +42618,20 @@ function startObserve(entry, walletAddress) {
|
|
|
42116
42618
|
"updated_at"
|
|
42117
42619
|
]).subscribe({
|
|
42118
42620
|
next: (records) => {
|
|
42119
|
-
const
|
|
42120
|
-
if (!
|
|
42621
|
+
const record3 = records[0];
|
|
42622
|
+
if (!record3) return;
|
|
42121
42623
|
const patch = {
|
|
42122
42624
|
userPreference: {
|
|
42123
|
-
uniqueId:
|
|
42124
|
-
walletAddress:
|
|
42125
|
-
nickname:
|
|
42126
|
-
occupation:
|
|
42127
|
-
description:
|
|
42128
|
-
models:
|
|
42129
|
-
personality:
|
|
42130
|
-
externalWallets:
|
|
42131
|
-
createdAt:
|
|
42132
|
-
updatedAt:
|
|
42625
|
+
uniqueId: record3.id,
|
|
42626
|
+
walletAddress: record3.walletAddress,
|
|
42627
|
+
nickname: record3.nickname,
|
|
42628
|
+
occupation: record3.occupation,
|
|
42629
|
+
description: record3.description,
|
|
42630
|
+
models: record3.models,
|
|
42631
|
+
personality: record3.personality,
|
|
42632
|
+
externalWallets: record3.externalWallets,
|
|
42633
|
+
createdAt: record3.createdAt,
|
|
42634
|
+
updatedAt: record3.updatedAt
|
|
42133
42635
|
}
|
|
42134
42636
|
};
|
|
42135
42637
|
if (isInitialEmission) {
|