@anuma/sdk 10.10.0 → 11.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +1024 -552
- package/dist/expo/index.d.mts +9 -5
- package/dist/expo/index.d.ts +9 -5
- package/dist/expo/index.mjs +1020 -552
- package/dist/react/index.cjs +1204 -661
- package/dist/react/index.d.mts +9 -5
- package/dist/react/index.d.ts +9 -5
- package/dist/react/index.mjs +1200 -661
- package/dist/tools/index.cjs +36 -2
- package/dist/tools/index.mjs +36 -2
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -544,9 +544,9 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
544
544
|
return false;
|
|
545
545
|
}
|
|
546
546
|
const startEpoch = sessionEpoch;
|
|
547
|
-
const
|
|
548
|
-
if (
|
|
549
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed,
|
|
547
|
+
const cached2 = refreshCandidatesByAddress.get(walletAddress);
|
|
548
|
+
if (cached2) {
|
|
549
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached2, startEpoch);
|
|
550
550
|
}
|
|
551
551
|
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
552
552
|
if (!derivePromise) {
|
|
@@ -895,10 +895,10 @@ function parsePlaintextToken(raw, walletAddress) {
|
|
|
895
895
|
return null;
|
|
896
896
|
}
|
|
897
897
|
if (!parsed || typeof parsed !== "object") return null;
|
|
898
|
-
const
|
|
899
|
-
const data =
|
|
898
|
+
const record3 = parsed;
|
|
899
|
+
const data = record3.token?.accessToken ? record3.token : record3;
|
|
900
900
|
if (!data?.accessToken) return null;
|
|
901
|
-
if (
|
|
901
|
+
if (record3.wallet && record3.wallet !== walletAddress) return null;
|
|
902
902
|
return data;
|
|
903
903
|
}
|
|
904
904
|
function promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress) {
|
|
@@ -990,10 +990,10 @@ async function discoverOAuthMetadata() {
|
|
|
990
990
|
}
|
|
991
991
|
async function getOAuthMetadata() {
|
|
992
992
|
if (typeof window !== "undefined") {
|
|
993
|
-
const
|
|
994
|
-
if (
|
|
993
|
+
const cached2 = sessionStorage.getItem(OAUTH_METADATA_KEY);
|
|
994
|
+
if (cached2) {
|
|
995
995
|
try {
|
|
996
|
-
return JSON.parse(
|
|
996
|
+
return JSON.parse(cached2);
|
|
997
997
|
} catch {
|
|
998
998
|
}
|
|
999
999
|
}
|
|
@@ -1097,8 +1097,8 @@ async function storeTokenData(data, walletAddress) {
|
|
|
1097
1097
|
} catch {
|
|
1098
1098
|
}
|
|
1099
1099
|
}
|
|
1100
|
-
const
|
|
1101
|
-
sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(
|
|
1100
|
+
const record3 = { wallet: walletAddress, token: data };
|
|
1101
|
+
sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record3));
|
|
1102
1102
|
}
|
|
1103
1103
|
async function getStoredTokenData(walletAddress) {
|
|
1104
1104
|
if (typeof window === "undefined") return null;
|
|
@@ -1502,25 +1502,25 @@ var TRUNCATION_MARKER_HEAD = "... (tool output truncated, ";
|
|
|
1502
1502
|
var TRUNCATION_MARKER_TAIL = " characters omitted)";
|
|
1503
1503
|
var MAX_PERSISTED_TOOL_RESULT_CHARS = 1e5;
|
|
1504
1504
|
function buildToolResultContent(results) {
|
|
1505
|
-
const
|
|
1505
|
+
const entries2 = results.map(
|
|
1506
1506
|
(r) => `Tool "${r.name}" returned: ${JSON.stringify(r.result)}`.replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029")
|
|
1507
1507
|
);
|
|
1508
|
-
const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0,
|
|
1509
|
-
const summary = capEntries(
|
|
1508
|
+
const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0, entries2.length - 1);
|
|
1509
|
+
const summary = capEntries(entries2, MAX_PERSISTED_TOOL_RESULT_CHARS - framing).join(
|
|
1510
1510
|
ENTRY_SEPARATOR
|
|
1511
1511
|
);
|
|
1512
1512
|
return `${HEADER}${summary}${FOOTER}`;
|
|
1513
1513
|
}
|
|
1514
|
-
function capToolResultEntries(
|
|
1515
|
-
return capEntries(
|
|
1514
|
+
function capToolResultEntries(entries2, budget) {
|
|
1515
|
+
return capEntries(entries2, budget);
|
|
1516
1516
|
}
|
|
1517
|
-
function capEntries(
|
|
1518
|
-
const smallestFirst =
|
|
1519
|
-
const capped = [...
|
|
1517
|
+
function capEntries(entries2, budget) {
|
|
1518
|
+
const smallestFirst = entries2.map((_, index) => index).sort((a, b) => entries2[a].length - entries2[b].length);
|
|
1519
|
+
const capped = [...entries2];
|
|
1520
1520
|
let remaining = budget;
|
|
1521
|
-
let unassigned =
|
|
1521
|
+
let unassigned = entries2.length;
|
|
1522
1522
|
for (const index of smallestFirst) {
|
|
1523
|
-
capped[index] = truncateEntry(
|
|
1523
|
+
capped[index] = truncateEntry(entries2[index], Math.floor(remaining / unassigned));
|
|
1524
1524
|
remaining -= capped[index].length;
|
|
1525
1525
|
unassigned--;
|
|
1526
1526
|
}
|
|
@@ -2408,11 +2408,11 @@ var ToolCallEventIndex = class {
|
|
|
2408
2408
|
this.pending = /* @__PURE__ */ new Map();
|
|
2409
2409
|
this.resetCount = collection.database._resetCount;
|
|
2410
2410
|
collection.experimentalSubscribe((changes) => {
|
|
2411
|
-
for (const { record:
|
|
2411
|
+
for (const { record: record3, type } of changes) {
|
|
2412
2412
|
this.replace(
|
|
2413
|
-
|
|
2414
|
-
type === "destroyed" ? void 0 :
|
|
2415
|
-
type === "destroyed" ? void 0 :
|
|
2413
|
+
record3.id,
|
|
2414
|
+
type === "destroyed" ? void 0 : record3.conversationId,
|
|
2415
|
+
type === "destroyed" ? void 0 : record3._getRaw("tool_call_events")
|
|
2416
2416
|
);
|
|
2417
2417
|
}
|
|
2418
2418
|
});
|
|
@@ -3855,15 +3855,15 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
3855
3855
|
staleSkipped++;
|
|
3856
3856
|
continue;
|
|
3857
3857
|
}
|
|
3858
|
-
const
|
|
3859
|
-
if (!
|
|
3858
|
+
const cached2 = chunkCache?.get(key3.id);
|
|
3859
|
+
if (!cached2 || cached2.version !== key3.version) {
|
|
3860
3860
|
missIds.push(key3.id);
|
|
3861
3861
|
continue;
|
|
3862
3862
|
}
|
|
3863
3863
|
cacheHits++;
|
|
3864
|
-
if (
|
|
3865
|
-
for (let ci = 0; ci <
|
|
3866
|
-
const vec =
|
|
3864
|
+
if (cached2.chunks.length > 0) {
|
|
3865
|
+
for (let ci = 0; ci < cached2.chunks.length; ci++) {
|
|
3866
|
+
const vec = cached2.chunks[ci];
|
|
3867
3867
|
if (vec.length === 0) continue;
|
|
3868
3868
|
const similarity = cosineSimilarity(queryVector, vec);
|
|
3869
3869
|
if (similarity >= minSimilarity) {
|
|
@@ -3876,8 +3876,8 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
3876
3876
|
});
|
|
3877
3877
|
}
|
|
3878
3878
|
}
|
|
3879
|
-
} else if (
|
|
3880
|
-
const similarity = cosineSimilarity(queryVector,
|
|
3879
|
+
} else if (cached2.fallback) {
|
|
3880
|
+
const similarity = cosineSimilarity(queryVector, cached2.fallback);
|
|
3881
3881
|
if (similarity >= minSimilarity) {
|
|
3882
3882
|
candidates.push({
|
|
3883
3883
|
id: key3.id,
|
|
@@ -4690,11 +4690,11 @@ var mergeConfigs = (a, b) => {
|
|
|
4690
4690
|
return config;
|
|
4691
4691
|
};
|
|
4692
4692
|
var headersEntries = (headers) => {
|
|
4693
|
-
const
|
|
4693
|
+
const entries2 = [];
|
|
4694
4694
|
headers.forEach((value, key3) => {
|
|
4695
|
-
|
|
4695
|
+
entries2.push([key3, value]);
|
|
4696
4696
|
});
|
|
4697
|
-
return
|
|
4697
|
+
return entries2;
|
|
4698
4698
|
};
|
|
4699
4699
|
var mergeHeaders = (...headers) => {
|
|
4700
4700
|
const mergedHeaders = new Headers();
|
|
@@ -5169,9 +5169,9 @@ async function embedOne(text16, options, outer) {
|
|
|
5169
5169
|
const { cache } = options;
|
|
5170
5170
|
if (!cache) return Array.from(await requestEmbedding(text16, options, outer));
|
|
5171
5171
|
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
5172
|
-
const
|
|
5173
|
-
const cachedModel =
|
|
5174
|
-
if (
|
|
5172
|
+
const cached2 = cache.get(text16);
|
|
5173
|
+
const cachedModel = cached2 && cachedEmbeddingModels.get(cached2);
|
|
5174
|
+
if (cached2 && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached2);
|
|
5175
5175
|
const inFlight = inFlightByCache.get(cache) ?? /* @__PURE__ */ new Map();
|
|
5176
5176
|
inFlightByCache.set(cache, inFlight);
|
|
5177
5177
|
const requestKey = JSON.stringify([model, text16]);
|
|
@@ -5286,10 +5286,10 @@ async function embedMany(texts, options, outer) {
|
|
|
5286
5286
|
const uncachedTexts = [];
|
|
5287
5287
|
for (let i = 0; i < texts.length; i++) {
|
|
5288
5288
|
if (cache) {
|
|
5289
|
-
const
|
|
5290
|
-
const cachedModel =
|
|
5291
|
-
if (
|
|
5292
|
-
results[i] = Array.from(
|
|
5289
|
+
const cached2 = cache.get(texts[i]);
|
|
5290
|
+
const cachedModel = cached2 && cachedEmbeddingModels.get(cached2);
|
|
5291
|
+
if (cached2 && (cachedModel === void 0 || cachedModel === embeddingModel)) {
|
|
5292
|
+
results[i] = Array.from(cached2);
|
|
5293
5293
|
continue;
|
|
5294
5294
|
}
|
|
5295
5295
|
}
|
|
@@ -5730,58 +5730,337 @@ function parseTopics(value) {
|
|
|
5730
5730
|
return out;
|
|
5731
5731
|
}
|
|
5732
5732
|
|
|
5733
|
+
// src/lib/memory/store/topicCodec.ts
|
|
5734
|
+
var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
|
|
5735
|
+
var topicHashPattern = /^[0-9a-f]{64}$/;
|
|
5736
|
+
var MAX_SEALED_TOPIC_NAME_BYTES = 1024;
|
|
5737
|
+
function normalizeTopicName(name) {
|
|
5738
|
+
return normalizeEntityName(name).normalize("NFC");
|
|
5739
|
+
}
|
|
5740
|
+
function sealedTopicNamesFit(json5) {
|
|
5741
|
+
return (entries(json5) ?? []).every(
|
|
5742
|
+
(entry) => !hashed(entry) || typeof entry.name !== "string" || entry.name.length <= MAX_SEALED_TOPIC_NAME_BYTES
|
|
5743
|
+
);
|
|
5744
|
+
}
|
|
5745
|
+
function record(value) {
|
|
5746
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5747
|
+
}
|
|
5748
|
+
function hashed(entry) {
|
|
5749
|
+
return record(entry) && typeof entry.name_hash === "string";
|
|
5750
|
+
}
|
|
5751
|
+
function entries(json5) {
|
|
5752
|
+
if (typeof json5 !== "string") return void 0;
|
|
5753
|
+
try {
|
|
5754
|
+
const parsed = JSON.parse(json5);
|
|
5755
|
+
return Array.isArray(parsed) ? parsed : void 0;
|
|
5756
|
+
} catch {
|
|
5757
|
+
return void 0;
|
|
5758
|
+
}
|
|
5759
|
+
}
|
|
5760
|
+
function cached(cache, key3, load) {
|
|
5761
|
+
let pending = cache.get(key3);
|
|
5762
|
+
if (!pending) {
|
|
5763
|
+
const loading = load();
|
|
5764
|
+
pending = loading;
|
|
5765
|
+
cache.set(key3, loading);
|
|
5766
|
+
loading.catch(() => {
|
|
5767
|
+
if (cache.get(key3) === loading) cache.delete(key3);
|
|
5768
|
+
});
|
|
5769
|
+
}
|
|
5770
|
+
return pending;
|
|
5771
|
+
}
|
|
5772
|
+
function createTopicCodec(cipher) {
|
|
5773
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
5774
|
+
const opened = /* @__PURE__ */ new Map();
|
|
5775
|
+
const seals = /* @__PURE__ */ new Map();
|
|
5776
|
+
const legacyNames = /* @__PURE__ */ new Map();
|
|
5777
|
+
const hash = async (name) => {
|
|
5778
|
+
const normalized2 = normalizeTopicName(name);
|
|
5779
|
+
if (!normalized2) return null;
|
|
5780
|
+
return cached(hashes, normalized2, async () => {
|
|
5781
|
+
const digest = await cipher.hashTopic(normalized2);
|
|
5782
|
+
if (!topicHashPattern.test(digest))
|
|
5783
|
+
throw new Error("Topic hashing must return 64 lowercase hex characters");
|
|
5784
|
+
return digest;
|
|
5785
|
+
});
|
|
5786
|
+
};
|
|
5787
|
+
const seal = async (display) => {
|
|
5788
|
+
const nameHash = await hash(display);
|
|
5789
|
+
if (nameHash === null) return null;
|
|
5790
|
+
return cached(seals, display, async () => {
|
|
5791
|
+
const name = await cipher.encrypt(display);
|
|
5792
|
+
if (name === display || !ciphertextPattern.test(name))
|
|
5793
|
+
throw new Error(
|
|
5794
|
+
"Topic encryption must return SDK ciphertext; refusing to upload plaintext"
|
|
5795
|
+
);
|
|
5796
|
+
opened.set(name, Promise.resolve(display));
|
|
5797
|
+
return { name_hash: nameHash, name };
|
|
5798
|
+
});
|
|
5799
|
+
};
|
|
5800
|
+
const plain2 = (name) => {
|
|
5801
|
+
if (!ciphertextPattern.test(name)) return Promise.resolve(name);
|
|
5802
|
+
let pending = legacyNames.get(name);
|
|
5803
|
+
if (!pending) {
|
|
5804
|
+
pending = cipher.decrypt(name).catch(() => name);
|
|
5805
|
+
legacyNames.set(name, pending);
|
|
5806
|
+
}
|
|
5807
|
+
return pending;
|
|
5808
|
+
};
|
|
5809
|
+
const open = async ({ name, name_hash: nameHash }) => {
|
|
5810
|
+
if (nameHash === void 0) return plain2(name);
|
|
5811
|
+
if (typeof name !== "string" || typeof nameHash !== "string" || !topicHashPattern.test(nameHash) || !ciphertextPattern.test(name))
|
|
5812
|
+
throw new Error("Nearby returned a malformed topic name");
|
|
5813
|
+
const plaintext = await cached(opened, name, async () => {
|
|
5814
|
+
const value = await cipher.decrypt(name);
|
|
5815
|
+
if (value === name) throw new Error("Topic decryption failed");
|
|
5816
|
+
return value;
|
|
5817
|
+
});
|
|
5818
|
+
if (await hash(plaintext) !== nameHash) throw new Error("Topic name does not match its hash");
|
|
5819
|
+
if (!seals.has(plaintext)) seals.set(plaintext, Promise.resolve({ name_hash: nameHash, name }));
|
|
5820
|
+
return plaintext;
|
|
5821
|
+
};
|
|
5822
|
+
return {
|
|
5823
|
+
hash,
|
|
5824
|
+
seal,
|
|
5825
|
+
open,
|
|
5826
|
+
encodeTopics: async (json5) => {
|
|
5827
|
+
const list = entries(json5);
|
|
5828
|
+
if (!list) return json5;
|
|
5829
|
+
const sealed2 = await Promise.all(
|
|
5830
|
+
list.map(async (entry) => {
|
|
5831
|
+
if (!record(entry) || typeof entry.name !== "string") return null;
|
|
5832
|
+
const name = await seal(await plain2(entry.name));
|
|
5833
|
+
return name && { ...entry, name: name.name, name_hash: name.name_hash };
|
|
5834
|
+
})
|
|
5835
|
+
);
|
|
5836
|
+
return JSON.stringify(sealed2.filter((entry) => entry !== null));
|
|
5837
|
+
},
|
|
5838
|
+
decodeTopics: async (json5) => {
|
|
5839
|
+
const list = entries(json5);
|
|
5840
|
+
if (!list?.some(
|
|
5841
|
+
(entry) => hashed(entry) || record(entry) && typeof entry.name === "string" && ciphertextPattern.test(entry.name)
|
|
5842
|
+
))
|
|
5843
|
+
return json5;
|
|
5844
|
+
const decoded = await Promise.all(
|
|
5845
|
+
list.map(async (entry) => {
|
|
5846
|
+
if (!hashed(entry))
|
|
5847
|
+
return record(entry) && typeof entry.name === "string" ? { ...entry, name: await plain2(entry.name) } : entry;
|
|
5848
|
+
const { name_hash: nameHash, ...rest } = entry;
|
|
5849
|
+
return { ...rest, name: await open({ name: entry.name, name_hash: nameHash }) };
|
|
5850
|
+
})
|
|
5851
|
+
);
|
|
5852
|
+
return JSON.stringify(decoded);
|
|
5853
|
+
},
|
|
5854
|
+
isLegacy: (json5) => (entries(json5) ?? []).some(
|
|
5855
|
+
(entry) => record(entry) && typeof entry.name === "string" && !hashed(entry)
|
|
5856
|
+
),
|
|
5857
|
+
matchesLegacy: async (json5, names, hashes2) => {
|
|
5858
|
+
const list = typeof json5 === "string" ? entries(json5) ?? [] : [];
|
|
5859
|
+
if (list.some((entry) => hashed(entry) && hashes2.has(entry.name_hash))) return false;
|
|
5860
|
+
const legacy = await Promise.all(
|
|
5861
|
+
list.map(
|
|
5862
|
+
async (entry) => record(entry) && typeof entry.name === "string" && !hashed(entry) ? normalizeTopicName(await plain2(entry.name)) : null
|
|
5863
|
+
)
|
|
5864
|
+
);
|
|
5865
|
+
return legacy.some((name) => name !== null && names.has(name));
|
|
5866
|
+
},
|
|
5867
|
+
encodeCatalog: async (topic2) => {
|
|
5868
|
+
const sealed2 = await seal(normalizeTopicName(await plain2(topic2.name)));
|
|
5869
|
+
return sealed2 && { ...topic2, name: sealed2.name, name_hash: sealed2.name_hash };
|
|
5870
|
+
},
|
|
5871
|
+
decodeCatalog: async (item) => {
|
|
5872
|
+
const { name_hash: nameHash, ...rest } = item;
|
|
5873
|
+
return { ...rest, name: await open({ name: item.name, name_hash: nameHash }) };
|
|
5874
|
+
}
|
|
5875
|
+
};
|
|
5876
|
+
}
|
|
5877
|
+
|
|
5733
5878
|
// src/lib/memory/store/remoteTopics.ts
|
|
5879
|
+
var RETIRE_CONCURRENCY = 8;
|
|
5734
5880
|
function topic(value) {
|
|
5735
5881
|
const t = value;
|
|
5736
|
-
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")
|
|
5882
|
+
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")
|
|
5737
5883
|
throw new Error("Invalid nearby topic");
|
|
5738
5884
|
return t;
|
|
5739
5885
|
}
|
|
5740
|
-
function
|
|
5886
|
+
async function wireTopics(request, signal) {
|
|
5887
|
+
const out = [];
|
|
5888
|
+
let cursor;
|
|
5889
|
+
do {
|
|
5890
|
+
const page = await request(
|
|
5891
|
+
"/topics?limit=200" + (cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""),
|
|
5892
|
+
{},
|
|
5893
|
+
signal
|
|
5894
|
+
);
|
|
5895
|
+
if (!Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string")
|
|
5896
|
+
throw new Error("Invalid nearby topic page");
|
|
5897
|
+
out.push(...page.items.map(topic));
|
|
5898
|
+
cursor = page.next_cursor;
|
|
5899
|
+
} while (cursor);
|
|
5900
|
+
return out;
|
|
5901
|
+
}
|
|
5902
|
+
function hashesOf(items) {
|
|
5903
|
+
return new Set(items.flatMap((t) => t.name_hash === void 0 ? [] : [t.name_hash]));
|
|
5904
|
+
}
|
|
5905
|
+
async function sealedImport(request, codec, topics, signal) {
|
|
5906
|
+
let oversized = 0;
|
|
5907
|
+
for (let i = 0; i < topics.length; i += 50) {
|
|
5908
|
+
signal?.throwIfAborted();
|
|
5909
|
+
const sealed2 = (await Promise.all(topics.slice(i, i + 50).map((t) => codec.encodeCatalog(t)))).filter((t) => {
|
|
5910
|
+
if (t === null) return false;
|
|
5911
|
+
if (t.name.length <= MAX_SEALED_TOPIC_NAME_BYTES) return true;
|
|
5912
|
+
oversized++;
|
|
5913
|
+
return false;
|
|
5914
|
+
});
|
|
5915
|
+
if (sealed2.length)
|
|
5916
|
+
await request(
|
|
5917
|
+
"/topics/import",
|
|
5918
|
+
{ method: "POST", body: JSON.stringify({ topics: sealed2 }) },
|
|
5919
|
+
signal
|
|
5920
|
+
);
|
|
5921
|
+
}
|
|
5922
|
+
signal?.throwIfAborted();
|
|
5923
|
+
if (oversized)
|
|
5924
|
+
getLogger().warn(
|
|
5925
|
+
`[memory/remote] Skipped ${oversized} topic catalog entries whose sealed name exceeds ${MAX_SEALED_TOPIC_NAME_BYTES} bytes`
|
|
5926
|
+
);
|
|
5927
|
+
}
|
|
5928
|
+
function createRemoteTopicPersistence(request, codec) {
|
|
5929
|
+
let legacyOnly = /* @__PURE__ */ new Set();
|
|
5741
5930
|
return {
|
|
5742
5931
|
topics: async () => {
|
|
5743
|
-
const
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5932
|
+
const items = await wireTopics(request);
|
|
5933
|
+
const hashed2 = hashesOf(items);
|
|
5934
|
+
const legacy = /* @__PURE__ */ new Set();
|
|
5935
|
+
const decoded = await Promise.all(
|
|
5936
|
+
items.map(async (item) => {
|
|
5937
|
+
const plain2 = await codec.decodeCatalog(item);
|
|
5938
|
+
const name = normalizeTopicName(plain2.name);
|
|
5939
|
+
if (item.name_hash === void 0) {
|
|
5940
|
+
const hash = await codec.hash(name);
|
|
5941
|
+
if (hash !== null && hashed2.has(hash)) return null;
|
|
5942
|
+
legacy.add(name);
|
|
5943
|
+
}
|
|
5944
|
+
return { ...plain2, name };
|
|
5945
|
+
})
|
|
5946
|
+
);
|
|
5947
|
+
legacyOnly = legacy;
|
|
5948
|
+
return decoded.filter((t) => t !== null);
|
|
5756
5949
|
},
|
|
5757
5950
|
putTopic: async (value, expectedVersion) => {
|
|
5758
5951
|
if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
|
|
5759
5952
|
throw new Error("Expected topic version must be a nonnegative integer");
|
|
5760
|
-
|
|
5953
|
+
const sealed2 = await codec.encodeCatalog(value);
|
|
5954
|
+
if (!sealed2) throw new Error("Topic name must not be empty");
|
|
5955
|
+
const saved = topic(
|
|
5761
5956
|
await request("/topics", {
|
|
5762
5957
|
method: "PUT",
|
|
5763
|
-
body: JSON.stringify({
|
|
5958
|
+
body: JSON.stringify({
|
|
5959
|
+
topic: sealed2,
|
|
5960
|
+
expected_version: legacyOnly.has(normalizeTopicName(value.name)) ? 0 : expectedVersion
|
|
5961
|
+
})
|
|
5764
5962
|
})
|
|
5765
5963
|
);
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5964
|
+
const decoded = await codec.decodeCatalog(saved);
|
|
5965
|
+
legacyOnly.delete(decoded.name);
|
|
5966
|
+
return decoded;
|
|
5967
|
+
},
|
|
5968
|
+
importTopics: (topics, signal) => sealedImport(
|
|
5969
|
+
request,
|
|
5970
|
+
codec,
|
|
5971
|
+
topics.map(({ name, kind }) => ({ name, ...kind !== void 0 && { kind } })),
|
|
5972
|
+
signal
|
|
5973
|
+
)
|
|
5974
|
+
};
|
|
5975
|
+
}
|
|
5976
|
+
async function retireLegacyTopics(request, codec, topics, imported, signal) {
|
|
5977
|
+
const failures = [];
|
|
5978
|
+
const put = async (topic2, expectedVersion) => {
|
|
5979
|
+
try {
|
|
5980
|
+
await request(
|
|
5981
|
+
"/topics",
|
|
5982
|
+
{ method: "PUT", body: JSON.stringify({ topic: topic2, expected_version: expectedVersion }) },
|
|
5983
|
+
signal
|
|
5984
|
+
);
|
|
5985
|
+
return "saved";
|
|
5986
|
+
} catch (error) {
|
|
5987
|
+
if (signal?.aborted) throw error;
|
|
5988
|
+
if (error instanceof RemoteMemoryError && error.status === 409) return "conflict";
|
|
5989
|
+
failures.push(error);
|
|
5990
|
+
return "failed";
|
|
5991
|
+
}
|
|
5992
|
+
};
|
|
5993
|
+
const retire = (item) => put(
|
|
5994
|
+
{ name: item.name, ...item.kind !== void 0 && { kind: item.kind }, is_deleted: true },
|
|
5995
|
+
item.version
|
|
5996
|
+
);
|
|
5997
|
+
const changed = [];
|
|
5998
|
+
let next = 0;
|
|
5999
|
+
const worker = async () => {
|
|
6000
|
+
while (next < topics.length) {
|
|
5779
6001
|
signal?.throwIfAborted();
|
|
6002
|
+
const item = topics[next++];
|
|
6003
|
+
if (await retire(item) === "conflict") changed.push(item);
|
|
5780
6004
|
}
|
|
5781
6005
|
};
|
|
6006
|
+
await Promise.all(
|
|
6007
|
+
Array.from({ length: Math.min(RETIRE_CONCURRENCY, topics.length) }, () => worker())
|
|
6008
|
+
);
|
|
6009
|
+
if (changed.length) {
|
|
6010
|
+
const current = await wireTopics(request, signal);
|
|
6011
|
+
for (const stale of changed) {
|
|
6012
|
+
const legacy = current.find((t) => t.name_hash === void 0 && t.name === stale.name);
|
|
6013
|
+
if (!legacy || legacy.is_deleted) continue;
|
|
6014
|
+
const hash = await codec.hash(await codec.open(legacy));
|
|
6015
|
+
const copy = current.find((t) => t.name_hash !== void 0 && t.name_hash === hash);
|
|
6016
|
+
if (!copy || hash === null) continue;
|
|
6017
|
+
const newer = imported.has(hash) || Date.parse(legacy.server_updated_at) > Date.parse(copy.server_updated_at);
|
|
6018
|
+
if (newer && (copy.is_deleted || legacy.kind !== copy.kind)) {
|
|
6019
|
+
const sealed2 = await codec.encodeCatalog({
|
|
6020
|
+
name: legacy.name,
|
|
6021
|
+
...legacy.kind !== void 0 && { kind: legacy.kind },
|
|
6022
|
+
is_deleted: false
|
|
6023
|
+
});
|
|
6024
|
+
if (!sealed2 || await put(sealed2, copy.version) !== "saved") continue;
|
|
6025
|
+
}
|
|
6026
|
+
await retire(legacy);
|
|
6027
|
+
}
|
|
6028
|
+
}
|
|
6029
|
+
if (failures.length)
|
|
6030
|
+
getLogger().warn(
|
|
6031
|
+
`[memory/remote] Could not retire ${failures.length} upgraded topic catalog entries:`,
|
|
6032
|
+
failures[0]
|
|
6033
|
+
);
|
|
6034
|
+
}
|
|
6035
|
+
async function upgradeLegacyTopicCatalog(request, codec, signal) {
|
|
6036
|
+
const items = await wireTopics(request, signal);
|
|
6037
|
+
const hashed2 = hashesOf(items);
|
|
6038
|
+
const hashes = await Promise.all(
|
|
6039
|
+
items.map(
|
|
6040
|
+
async (item) => item.name_hash === void 0 ? codec.hash(await codec.open(item)) : null
|
|
6041
|
+
)
|
|
6042
|
+
);
|
|
6043
|
+
const sources = /* @__PURE__ */ new Map();
|
|
6044
|
+
const live2 = [];
|
|
6045
|
+
items.forEach((item, i) => {
|
|
6046
|
+
const hash = hashes[i];
|
|
6047
|
+
if (hash === null) return;
|
|
6048
|
+
if (!item.is_deleted) live2.push(item);
|
|
6049
|
+
if (hashed2.has(hash)) return;
|
|
6050
|
+
const source = sources.get(hash);
|
|
6051
|
+
if (!source || source.is_deleted && !item.is_deleted) sources.set(hash, item);
|
|
6052
|
+
});
|
|
6053
|
+
const legacy = [...sources.values()].map((item) => ({
|
|
6054
|
+
name: item.name,
|
|
6055
|
+
...item.kind !== void 0 && { kind: item.kind },
|
|
6056
|
+
...item.is_deleted && { is_deleted: true }
|
|
6057
|
+
}));
|
|
6058
|
+
await sealedImport(request, codec, legacy, signal);
|
|
6059
|
+
await retireLegacyTopics(request, codec, live2, new Set(sources.keys()), signal);
|
|
6060
|
+
return legacy.length;
|
|
5782
6061
|
}
|
|
5783
6062
|
async function createRemoteTopic(persistence, name) {
|
|
5784
|
-
const canonical =
|
|
6063
|
+
const canonical = normalizeTopicName(name);
|
|
5785
6064
|
if (!canonical) return null;
|
|
5786
6065
|
const existing = (await persistence.topics()).find((t) => t.name === canonical);
|
|
5787
6066
|
if (existing && !existing.is_deleted) return canonical;
|
|
@@ -5869,7 +6148,10 @@ var RemoteMemoryError = class extends Error {
|
|
|
5869
6148
|
this.name = "RemoteMemoryError";
|
|
5870
6149
|
}
|
|
5871
6150
|
};
|
|
5872
|
-
var
|
|
6151
|
+
var TOPIC_UPGRADE_PROCESSOR = "topic-hash-v1";
|
|
6152
|
+
var TOPIC_UPGRADE_PAGE = 50;
|
|
6153
|
+
var LEGACY_TOPIC_CURSOR = "legacy-topics:";
|
|
6154
|
+
var LEGACY_TOPIC_RECHECK_MS = 6e4;
|
|
5873
6155
|
var memoryFields = {
|
|
5874
6156
|
memory_id: true,
|
|
5875
6157
|
content: true,
|
|
@@ -5929,7 +6211,8 @@ var queryFields = [
|
|
|
5929
6211
|
"fact_types",
|
|
5930
6212
|
"visibility",
|
|
5931
6213
|
"memory_ids",
|
|
5932
|
-
"
|
|
6214
|
+
"topic_hashes",
|
|
6215
|
+
"topics_legacy",
|
|
5933
6216
|
"updated_after",
|
|
5934
6217
|
"topics_due",
|
|
5935
6218
|
"topics_extracted",
|
|
@@ -5939,11 +6222,17 @@ var queryFields = [
|
|
|
5939
6222
|
"limit",
|
|
5940
6223
|
"include_embeddings"
|
|
5941
6224
|
];
|
|
5942
|
-
function
|
|
6225
|
+
function isVersionConflict(error) {
|
|
6226
|
+
return error instanceof RemoteMemoryError && error.code === "version_conflict";
|
|
6227
|
+
}
|
|
6228
|
+
function isRejectedRow(error) {
|
|
6229
|
+
return error instanceof RemoteMemoryError && error.status === 400;
|
|
6230
|
+
}
|
|
6231
|
+
function record2(value) {
|
|
5943
6232
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5944
6233
|
}
|
|
5945
6234
|
function memoryRecord(value) {
|
|
5946
|
-
if (!
|
|
6235
|
+
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))) {
|
|
5947
6236
|
throw new Error("Invalid nearby private-memory response");
|
|
5948
6237
|
}
|
|
5949
6238
|
return value;
|
|
@@ -6023,14 +6312,14 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
|
|
|
6023
6312
|
const body = await response.json().catch(() => null);
|
|
6024
6313
|
const retryAfter = parseRetryAfterMs(response.headers.get("Retry-After"));
|
|
6025
6314
|
const error = new RemoteMemoryError(
|
|
6026
|
-
|
|
6315
|
+
record2(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
|
|
6027
6316
|
response.status,
|
|
6028
|
-
|
|
6317
|
+
record2(body) && typeof body.code === "string" ? body.code : void 0,
|
|
6029
6318
|
retryAfter ?? void 0,
|
|
6030
|
-
|
|
6319
|
+
record2(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
|
|
6031
6320
|
);
|
|
6032
6321
|
if (response.status === 429 && retryAfter !== null && retryAfter > 0 && (!error.code || error.code === "rate_limited")) {
|
|
6033
|
-
const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket :
|
|
6322
|
+
const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record2(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
|
|
6034
6323
|
cooldowns.set(bucket, { until: Date.now() + retryAfter, error });
|
|
6035
6324
|
}
|
|
6036
6325
|
throw error;
|
|
@@ -6053,7 +6342,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6053
6342
|
throw new Error("A canonical keyId is required");
|
|
6054
6343
|
const request = createNearbyRequest(options);
|
|
6055
6344
|
const account = await request("/account", {}, options.signal);
|
|
6056
|
-
if (!
|
|
6345
|
+
if (!record2(account) || account.state !== "active") {
|
|
6057
6346
|
throw new RemoteMemoryError(
|
|
6058
6347
|
"Complete and verify migration before using remote memories",
|
|
6059
6348
|
409,
|
|
@@ -6067,6 +6356,25 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6067
6356
|
"key_mismatch"
|
|
6068
6357
|
);
|
|
6069
6358
|
}
|
|
6359
|
+
const codec = createTopicCodec(options);
|
|
6360
|
+
let legacyTopicRows = typeof account.legacy_topic_memories === "number" && account.legacy_topic_memories > 0;
|
|
6361
|
+
if (typeof account.legacy_topic_catalog === "number" && account.legacy_topic_catalog > 0)
|
|
6362
|
+
void upgradeLegacyTopicCatalog(request, codec, options.signal).catch((error) => {
|
|
6363
|
+
if (!options.signal?.aborted)
|
|
6364
|
+
getLogger().warn("[memory/remote] Topic catalog upgrade failed:", error);
|
|
6365
|
+
});
|
|
6366
|
+
let legacyCheckedAt = Date.now();
|
|
6367
|
+
let legacyCheck;
|
|
6368
|
+
const recheckLegacyTopicRows = () => {
|
|
6369
|
+
if (legacyCheck || Date.now() - legacyCheckedAt < LEGACY_TOPIC_RECHECK_MS) return;
|
|
6370
|
+
legacyCheckedAt = Date.now();
|
|
6371
|
+
legacyCheck = request("/account", {}, options.signal).then((current) => {
|
|
6372
|
+
if (record2(current) && current.legacy_topic_memories === 0) legacyTopicRows = false;
|
|
6373
|
+
}).catch(() => {
|
|
6374
|
+
}).finally(() => {
|
|
6375
|
+
legacyCheck = void 0;
|
|
6376
|
+
});
|
|
6377
|
+
};
|
|
6070
6378
|
const snapshots = /* @__PURE__ */ new WeakMap();
|
|
6071
6379
|
const decode = async (value) => {
|
|
6072
6380
|
const item = memoryRecord(value);
|
|
@@ -6084,6 +6392,9 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6084
6392
|
content: item.memory.is_deleted && item.memory.content === "" ? "" : await decrypt(item.memory.content),
|
|
6085
6393
|
...item.memory.kind_value !== void 0 && {
|
|
6086
6394
|
kind_value: await decrypt(item.memory.kind_value)
|
|
6395
|
+
},
|
|
6396
|
+
...item.memory.topics !== void 0 && {
|
|
6397
|
+
topics: await codec.decodeTopics(item.memory.topics)
|
|
6087
6398
|
}
|
|
6088
6399
|
}
|
|
6089
6400
|
};
|
|
@@ -6095,8 +6406,10 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6095
6406
|
version: item.version,
|
|
6096
6407
|
content: decoded.memory.content,
|
|
6097
6408
|
kindValue: decoded.memory.kind_value,
|
|
6409
|
+
topics: decoded.memory.topics,
|
|
6098
6410
|
encryptedContent: item.memory.content,
|
|
6099
|
-
encryptedKindValue: item.memory.kind_value
|
|
6411
|
+
encryptedKindValue: item.memory.kind_value,
|
|
6412
|
+
encryptedTopics: item.memory.topics
|
|
6100
6413
|
});
|
|
6101
6414
|
return decoded;
|
|
6102
6415
|
};
|
|
@@ -6118,7 +6431,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6118
6431
|
};
|
|
6119
6432
|
const decodeCommitted = async (value, write) => {
|
|
6120
6433
|
const item = memoryRecord(value);
|
|
6121
|
-
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)
|
|
6434
|
+
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)
|
|
6122
6435
|
return decode(item);
|
|
6123
6436
|
return remember(
|
|
6124
6437
|
{
|
|
@@ -6126,7 +6439,8 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6126
6439
|
memory: {
|
|
6127
6440
|
...item.memory,
|
|
6128
6441
|
content: write.content,
|
|
6129
|
-
...write.kindValue !== void 0 && { kind_value: write.kindValue }
|
|
6442
|
+
...write.kindValue !== void 0 && { kind_value: write.kindValue },
|
|
6443
|
+
...write.topics !== void 0 && { topics: write.topics }
|
|
6130
6444
|
}
|
|
6131
6445
|
},
|
|
6132
6446
|
item
|
|
@@ -6178,13 +6492,21 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6178
6492
|
const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
|
|
6179
6493
|
const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
|
|
6180
6494
|
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);
|
|
6495
|
+
const wireTopics2 = snapshot ? snapshot.encryptedTopics : existing?.memory.topics;
|
|
6496
|
+
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);
|
|
6181
6497
|
return {
|
|
6182
6498
|
body: {
|
|
6183
6499
|
expected_version: expectedVersion,
|
|
6184
|
-
memory: {
|
|
6500
|
+
memory: {
|
|
6501
|
+
...memory,
|
|
6502
|
+
content,
|
|
6503
|
+
...kindValue !== void 0 && { kind_value: kindValue },
|
|
6504
|
+
...topics !== void 0 && { topics }
|
|
6505
|
+
}
|
|
6185
6506
|
},
|
|
6186
6507
|
content: memory.content,
|
|
6187
|
-
kindValue: memory.kind_value
|
|
6508
|
+
kindValue: memory.kind_value,
|
|
6509
|
+
topics: memory.topics
|
|
6188
6510
|
};
|
|
6189
6511
|
};
|
|
6190
6512
|
const fetchCandidates = async (embedding2, candidateOptions, withCounts) => {
|
|
@@ -6233,32 +6555,72 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6233
6555
|
},
|
|
6234
6556
|
candidateOptions.signal
|
|
6235
6557
|
);
|
|
6236
|
-
if (!
|
|
6558
|
+
if (!record2(result) || !Array.isArray(result.items))
|
|
6237
6559
|
throw new Error("Invalid nearby candidate response");
|
|
6238
6560
|
return result;
|
|
6239
6561
|
};
|
|
6240
6562
|
const fetchQueryPage = async (queryOptions) => {
|
|
6241
|
-
const { signal, ...
|
|
6242
|
-
if (
|
|
6563
|
+
const { signal, topics: names, ...wire2 } = queryOptions;
|
|
6564
|
+
if (wire2.limit !== void 0 && (!Number.isInteger(wire2.limit) || wire2.limit < 1 || wire2.limit > 200))
|
|
6243
6565
|
throw new Error("Page limit must be 1\u2013200");
|
|
6244
6566
|
for (const [key3, max] of queryListLimits) {
|
|
6245
|
-
const values =
|
|
6567
|
+
const values = queryOptions[key3];
|
|
6246
6568
|
if (values && values.length > max)
|
|
6247
6569
|
throw new Error(`Query ${key3} accepts at most ${max} entries (got ${values.length})`);
|
|
6248
6570
|
}
|
|
6571
|
+
const body = wire2;
|
|
6572
|
+
if (names === void 0) return postQuery(body, signal);
|
|
6573
|
+
const hashes = [
|
|
6574
|
+
...new Set(
|
|
6575
|
+
(await Promise.all(names.map((name) => codec.hash(name)))).filter((h) => h !== null)
|
|
6576
|
+
)
|
|
6577
|
+
];
|
|
6578
|
+
if (names.length > 0 && hashes.length === 0) return { items: [] };
|
|
6579
|
+
if (hashes.length > 0 && wire2.cursor?.startsWith(LEGACY_TOPIC_CURSOR)) {
|
|
6580
|
+
const page2 = await postQuery(
|
|
6581
|
+
{
|
|
6582
|
+
...wire2,
|
|
6583
|
+
cursor: wire2.cursor.slice(LEGACY_TOPIC_CURSOR.length) || void 0,
|
|
6584
|
+
topics_legacy: true
|
|
6585
|
+
},
|
|
6586
|
+
signal
|
|
6587
|
+
);
|
|
6588
|
+
const wanted = new Set(names.map(normalizeTopicName));
|
|
6589
|
+
const hashed2 = new Set(hashes);
|
|
6590
|
+
const matches = await Promise.all(
|
|
6591
|
+
page2.items.map(
|
|
6592
|
+
(item) => codec.matchesLegacy(
|
|
6593
|
+
record2(item) && record2(item.memory) ? item.memory.topics : void 0,
|
|
6594
|
+
wanted,
|
|
6595
|
+
hashed2
|
|
6596
|
+
)
|
|
6597
|
+
)
|
|
6598
|
+
);
|
|
6599
|
+
return {
|
|
6600
|
+
...page2,
|
|
6601
|
+
items: page2.items.filter((_, i) => matches[i]),
|
|
6602
|
+
next_cursor: page2.next_cursor === void 0 ? void 0 : LEGACY_TOPIC_CURSOR + page2.next_cursor
|
|
6603
|
+
};
|
|
6604
|
+
}
|
|
6605
|
+
const page = await postQuery({ ...body, topic_hashes: hashes }, signal);
|
|
6606
|
+
if (hashes.length === 0 || page.next_cursor !== void 0 || !legacyTopicRows) return page;
|
|
6607
|
+
recheckLegacyTopicRows();
|
|
6608
|
+
return { ...page, next_cursor: LEGACY_TOPIC_CURSOR };
|
|
6609
|
+
};
|
|
6610
|
+
const postQuery = async (body, signal) => {
|
|
6249
6611
|
const page = await request(
|
|
6250
6612
|
"/memories/query",
|
|
6251
6613
|
{
|
|
6252
6614
|
method: "POST",
|
|
6253
6615
|
body: JSON.stringify(
|
|
6254
6616
|
Object.fromEntries(
|
|
6255
|
-
queryFields.filter((key3) =>
|
|
6617
|
+
queryFields.filter((key3) => body[key3] !== void 0).map((key3) => [key3, body[key3]])
|
|
6256
6618
|
)
|
|
6257
6619
|
)
|
|
6258
6620
|
},
|
|
6259
6621
|
signal
|
|
6260
6622
|
);
|
|
6261
|
-
if (!
|
|
6623
|
+
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")
|
|
6262
6624
|
throw new Error("Invalid nearby private-memory page");
|
|
6263
6625
|
return page;
|
|
6264
6626
|
};
|
|
@@ -6272,13 +6634,13 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6272
6634
|
unavailable_count: result.unavailable_count
|
|
6273
6635
|
};
|
|
6274
6636
|
};
|
|
6275
|
-
|
|
6276
|
-
...createRemoteTopicPersistence(request),
|
|
6637
|
+
const persistence = {
|
|
6638
|
+
...createRemoteTopicPersistence(request, codec),
|
|
6277
6639
|
...createRemoteWorkPersistence(request),
|
|
6278
6640
|
supportsRealtimeChanges: account.realtime_changes === true,
|
|
6279
6641
|
counts: async () => {
|
|
6280
6642
|
const result = await request("/counts", {});
|
|
6281
|
-
if (!
|
|
6643
|
+
if (!record2(result) || ["live", "archived", "quarantined"].some(
|
|
6282
6644
|
(key3) => !Number.isSafeInteger(result[key3]) || result[key3] < 0
|
|
6283
6645
|
))
|
|
6284
6646
|
throw new Error("Invalid nearby memory counts");
|
|
@@ -6295,8 +6657,8 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6295
6657
|
method: "POST",
|
|
6296
6658
|
body: JSON.stringify({ ...window2, limit })
|
|
6297
6659
|
});
|
|
6298
|
-
if (!
|
|
6299
|
-
(item) => !
|
|
6660
|
+
if (!record2(result) || !Array.isArray(result.items) || result.items.some(
|
|
6661
|
+
(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
|
|
6300
6662
|
))
|
|
6301
6663
|
throw new Error("Invalid nearby temporal candidates");
|
|
6302
6664
|
return result.items.map((item) => item.memory_id);
|
|
@@ -6327,7 +6689,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6327
6689
|
if (query[key3] !== void 0) params.set(key3, String(query[key3]));
|
|
6328
6690
|
}
|
|
6329
6691
|
const page = await request("/memories?" + params.toString(), {}, signal);
|
|
6330
|
-
if (!
|
|
6692
|
+
if (!record2(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
|
|
6331
6693
|
throw new Error("Invalid nearby private-memory page");
|
|
6332
6694
|
}
|
|
6333
6695
|
return {
|
|
@@ -6367,7 +6729,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6367
6729
|
},
|
|
6368
6730
|
signal
|
|
6369
6731
|
);
|
|
6370
|
-
if (!
|
|
6732
|
+
if (!record2(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
|
|
6371
6733
|
throw new Error("Invalid nearby batch response");
|
|
6372
6734
|
return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
|
|
6373
6735
|
},
|
|
@@ -6382,20 +6744,87 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6382
6744
|
queryMetadata: async (queryOptions = {}) => {
|
|
6383
6745
|
const page = await fetchQueryPage(queryOptions);
|
|
6384
6746
|
return {
|
|
6385
|
-
items:
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6747
|
+
items: await Promise.all(
|
|
6748
|
+
page.items.map(async (item) => {
|
|
6749
|
+
const {
|
|
6750
|
+
memory: { content: _content, kind_value: _kindValue, topics, ...memory },
|
|
6751
|
+
version,
|
|
6752
|
+
server_updated_at
|
|
6753
|
+
} = memoryRecord(item);
|
|
6754
|
+
const plain2 = topics === void 0 ? void 0 : await codec.decodeTopics(topics).catch(() => null);
|
|
6755
|
+
return {
|
|
6756
|
+
memory: { ...memory, ...typeof plain2 === "string" && { topics: plain2 } },
|
|
6757
|
+
version,
|
|
6758
|
+
server_updated_at
|
|
6759
|
+
};
|
|
6760
|
+
})
|
|
6761
|
+
),
|
|
6393
6762
|
...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
|
|
6394
6763
|
};
|
|
6395
6764
|
},
|
|
6396
6765
|
candidateSet,
|
|
6397
6766
|
candidates: async (embedding2, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding2, candidateOptions, false)).items)
|
|
6398
6767
|
};
|
|
6768
|
+
let rejectedRows = 0;
|
|
6769
|
+
const rewriteLegacyTopics = async (records, token) => {
|
|
6770
|
+
const write = (batch) => persistence.putMany(
|
|
6771
|
+
batch.map((item) => ({ memory: item.memory, expectedVersion: item })),
|
|
6772
|
+
options.signal,
|
|
6773
|
+
token
|
|
6774
|
+
);
|
|
6775
|
+
try {
|
|
6776
|
+
await write(records);
|
|
6777
|
+
return true;
|
|
6778
|
+
} catch (error) {
|
|
6779
|
+
if (!isVersionConflict(error) && !isRejectedRow(error)) throw error;
|
|
6780
|
+
if (records.length === 1) {
|
|
6781
|
+
if (isRejectedRow(error)) rejectedRows++;
|
|
6782
|
+
return false;
|
|
6783
|
+
}
|
|
6784
|
+
let complete = true;
|
|
6785
|
+
for (const item of records)
|
|
6786
|
+
await write([item]).catch((rowError) => {
|
|
6787
|
+
if (isRejectedRow(rowError)) rejectedRows++;
|
|
6788
|
+
else if (!isVersionConflict(rowError)) throw rowError;
|
|
6789
|
+
complete = false;
|
|
6790
|
+
});
|
|
6791
|
+
return complete;
|
|
6792
|
+
}
|
|
6793
|
+
};
|
|
6794
|
+
const upgradeLegacyTopics = () => withRemoteWorkLease(persistence, "topics", TOPIC_UPGRADE_PROCESSOR, async (token, lease) => {
|
|
6795
|
+
let cursor;
|
|
6796
|
+
let complete = true;
|
|
6797
|
+
do {
|
|
6798
|
+
options.signal?.throwIfAborted();
|
|
6799
|
+
if (lease.aborted) return false;
|
|
6800
|
+
const page = await fetchQueryPage({
|
|
6801
|
+
topics_legacy: true,
|
|
6802
|
+
include_archived: true,
|
|
6803
|
+
include_quarantined: true,
|
|
6804
|
+
include_superseded: true,
|
|
6805
|
+
limit: TOPIC_UPGRADE_PAGE,
|
|
6806
|
+
...cursor !== void 0 && { cursor },
|
|
6807
|
+
signal: options.signal
|
|
6808
|
+
});
|
|
6809
|
+
const { items } = await decodeAll(page.items);
|
|
6810
|
+
const legacy = items.filter((item) => codec.isLegacy(snapshots.get(item)?.encryptedTopics));
|
|
6811
|
+
if (legacy.length && !await rewriteLegacyTopics(legacy, token)) complete = false;
|
|
6812
|
+
cursor = page.next_cursor;
|
|
6813
|
+
} while (cursor);
|
|
6814
|
+
if (rejectedRows)
|
|
6815
|
+
getLogger().warn(
|
|
6816
|
+
`[memory/remote] Nearby rejected ${rejectedRows} rows during the topic upgrade; they keep legacy topics`
|
|
6817
|
+
);
|
|
6818
|
+
return complete;
|
|
6819
|
+
});
|
|
6820
|
+
if (legacyTopicRows)
|
|
6821
|
+
void upgradeLegacyTopics().then((complete) => {
|
|
6822
|
+
if (complete) legacyTopicRows = false;
|
|
6823
|
+
}).catch((error) => {
|
|
6824
|
+
if (!options.signal?.aborted)
|
|
6825
|
+
getLogger().warn("[memory/remote] Topic upgrade failed:", error);
|
|
6826
|
+
});
|
|
6827
|
+
return persistence;
|
|
6399
6828
|
}
|
|
6400
6829
|
|
|
6401
6830
|
// src/lib/chat/inbox.ts
|
|
@@ -6946,9 +7375,9 @@ function toResponsesFormat(tool) {
|
|
|
6946
7375
|
function getCachedServerTools() {
|
|
6947
7376
|
if (typeof localStorage === "undefined") return null;
|
|
6948
7377
|
try {
|
|
6949
|
-
const
|
|
6950
|
-
if (!
|
|
6951
|
-
const parsed = JSON.parse(
|
|
7378
|
+
const cached2 = localStorage.getItem(SERVER_TOOLS_CACHE_KEY);
|
|
7379
|
+
if (!cached2) return null;
|
|
7380
|
+
const parsed = JSON.parse(cached2);
|
|
6952
7381
|
if (parsed.version !== CACHE_VERSION) {
|
|
6953
7382
|
removeLocalStorageCache();
|
|
6954
7383
|
return null;
|
|
@@ -6992,8 +7421,8 @@ function clearServerToolsCache(cache = localStorageToolsCache) {
|
|
|
6992
7421
|
return cache.clear?.();
|
|
6993
7422
|
}
|
|
6994
7423
|
function getToolsChecksum2(cache = localStorageToolsCache) {
|
|
6995
|
-
const
|
|
6996
|
-
return
|
|
7424
|
+
const cached2 = cache.get();
|
|
7425
|
+
return cached2 instanceof Promise ? cached2.then((c) => c?.checksum) : cached2?.checksum;
|
|
6997
7426
|
}
|
|
6998
7427
|
function shouldRefreshTools(responseChecksum, cache = localStorageToolsCache) {
|
|
6999
7428
|
if (!responseChecksum) {
|
|
@@ -7056,33 +7485,33 @@ async function getServerTools(options) {
|
|
|
7056
7485
|
} catch (error) {
|
|
7057
7486
|
getLogger().warn("[serverTools] Cache read failed; falling through to server fetch:", error);
|
|
7058
7487
|
}
|
|
7059
|
-
const
|
|
7060
|
-
const cacheValid = !isCacheExpired(
|
|
7061
|
-
if (
|
|
7062
|
-
return
|
|
7488
|
+
const cached2 = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
|
|
7489
|
+
const cacheValid = !isCacheExpired(cached2, cacheExpirationMs);
|
|
7490
|
+
if (cached2 && cacheValid && !forceRefresh) {
|
|
7491
|
+
return cached2.tools;
|
|
7063
7492
|
}
|
|
7064
7493
|
try {
|
|
7065
7494
|
const { BASE_URL: BASE_URL2 } = await import("./clientConfig-VPOGQRNP.mjs");
|
|
7066
7495
|
const effectiveBaseUrl = baseUrl ?? BASE_URL2;
|
|
7067
|
-
const validator =
|
|
7496
|
+
const validator = cached2 && !forceRefresh ? cached2.etag : void 0;
|
|
7068
7497
|
let authHeaders;
|
|
7069
7498
|
if (apiKey) {
|
|
7070
7499
|
authHeaders = { "X-API-Key": apiKey };
|
|
7071
7500
|
} else {
|
|
7072
7501
|
if (!getToken) {
|
|
7073
7502
|
getLogger().warn("[serverTools] No auth method available for fetching tools");
|
|
7074
|
-
return
|
|
7503
|
+
return cached2?.tools ?? [];
|
|
7075
7504
|
}
|
|
7076
7505
|
const token = await getToken();
|
|
7077
7506
|
if (!token) {
|
|
7078
7507
|
getLogger().warn("[serverTools] No auth token available for fetching tools");
|
|
7079
|
-
return
|
|
7508
|
+
return cached2?.tools ?? [];
|
|
7080
7509
|
}
|
|
7081
7510
|
authHeaders = { Authorization: `Bearer ${token}` };
|
|
7082
7511
|
}
|
|
7083
7512
|
const result = await fetchServerToolsFromApi(effectiveBaseUrl, authHeaders, validator);
|
|
7084
7513
|
if (result.notModified) {
|
|
7085
|
-
const confirmed =
|
|
7514
|
+
const confirmed = cached2;
|
|
7086
7515
|
await persistCache({ ...confirmed, timestamp: Date.now() });
|
|
7087
7516
|
return confirmed.tools;
|
|
7088
7517
|
}
|
|
@@ -7090,9 +7519,9 @@ async function getServerTools(options) {
|
|
|
7090
7519
|
return result.tools;
|
|
7091
7520
|
} catch (error) {
|
|
7092
7521
|
getLogger().error("[serverTools] Failed to fetch server tools:", error);
|
|
7093
|
-
if (
|
|
7522
|
+
if (cached2?.tools) {
|
|
7094
7523
|
getLogger().warn("[serverTools] Using stale cached tools due to fetch error");
|
|
7095
|
-
return
|
|
7524
|
+
return cached2.tools;
|
|
7096
7525
|
}
|
|
7097
7526
|
return [];
|
|
7098
7527
|
}
|
|
@@ -8226,13 +8655,13 @@ function extractParamGroups(content) {
|
|
|
8226
8655
|
}
|
|
8227
8656
|
function mergeXaiInlineParameterTags(content, toolCalls) {
|
|
8228
8657
|
if (!content || !content.includes(PARAM_MARKER)) return content;
|
|
8229
|
-
const
|
|
8230
|
-
if (
|
|
8658
|
+
const entries2 = Array.from(toolCalls.values());
|
|
8659
|
+
if (entries2.length === 0) return content;
|
|
8231
8660
|
const groups = extractParamGroups(content);
|
|
8232
8661
|
if (groups.length === 0) return content;
|
|
8233
|
-
const pairCount = Math.min(groups.length,
|
|
8662
|
+
const pairCount = Math.min(groups.length, entries2.length);
|
|
8234
8663
|
for (let i = 0; i < pairCount; i++) {
|
|
8235
|
-
const target =
|
|
8664
|
+
const target = entries2[i];
|
|
8236
8665
|
const params = groups[i];
|
|
8237
8666
|
if (!target || !params) continue;
|
|
8238
8667
|
let args = {};
|
|
@@ -11554,21 +11983,21 @@ function contextFields(context) {
|
|
|
11554
11983
|
);
|
|
11555
11984
|
}
|
|
11556
11985
|
function conversationContext(data) {
|
|
11557
|
-
const
|
|
11558
|
-
return
|
|
11986
|
+
const entries2 = Object.entries(data).filter(([field10]) => field10.startsWith(CONTEXT_FIELD_PREFIX)).map(([field10, value]) => [field10.slice(CONTEXT_FIELD_PREFIX.length), value]);
|
|
11987
|
+
return entries2.length > 0 ? plain(Object.fromEntries(entries2)) : void 0;
|
|
11559
11988
|
}
|
|
11560
|
-
function toConversation(
|
|
11561
|
-
const pinnedAt = number(
|
|
11562
|
-
const projectId = text3(
|
|
11563
|
-
const context = conversationContext(
|
|
11989
|
+
function toConversation(record3) {
|
|
11990
|
+
const pinnedAt = number(record3.data.pinnedAt);
|
|
11991
|
+
const projectId = text3(record3.data.projectId);
|
|
11992
|
+
const context = conversationContext(record3.data);
|
|
11564
11993
|
return {
|
|
11565
|
-
uniqueId:
|
|
11566
|
-
conversationId:
|
|
11567
|
-
title: text3(
|
|
11994
|
+
uniqueId: record3.id,
|
|
11995
|
+
conversationId: record3.id,
|
|
11996
|
+
title: text3(record3.data.title) ?? "",
|
|
11568
11997
|
...projectId ? { projectId } : {},
|
|
11569
|
-
createdAt: new Date(
|
|
11570
|
-
updatedAt: new Date(
|
|
11571
|
-
isDeleted:
|
|
11998
|
+
createdAt: new Date(record3.createdAt),
|
|
11999
|
+
updatedAt: new Date(record3.updatedAt),
|
|
12000
|
+
isDeleted: record3.isDeleted,
|
|
11572
12001
|
pinnedAt: pinnedAt ? new Date(pinnedAt) : null,
|
|
11573
12002
|
...context ? { context } : {}
|
|
11574
12003
|
};
|
|
@@ -11590,21 +12019,21 @@ function messageData(options) {
|
|
|
11590
12019
|
...anuma ? { anuma } : {}
|
|
11591
12020
|
});
|
|
11592
12021
|
}
|
|
11593
|
-
function toMessage(
|
|
11594
|
-
const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } =
|
|
12022
|
+
function toMessage(record3) {
|
|
12023
|
+
const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } = record3.data;
|
|
11595
12024
|
const anuma = readAnumaTurn(rawAnuma);
|
|
11596
12025
|
return {
|
|
11597
12026
|
...anuma ? { anuma } : {},
|
|
11598
12027
|
...fields,
|
|
11599
|
-
uniqueId:
|
|
11600
|
-
messageId:
|
|
11601
|
-
conversationId:
|
|
11602
|
-
createdAt: new Date(
|
|
11603
|
-
updatedAt: new Date(
|
|
12028
|
+
uniqueId: record3.id,
|
|
12029
|
+
messageId: record3.sortKey,
|
|
12030
|
+
conversationId: record3.conversationId,
|
|
12031
|
+
createdAt: new Date(record3.createdAt),
|
|
12032
|
+
updatedAt: new Date(record3.updatedAt)
|
|
11604
12033
|
};
|
|
11605
12034
|
}
|
|
11606
|
-
function chunkOffsets(
|
|
11607
|
-
const offsets =
|
|
12035
|
+
function chunkOffsets(record3) {
|
|
12036
|
+
const offsets = record3.data.chunkOffsets;
|
|
11608
12037
|
return Array.isArray(offsets) ? offsets : void 0;
|
|
11609
12038
|
}
|
|
11610
12039
|
function toSkeletons(records) {
|
|
@@ -11625,15 +12054,15 @@ function toSkeletons(records) {
|
|
|
11625
12054
|
};
|
|
11626
12055
|
});
|
|
11627
12056
|
}
|
|
11628
|
-
function toSummary(
|
|
12057
|
+
function toSummary(record3) {
|
|
11629
12058
|
return {
|
|
11630
|
-
uniqueId:
|
|
11631
|
-
conversationId:
|
|
11632
|
-
summary: text3(
|
|
11633
|
-
summarizedUpTo: text3(
|
|
11634
|
-
tokenCount: number(
|
|
11635
|
-
createdAt: new Date(
|
|
11636
|
-
updatedAt: new Date(
|
|
12059
|
+
uniqueId: record3.id,
|
|
12060
|
+
conversationId: record3.id,
|
|
12061
|
+
summary: text3(record3.data.summary) ?? "",
|
|
12062
|
+
summarizedUpTo: text3(record3.data.summarizedUpTo) ?? "",
|
|
12063
|
+
tokenCount: number(record3.data.tokenCount) ?? 0,
|
|
12064
|
+
createdAt: new Date(record3.createdAt),
|
|
12065
|
+
updatedAt: new Date(record3.updatedAt)
|
|
11637
12066
|
};
|
|
11638
12067
|
}
|
|
11639
12068
|
function links(data) {
|
|
@@ -11659,10 +12088,10 @@ function applyLinkOps(data, ops) {
|
|
|
11659
12088
|
}
|
|
11660
12089
|
return plain({ links: current });
|
|
11661
12090
|
}
|
|
11662
|
-
function toLinks(
|
|
11663
|
-
return links(
|
|
11664
|
-
uniqueId: `${
|
|
11665
|
-
conversationId:
|
|
12091
|
+
function toLinks(record3) {
|
|
12092
|
+
return links(record3.data).map((l) => ({
|
|
12093
|
+
uniqueId: `${record3.id}:${l.memoryId}`,
|
|
12094
|
+
conversationId: record3.id,
|
|
11666
12095
|
memoryId: l.memoryId,
|
|
11667
12096
|
score: l.score,
|
|
11668
12097
|
createdAt: new Date(l.createdAt)
|
|
@@ -11671,24 +12100,24 @@ function toLinks(record2) {
|
|
|
11671
12100
|
function bytes(value) {
|
|
11672
12101
|
return new TextEncoder().encode(JSON.stringify(value)).length;
|
|
11673
12102
|
}
|
|
11674
|
-
function fitRecord(
|
|
11675
|
-
if (
|
|
11676
|
-
const data = { ...
|
|
12103
|
+
function fitRecord(record3) {
|
|
12104
|
+
if (record3.kind !== "message" || bytes(record3) <= recordBudgetBytes) return record3;
|
|
12105
|
+
const data = { ...record3.data };
|
|
11677
12106
|
const truncated = [];
|
|
11678
12107
|
for (const field10 of droppable) {
|
|
11679
|
-
if (bytes({ ...
|
|
12108
|
+
if (bytes({ ...record3, data }) <= recordBudgetBytes) break;
|
|
11680
12109
|
if (data[field10] === void 0) continue;
|
|
11681
12110
|
delete data[field10];
|
|
11682
12111
|
truncated.push(field10);
|
|
11683
12112
|
}
|
|
11684
12113
|
const content = text3(data.content) ?? "";
|
|
11685
|
-
const over = bytes({ ...
|
|
12114
|
+
const over = bytes({ ...record3, data }) - recordBudgetBytes;
|
|
11686
12115
|
if (over > 0) {
|
|
11687
12116
|
const encoded = new TextEncoder().encode(content);
|
|
11688
12117
|
data.content = new TextDecoder().decode(encoded.slice(0, Math.max(0, encoded.length - over - 64))).replace(/�$/, "");
|
|
11689
12118
|
truncated.push("content");
|
|
11690
12119
|
}
|
|
11691
|
-
return { ...
|
|
12120
|
+
return { ...record3, data: { ...data, truncated } };
|
|
11692
12121
|
}
|
|
11693
12122
|
function acceptedVector(vector2) {
|
|
11694
12123
|
if (!vector2 || !acceptedDims.has(vector2.length)) return void 0;
|
|
@@ -11732,8 +12161,8 @@ function anumaTurnContent(bubbles) {
|
|
|
11732
12161
|
return bubbles.join("\n\n");
|
|
11733
12162
|
}
|
|
11734
12163
|
function anumaLastReadSortKey(conversation) {
|
|
11735
|
-
const
|
|
11736
|
-
const state =
|
|
12164
|
+
const record3 = conversation && "record" in conversation ? conversation.record : conversation;
|
|
12165
|
+
const state = record3?.data.anuma;
|
|
11737
12166
|
if (!isObject(state)) return 0;
|
|
11738
12167
|
const sortKey = state.lastReadSortKey;
|
|
11739
12168
|
return Number.isSafeInteger(sortKey) && sortKey > 0 ? sortKey : 0;
|
|
@@ -11786,19 +12215,19 @@ async function markAnumaRead(store, sortKey, options = {}) {
|
|
|
11786
12215
|
const current = await ensureAnumaConversation(store, options);
|
|
11787
12216
|
const read = anumaLastReadSortKey(current);
|
|
11788
12217
|
if (sortKey <= read) return current;
|
|
11789
|
-
const
|
|
11790
|
-
const state = isObject(
|
|
11791
|
-
const data = plain({ ...
|
|
12218
|
+
const record3 = current.record;
|
|
12219
|
+
const state = isObject(record3.data.anuma) ? record3.data.anuma : {};
|
|
12220
|
+
const data = plain({ ...record3.data, anuma: { ...state, lastReadSortKey: sortKey } });
|
|
11792
12221
|
try {
|
|
11793
12222
|
const [written] = await store.putMany(
|
|
11794
12223
|
[
|
|
11795
12224
|
{
|
|
11796
12225
|
expectedVersion: current.version,
|
|
11797
12226
|
record: {
|
|
11798
|
-
...
|
|
12227
|
+
...record3,
|
|
11799
12228
|
data,
|
|
11800
|
-
sortKey: conversationSortKey(data,
|
|
11801
|
-
updatedAt: Math.max(
|
|
12229
|
+
sortKey: conversationSortKey(data, record3.createdAt),
|
|
12230
|
+
updatedAt: Math.max(record3.updatedAt, now())
|
|
11802
12231
|
}
|
|
11803
12232
|
}
|
|
11804
12233
|
],
|
|
@@ -11833,22 +12262,22 @@ function createSummaryContext(database, encryption = {}) {
|
|
|
11833
12262
|
summariesCollection: database.get("conversation_summaries")
|
|
11834
12263
|
};
|
|
11835
12264
|
}
|
|
11836
|
-
function modelToStored(
|
|
12265
|
+
function modelToStored(record3, summary) {
|
|
11837
12266
|
return {
|
|
11838
|
-
uniqueId:
|
|
11839
|
-
conversationId:
|
|
12267
|
+
uniqueId: record3.id,
|
|
12268
|
+
conversationId: record3.conversationId,
|
|
11840
12269
|
summary,
|
|
11841
|
-
summarizedUpTo:
|
|
11842
|
-
tokenCount:
|
|
11843
|
-
createdAt:
|
|
11844
|
-
updatedAt:
|
|
12270
|
+
summarizedUpTo: record3.summarizedUpTo,
|
|
12271
|
+
tokenCount: record3.tokenCount,
|
|
12272
|
+
createdAt: record3.createdAt,
|
|
12273
|
+
updatedAt: record3.updatedAt
|
|
11845
12274
|
};
|
|
11846
12275
|
}
|
|
11847
12276
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
11848
12277
|
const results = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
|
|
11849
12278
|
if (results.length === 0) return null;
|
|
11850
|
-
const
|
|
11851
|
-
const stored2 = modelToStored(
|
|
12279
|
+
const record3 = results[0];
|
|
12280
|
+
const stored2 = modelToStored(record3, record3.summary);
|
|
11852
12281
|
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
11853
12282
|
if (ctx.signMessage) {
|
|
11854
12283
|
try {
|
|
@@ -11867,7 +12296,7 @@ async function getConversationSummaryOp(ctx, conversationId) {
|
|
|
11867
12296
|
ctx.embeddedWalletSigner
|
|
11868
12297
|
);
|
|
11869
12298
|
await ctx.database.write(async () => {
|
|
11870
|
-
const current = await ctx.summariesCollection.query(Q4.where("id",
|
|
12299
|
+
const current = await ctx.summariesCollection.query(Q4.where("id", record3.id)).fetch();
|
|
11871
12300
|
if (current[0]?.summary === stored2.summary) {
|
|
11872
12301
|
await current[0].update((rec) => {
|
|
11873
12302
|
rec.summary = encryptedSummary;
|
|
@@ -11882,19 +12311,19 @@ async function getConversationSummaryOp(ctx, conversationId) {
|
|
|
11882
12311
|
}
|
|
11883
12312
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
11884
12313
|
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
11885
|
-
let
|
|
12314
|
+
let record3;
|
|
11886
12315
|
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
11887
12316
|
await ctx.database.write(async () => {
|
|
11888
12317
|
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
11889
12318
|
const existing = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
|
|
11890
12319
|
if (existing.length > 0) {
|
|
11891
|
-
|
|
12320
|
+
record3 = await existing[0].update((rec) => {
|
|
11892
12321
|
rec.summary = encryptedSummary;
|
|
11893
12322
|
rec.summarizedUpTo = summarizedUpTo;
|
|
11894
12323
|
rec.tokenCount = tokenCount;
|
|
11895
12324
|
});
|
|
11896
12325
|
} else {
|
|
11897
|
-
|
|
12326
|
+
record3 = await ctx.summariesCollection.create((rec) => {
|
|
11898
12327
|
rec.conversationId = conversationId;
|
|
11899
12328
|
rec.summary = encryptedSummary;
|
|
11900
12329
|
rec.summarizedUpTo = summarizedUpTo;
|
|
@@ -11902,13 +12331,13 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
|
|
|
11902
12331
|
});
|
|
11903
12332
|
}
|
|
11904
12333
|
});
|
|
11905
|
-
return modelToStored(
|
|
12334
|
+
return modelToStored(record3, summary);
|
|
11906
12335
|
}
|
|
11907
12336
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
11908
12337
|
await ctx.database.write(async () => {
|
|
11909
12338
|
const existing = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
|
|
11910
|
-
for (const
|
|
11911
|
-
await
|
|
12339
|
+
for (const record3 of existing) {
|
|
12340
|
+
await record3.destroyPermanently();
|
|
11912
12341
|
}
|
|
11913
12342
|
});
|
|
11914
12343
|
}
|
|
@@ -11984,7 +12413,7 @@ function messageRecord(message) {
|
|
|
11984
12413
|
const fitted = chunks3?.length ? fitChunks(chunks3) : void 0;
|
|
11985
12414
|
const single = fitted ? void 0 : acceptedVector(vector2);
|
|
11986
12415
|
const embeddings2 = fitted?.map((c) => c.vector) ?? (single ? [single] : void 0);
|
|
11987
|
-
const
|
|
12416
|
+
const record3 = fitRecord({
|
|
11988
12417
|
kind: "message",
|
|
11989
12418
|
id: message.uniqueId,
|
|
11990
12419
|
conversationId: message.conversationId,
|
|
@@ -11998,7 +12427,7 @@ function messageRecord(message) {
|
|
|
11998
12427
|
}
|
|
11999
12428
|
});
|
|
12000
12429
|
return {
|
|
12001
|
-
record:
|
|
12430
|
+
record: record3,
|
|
12002
12431
|
...embeddings2 ? { embeddings: embeddings2 } : {},
|
|
12003
12432
|
...embeddings2 && message.embeddingModel ? { embeddingModel: message.embeddingModel } : {}
|
|
12004
12433
|
};
|
|
@@ -12146,15 +12575,15 @@ function ref(value) {
|
|
|
12146
12575
|
function sameMetadata(a, b) {
|
|
12147
12576
|
return metadata.every((key3) => a[key3] === b[key3]);
|
|
12148
12577
|
}
|
|
12149
|
-
function wire(
|
|
12578
|
+
function wire(record3, payload) {
|
|
12150
12579
|
return {
|
|
12151
|
-
kind:
|
|
12152
|
-
id:
|
|
12153
|
-
conversation_id:
|
|
12154
|
-
sort_key:
|
|
12155
|
-
created_at:
|
|
12156
|
-
updated_at:
|
|
12157
|
-
is_deleted:
|
|
12580
|
+
kind: record3.kind,
|
|
12581
|
+
id: record3.id,
|
|
12582
|
+
conversation_id: record3.conversationId,
|
|
12583
|
+
sort_key: record3.sortKey,
|
|
12584
|
+
created_at: record3.createdAt,
|
|
12585
|
+
updated_at: record3.updatedAt,
|
|
12586
|
+
is_deleted: record3.isDeleted,
|
|
12158
12587
|
payload
|
|
12159
12588
|
};
|
|
12160
12589
|
}
|
|
@@ -12211,10 +12640,10 @@ async function createRemoteChatStore(options) {
|
|
|
12211
12640
|
serverUpdatedAt: value.server_updated_at
|
|
12212
12641
|
};
|
|
12213
12642
|
};
|
|
12214
|
-
const seal = async (
|
|
12215
|
-
if (
|
|
12643
|
+
const seal = async (record3, signal) => {
|
|
12644
|
+
if (record3.isDeleted) return "";
|
|
12216
12645
|
const payload = await encrypt(
|
|
12217
|
-
JSON.stringify({ schema: 1, account_id: accountId, key_id: keyId, record:
|
|
12646
|
+
JSON.stringify({ schema: 1, account_id: accountId, key_id: keyId, record: record3 })
|
|
12218
12647
|
);
|
|
12219
12648
|
signal?.throwIfAborted();
|
|
12220
12649
|
if (!cipherPattern.test(payload) || payload.length > maxPayload) invalid();
|
|
@@ -12578,8 +13007,8 @@ var emptyMessage = {
|
|
|
12578
13007
|
var maxPasses = 5;
|
|
12579
13008
|
var verifyBatch = 1e3;
|
|
12580
13009
|
var writeBatch = 25;
|
|
12581
|
-
function key(
|
|
12582
|
-
return `${
|
|
13010
|
+
function key(record3) {
|
|
13011
|
+
return `${record3.kind}/${record3.id}`;
|
|
12583
13012
|
}
|
|
12584
13013
|
function sealed(value) {
|
|
12585
13014
|
if (typeof value === "string") return isEncrypted(value);
|
|
@@ -12708,11 +13137,11 @@ async function missing(store, records, signal) {
|
|
|
12708
13137
|
const out = /* @__PURE__ */ new Set();
|
|
12709
13138
|
for (let i = 0; i < records.length; i += verifyBatch) {
|
|
12710
13139
|
const refs = await store.verify(
|
|
12711
|
-
records.slice(i, i + verifyBatch).map(({ record:
|
|
12712
|
-
kind:
|
|
12713
|
-
id:
|
|
12714
|
-
updatedAt:
|
|
12715
|
-
isDeleted:
|
|
13140
|
+
records.slice(i, i + verifyBatch).map(({ record: record3 }) => ({
|
|
13141
|
+
kind: record3.kind,
|
|
13142
|
+
id: record3.id,
|
|
13143
|
+
updatedAt: record3.updatedAt,
|
|
13144
|
+
isDeleted: record3.isDeleted
|
|
12716
13145
|
})),
|
|
12717
13146
|
signal
|
|
12718
13147
|
);
|
|
@@ -12752,14 +13181,14 @@ async function deletedSinceUpload(store, journal, local, signal) {
|
|
|
12752
13181
|
const live2 = (await store.getMany(gone.map(ref2), signal)).filter((s) => !s.record.isDeleted);
|
|
12753
13182
|
const tombstoning = new Set(live2.map((s) => key(s.record)));
|
|
12754
13183
|
await journal.drop(gone.filter((k) => !tombstoning.has(k)));
|
|
12755
|
-
return live2.map(({ record:
|
|
12756
|
-
const empty = emptied[
|
|
13184
|
+
return live2.map(({ record: record3, version }) => {
|
|
13185
|
+
const empty = emptied[record3.kind];
|
|
12757
13186
|
return {
|
|
12758
13187
|
record: {
|
|
12759
|
-
...
|
|
13188
|
+
...record3,
|
|
12760
13189
|
isDeleted: !empty,
|
|
12761
13190
|
data: empty ?? {},
|
|
12762
|
-
updatedAt: Math.max(Date.now(),
|
|
13191
|
+
updatedAt: Math.max(Date.now(), record3.updatedAt + 1)
|
|
12763
13192
|
},
|
|
12764
13193
|
expectedVersion: version
|
|
12765
13194
|
};
|
|
@@ -13108,8 +13537,8 @@ function createVaultAttachments(options) {
|
|
|
13108
13537
|
},
|
|
13109
13538
|
async read(attachmentId, signal) {
|
|
13110
13539
|
if (!attachmentIdPattern2.test(attachmentId)) invalidAttachment();
|
|
13111
|
-
const
|
|
13112
|
-
if (
|
|
13540
|
+
const cached2 = await cache?.get(attachmentId).catch(() => null);
|
|
13541
|
+
if (cached2) return cached2;
|
|
13113
13542
|
for (let attempt = 0; ; attempt++) {
|
|
13114
13543
|
const found = await withRetry(() => store.attachments.get(attachmentId, signal), signal);
|
|
13115
13544
|
if (!found?.download) return null;
|
|
@@ -13138,8 +13567,8 @@ function validRef(value) {
|
|
|
13138
13567
|
const ref3 = value;
|
|
13139
13568
|
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;
|
|
13140
13569
|
}
|
|
13141
|
-
function vaultAttachmentRefs(
|
|
13142
|
-
const refs =
|
|
13570
|
+
function vaultAttachmentRefs(record3) {
|
|
13571
|
+
const refs = record3.data.vaultAttachments;
|
|
13143
13572
|
return Array.isArray(refs) ? refs.filter(validRef) : [];
|
|
13144
13573
|
}
|
|
13145
13574
|
function journalKey(messageId, fileId) {
|
|
@@ -13347,14 +13776,14 @@ function sameRecord(a, b) {
|
|
|
13347
13776
|
return a.sortKey === b.sortKey && a.isDeleted === b.isDeleted && sameJson(a.data, b.data);
|
|
13348
13777
|
}
|
|
13349
13778
|
function toWrite(base, patch) {
|
|
13350
|
-
const
|
|
13351
|
-
if (!
|
|
13352
|
-
if (base && patch.embeddings === void 0 && sameRecord(base.record,
|
|
13779
|
+
const record3 = applyPatch(base?.record, patch);
|
|
13780
|
+
if (!record3) return void 0;
|
|
13781
|
+
if (base && patch.embeddings === void 0 && sameRecord(base.record, record3)) return null;
|
|
13353
13782
|
return {
|
|
13354
|
-
record: fitRecord(
|
|
13783
|
+
record: fitRecord(record3),
|
|
13355
13784
|
expectedVersion: base?.version ?? 0,
|
|
13356
|
-
...patch.embeddings !== void 0 && !
|
|
13357
|
-
...patch.embeddingModel !== void 0 && !
|
|
13785
|
+
...patch.embeddings !== void 0 && !record3.isDeleted ? { embeddings: patch.embeddings } : {},
|
|
13786
|
+
...patch.embeddingModel !== void 0 && !record3.isDeleted ? { embeddingModel: patch.embeddingModel } : {}
|
|
13358
13787
|
};
|
|
13359
13788
|
}
|
|
13360
13789
|
var maxWrites = 25;
|
|
@@ -13488,11 +13917,11 @@ function createVaultChatBackend(options) {
|
|
|
13488
13917
|
for (const listener of [...listeners]) listener(event);
|
|
13489
13918
|
};
|
|
13490
13919
|
const view = (k) => {
|
|
13491
|
-
let
|
|
13920
|
+
let record3 = confirmed.get(k)?.record;
|
|
13492
13921
|
for (const patch of [inflight.get(k), pending.get(k)]) {
|
|
13493
|
-
if (patch)
|
|
13922
|
+
if (patch) record3 = applyPatch(record3, patch) ?? record3;
|
|
13494
13923
|
}
|
|
13495
|
-
return
|
|
13924
|
+
return record3;
|
|
13496
13925
|
};
|
|
13497
13926
|
const conversationLive = (conversationId) => {
|
|
13498
13927
|
const conversation2 = view(key2("conversation", conversationId));
|
|
@@ -13503,10 +13932,10 @@ function createVaultChatBackend(options) {
|
|
|
13503
13932
|
const out = [];
|
|
13504
13933
|
for (const k of keys) {
|
|
13505
13934
|
if (!k.startsWith(`${kind}/`)) continue;
|
|
13506
|
-
const
|
|
13507
|
-
if (!
|
|
13508
|
-
if (conversationId !== void 0 &&
|
|
13509
|
-
out.push(
|
|
13935
|
+
const record3 = view(k);
|
|
13936
|
+
if (!record3 || record3.isDeleted && !includeDeleted) continue;
|
|
13937
|
+
if (conversationId !== void 0 && record3.conversationId !== conversationId) continue;
|
|
13938
|
+
out.push(record3);
|
|
13510
13939
|
}
|
|
13511
13940
|
return out;
|
|
13512
13941
|
};
|
|
@@ -13517,7 +13946,7 @@ function createVaultChatBackend(options) {
|
|
|
13517
13946
|
account: cache.account,
|
|
13518
13947
|
cursor: cursor ?? "",
|
|
13519
13948
|
records: [...confirmed.values()].filter(
|
|
13520
|
-
({ record:
|
|
13949
|
+
({ record: record3 }) => record3.kind === "conversation" || record3.kind !== "project" && keep.has(record3.conversationId)
|
|
13521
13950
|
),
|
|
13522
13951
|
threads: kept,
|
|
13523
13952
|
absent: [...checked].filter((k) => {
|
|
@@ -13831,17 +14260,17 @@ function createVaultChatBackend(options) {
|
|
|
13831
14260
|
return loading;
|
|
13832
14261
|
};
|
|
13833
14262
|
const applyRemote = (snapshot) => {
|
|
13834
|
-
const { record:
|
|
13835
|
-
const k = key2(
|
|
13836
|
-
if (
|
|
14263
|
+
const { record: record3 } = snapshot;
|
|
14264
|
+
const k = key2(record3.kind, record3.id);
|
|
14265
|
+
if (record3.kind === "conversation") {
|
|
13837
14266
|
if (!merge(snapshot)) return;
|
|
13838
|
-
if (
|
|
13839
|
-
announce([
|
|
14267
|
+
if (record3.isDeleted) forgetConversation(record3.id);
|
|
14268
|
+
announce([record3]);
|
|
13840
14269
|
return;
|
|
13841
14270
|
}
|
|
13842
|
-
if (
|
|
13843
|
-
const relevant2 = threads.has(
|
|
13844
|
-
if (relevant2 && merge(snapshot)) announce([
|
|
14271
|
+
if (record3.kind === "project") return;
|
|
14272
|
+
const relevant2 = threads.has(record3.conversationId) || confirmed.has(k) || checked.has(k) && record3.kind !== "message";
|
|
14273
|
+
if (relevant2 && merge(snapshot)) announce([record3]);
|
|
13845
14274
|
};
|
|
13846
14275
|
const listIndex = async (source) => {
|
|
13847
14276
|
const index = [];
|
|
@@ -13992,8 +14421,8 @@ function createVaultChatBackend(options) {
|
|
|
13992
14421
|
checked.add(k);
|
|
13993
14422
|
if (found) merge(found);
|
|
13994
14423
|
}
|
|
13995
|
-
const
|
|
13996
|
-
return
|
|
14424
|
+
const record3 = view(k);
|
|
14425
|
+
return record3 && !record3.isDeleted && conversationLive(record3.conversationId) ? record3 : void 0;
|
|
13997
14426
|
};
|
|
13998
14427
|
const child = async (kind, conversationId) => {
|
|
13999
14428
|
await available2();
|
|
@@ -14030,19 +14459,19 @@ function createVaultChatBackend(options) {
|
|
|
14030
14459
|
await backend.deleteSummary(conversationId);
|
|
14031
14460
|
};
|
|
14032
14461
|
const storedMessage = async (uniqueId) => {
|
|
14033
|
-
const
|
|
14034
|
-
return
|
|
14462
|
+
const record3 = await message(uniqueId);
|
|
14463
|
+
return record3 ? toMessage(record3) : null;
|
|
14035
14464
|
};
|
|
14036
14465
|
const patchMessage = async (uniqueId, patch) => {
|
|
14037
|
-
const
|
|
14038
|
-
if (!
|
|
14466
|
+
const record3 = await message(uniqueId);
|
|
14467
|
+
if (!record3) return null;
|
|
14039
14468
|
await enqueue({
|
|
14040
14469
|
kind: "message",
|
|
14041
14470
|
id: uniqueId,
|
|
14042
|
-
conversationId:
|
|
14471
|
+
conversationId: record3.conversationId,
|
|
14043
14472
|
...patch
|
|
14044
14473
|
});
|
|
14045
|
-
emit({ type: "messages", conversationId:
|
|
14474
|
+
emit({ type: "messages", conversationId: record3.conversationId, origin: "local" });
|
|
14046
14475
|
const updated = view(key2("message", uniqueId));
|
|
14047
14476
|
return updated && !updated.isDeleted ? toMessage(updated) : null;
|
|
14048
14477
|
};
|
|
@@ -14067,12 +14496,12 @@ function createVaultChatBackend(options) {
|
|
|
14067
14496
|
});
|
|
14068
14497
|
const backend = {
|
|
14069
14498
|
async getConversation(conversationId) {
|
|
14070
|
-
const
|
|
14071
|
-
return
|
|
14499
|
+
const record3 = await conversation(conversationId);
|
|
14500
|
+
return record3 && !record3.isDeleted ? toConversation(record3) : null;
|
|
14072
14501
|
},
|
|
14073
14502
|
async getConversations(query) {
|
|
14074
14503
|
await available2();
|
|
14075
|
-
return all("conversation").filter((
|
|
14504
|
+
return all("conversation").filter((record3) => record3.id !== ANUMA_CONVERSATION_ID).map(toConversation).filter(
|
|
14076
14505
|
(c) => query?.projectId === void 0 || (query.projectId === null ? !c.projectId : c.projectId === query.projectId)
|
|
14077
14506
|
).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
14078
14507
|
},
|
|
@@ -14111,13 +14540,13 @@ function createVaultChatBackend(options) {
|
|
|
14111
14540
|
async updateConversationContext(conversationId, context) {
|
|
14112
14541
|
const set = contextFields(context);
|
|
14113
14542
|
if (Object.keys(set).length > 0) return updateConversation(conversationId, set);
|
|
14114
|
-
const
|
|
14115
|
-
return !!
|
|
14543
|
+
const record3 = await conversation(conversationId);
|
|
14544
|
+
return !!record3 && !record3.isDeleted;
|
|
14116
14545
|
},
|
|
14117
14546
|
async deleteConversation(conversationId) {
|
|
14118
14547
|
if (conversationId === ANUMA_CONVERSATION_ID) return false;
|
|
14119
|
-
const
|
|
14120
|
-
if (!
|
|
14548
|
+
const record3 = await conversation(conversationId);
|
|
14549
|
+
if (!record3 || record3.isDeleted) return false;
|
|
14121
14550
|
for (const [k, patch] of pending)
|
|
14122
14551
|
if (patch.conversationId === conversationId) pending.delete(k);
|
|
14123
14552
|
await enqueue({ kind: "conversation", id: conversationId, conversationId: "", delete: true });
|
|
@@ -14153,8 +14582,8 @@ function createVaultChatBackend(options) {
|
|
|
14153
14582
|
const unknown = ids.map((id2) => key2("message", id2)).filter((k) => !view(k) && !checked.has(k));
|
|
14154
14583
|
await refresh(unknown);
|
|
14155
14584
|
return ids.flatMap((id2) => {
|
|
14156
|
-
const
|
|
14157
|
-
return
|
|
14585
|
+
const record3 = view(key2("message", id2));
|
|
14586
|
+
return record3 && !record3.isDeleted && conversationLive(record3.conversationId) ? [toMessage(record3)] : [];
|
|
14158
14587
|
});
|
|
14159
14588
|
},
|
|
14160
14589
|
async getMessageCount(conversationId) {
|
|
@@ -14162,8 +14591,8 @@ function createVaultChatBackend(options) {
|
|
|
14162
14591
|
},
|
|
14163
14592
|
async getToolCallEventIds(conversationId) {
|
|
14164
14593
|
const ids = /* @__PURE__ */ new Set();
|
|
14165
|
-
for (const
|
|
14166
|
-
const events =
|
|
14594
|
+
for (const record3 of await thread(conversationId)) {
|
|
14595
|
+
const events = record3.data.toolCallEvents;
|
|
14167
14596
|
if (!Array.isArray(events)) continue;
|
|
14168
14597
|
for (const event of events)
|
|
14169
14598
|
if (event && typeof event === "object" && !Array.isArray(event) && typeof event.id === "string")
|
|
@@ -14256,21 +14685,21 @@ function createVaultChatBackend(options) {
|
|
|
14256
14685
|
},
|
|
14257
14686
|
async clearMessages(conversationId) {
|
|
14258
14687
|
await invalidateSummary(conversationId);
|
|
14259
|
-
for (const
|
|
14260
|
-
await enqueue({ kind: "message", id:
|
|
14688
|
+
for (const record3 of await thread(conversationId))
|
|
14689
|
+
await enqueue({ kind: "message", id: record3.id, conversationId, delete: true });
|
|
14261
14690
|
emit({ type: "messages", conversationId, origin: "local" });
|
|
14262
14691
|
},
|
|
14263
14692
|
async deleteMessage(uniqueId) {
|
|
14264
|
-
const
|
|
14265
|
-
if (!
|
|
14266
|
-
await invalidateSummary(
|
|
14693
|
+
const record3 = await message(uniqueId);
|
|
14694
|
+
if (!record3) return null;
|
|
14695
|
+
await invalidateSummary(record3.conversationId, record3);
|
|
14267
14696
|
await enqueue({
|
|
14268
14697
|
kind: "message",
|
|
14269
14698
|
id: uniqueId,
|
|
14270
|
-
conversationId:
|
|
14699
|
+
conversationId: record3.conversationId,
|
|
14271
14700
|
delete: true
|
|
14272
14701
|
});
|
|
14273
|
-
emit({ type: "messages", conversationId:
|
|
14702
|
+
emit({ type: "messages", conversationId: record3.conversationId, origin: "local" });
|
|
14274
14703
|
return uniqueId;
|
|
14275
14704
|
},
|
|
14276
14705
|
observeMessages(conversationId) {
|
|
@@ -14283,13 +14712,13 @@ function createVaultChatBackend(options) {
|
|
|
14283
14712
|
await available2();
|
|
14284
14713
|
if (query?.conversationId) await loadThread(query.conversationId);
|
|
14285
14714
|
const files = [];
|
|
14286
|
-
for (const
|
|
14287
|
-
if (!conversationLive(
|
|
14288
|
-
const stored2 = toMessage(
|
|
14715
|
+
for (const record3 of all("message", query?.conversationId)) {
|
|
14716
|
+
if (!conversationLive(record3.conversationId)) continue;
|
|
14717
|
+
const stored2 = toMessage(record3);
|
|
14289
14718
|
for (const file of stored2.files ?? [])
|
|
14290
14719
|
files.push({
|
|
14291
14720
|
...file,
|
|
14292
|
-
conversationId:
|
|
14721
|
+
conversationId: record3.conversationId,
|
|
14293
14722
|
createdAt: stored2.createdAt,
|
|
14294
14723
|
messageRole: stored2.role
|
|
14295
14724
|
});
|
|
@@ -14328,8 +14757,8 @@ function createVaultChatBackend(options) {
|
|
|
14328
14757
|
return results;
|
|
14329
14758
|
},
|
|
14330
14759
|
async getSummary(conversationId) {
|
|
14331
|
-
const
|
|
14332
|
-
return
|
|
14760
|
+
const record3 = await child("summary", conversationId);
|
|
14761
|
+
return record3 && !record3.isDeleted && record3.data.summarizedUpTo ? toSummary(record3) : null;
|
|
14333
14762
|
},
|
|
14334
14763
|
async upsertSummary(conversationId, summary, summarizedUpTo, tokenCount) {
|
|
14335
14764
|
await child("summary", conversationId);
|
|
@@ -14345,8 +14774,8 @@ function createVaultChatBackend(options) {
|
|
|
14345
14774
|
return toSummary(view(key2("summary", conversationId)));
|
|
14346
14775
|
},
|
|
14347
14776
|
async deleteSummary(conversationId) {
|
|
14348
|
-
const
|
|
14349
|
-
if (!
|
|
14777
|
+
const record3 = await child("summary", conversationId);
|
|
14778
|
+
if (!record3 || record3.isDeleted) return;
|
|
14350
14779
|
await enqueue({
|
|
14351
14780
|
kind: "summary",
|
|
14352
14781
|
id: conversationId,
|
|
@@ -14356,8 +14785,8 @@ function createVaultChatBackend(options) {
|
|
|
14356
14785
|
emit({ type: "summary", conversationId, origin: "local" });
|
|
14357
14786
|
},
|
|
14358
14787
|
async getMemoryLinks(conversationId) {
|
|
14359
|
-
const
|
|
14360
|
-
return
|
|
14788
|
+
const record3 = await child("memory_links", conversationId);
|
|
14789
|
+
return record3 && !record3.isDeleted ? toLinks(record3) : [];
|
|
14361
14790
|
},
|
|
14362
14791
|
async addMemoryLinks(conversationId, items) {
|
|
14363
14792
|
if (!conversationId || items.length === 0) return;
|
|
@@ -14372,8 +14801,8 @@ function createVaultChatBackend(options) {
|
|
|
14372
14801
|
emit({ type: "links", conversationId, origin: "local" });
|
|
14373
14802
|
},
|
|
14374
14803
|
async clearMemoryLinks(conversationId) {
|
|
14375
|
-
const
|
|
14376
|
-
if (!
|
|
14804
|
+
const record3 = await child("memory_links", conversationId);
|
|
14805
|
+
if (!record3 || record3.isDeleted) return;
|
|
14377
14806
|
await enqueue({
|
|
14378
14807
|
kind: "memory_links",
|
|
14379
14808
|
id: conversationId,
|
|
@@ -14391,8 +14820,8 @@ function createVaultChatBackend(options) {
|
|
|
14391
14820
|
async importChats(chats) {
|
|
14392
14821
|
await ready();
|
|
14393
14822
|
const seen = /* @__PURE__ */ new Set();
|
|
14394
|
-
const unique = (items) => items.filter(({ record:
|
|
14395
|
-
const k = key2(
|
|
14823
|
+
const unique = (items) => items.filter(({ record: record3 }) => {
|
|
14824
|
+
const k = key2(record3.kind, record3.id);
|
|
14396
14825
|
if (seen.has(k)) return false;
|
|
14397
14826
|
seen.add(k);
|
|
14398
14827
|
return true;
|
|
@@ -14416,15 +14845,15 @@ function createVaultChatBackend(options) {
|
|
|
14416
14845
|
for (const batch of batches(messages))
|
|
14417
14846
|
messageCount += await connected.importRecords(batch);
|
|
14418
14847
|
} finally {
|
|
14419
|
-
for (const { record:
|
|
14420
|
-
await refresh(conversations.map(({ record:
|
|
14848
|
+
for (const { record: record3 } of messages) checked.delete(key2("message", record3.id));
|
|
14849
|
+
await refresh(conversations.map(({ record: record3 }) => key2("conversation", record3.id))).catch(
|
|
14421
14850
|
() => void 0
|
|
14422
14851
|
);
|
|
14423
|
-
for (const { record:
|
|
14852
|
+
for (const { record: record3 } of conversations) threads.delete(record3.id);
|
|
14424
14853
|
channel?.postMessage("changed");
|
|
14425
14854
|
emit({ type: "conversations", origin: "local" });
|
|
14426
|
-
for (const { record:
|
|
14427
|
-
emit({ type: "messages", conversationId:
|
|
14855
|
+
for (const { record: record3 } of conversations)
|
|
14856
|
+
emit({ type: "messages", conversationId: record3.id, origin: "local" });
|
|
14428
14857
|
}
|
|
14429
14858
|
return { conversations: conversationCount, messages: messageCount };
|
|
14430
14859
|
},
|
|
@@ -14443,8 +14872,8 @@ function createVaultChatBackend(options) {
|
|
|
14443
14872
|
}
|
|
14444
14873
|
};
|
|
14445
14874
|
const updateConversation = async (conversationId, set) => {
|
|
14446
|
-
const
|
|
14447
|
-
if (!
|
|
14875
|
+
const record3 = await conversation(conversationId);
|
|
14876
|
+
if (!record3 || record3.isDeleted) return false;
|
|
14448
14877
|
await enqueue({ kind: "conversation", id: conversationId, conversationId: "", set });
|
|
14449
14878
|
emit({ type: "conversations", origin: "local" });
|
|
14450
14879
|
return true;
|
|
@@ -14620,10 +15049,10 @@ async function decryptConversationTitle(encryptedTitle, address) {
|
|
|
14620
15049
|
);
|
|
14621
15050
|
}
|
|
14622
15051
|
const cacheKey = buildCacheKey(address, encryptedTitle);
|
|
14623
|
-
const
|
|
14624
|
-
if (
|
|
14625
|
-
touchEntry(cacheKey,
|
|
14626
|
-
return
|
|
15052
|
+
const cached2 = titleCache.get(cacheKey);
|
|
15053
|
+
if (cached2 !== void 0) {
|
|
15054
|
+
touchEntry(cacheKey, cached2);
|
|
15055
|
+
return cached2;
|
|
14627
15056
|
}
|
|
14628
15057
|
const inFlight = pendingDecrypts.get(cacheKey);
|
|
14629
15058
|
if (inFlight) return inFlight;
|
|
@@ -14882,25 +15311,25 @@ async function upsertEntitiesInWrite(ctx, entities) {
|
|
|
14882
15311
|
const kindBackfills = existing.filter((e) => {
|
|
14883
15312
|
const incoming = kindByName.get(e.canonicalName);
|
|
14884
15313
|
return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
|
|
14885
|
-
}).map((
|
|
15314
|
+
}).map((record3) => ({ record: record3, kind: kindByName.get(record3.canonicalName) }));
|
|
14886
15315
|
const missing2 = unique.filter((n) => !existingNames.has(n));
|
|
14887
15316
|
const created = missing2.map(
|
|
14888
|
-
(name) => ctx.entityCollection.prepareCreate((
|
|
14889
|
-
|
|
15317
|
+
(name) => ctx.entityCollection.prepareCreate((record3) => {
|
|
15318
|
+
record3._setRaw("canonical_name", name);
|
|
14890
15319
|
const kind = kindByName.get(name);
|
|
14891
|
-
if (kind !== void 0)
|
|
15320
|
+
if (kind !== void 0) record3._setRaw("kind", kind);
|
|
14892
15321
|
})
|
|
14893
15322
|
);
|
|
14894
15323
|
for (const e of existing) out.set(e.canonicalName, entityToStored(e));
|
|
14895
|
-
for (const
|
|
14896
|
-
for (const { record:
|
|
14897
|
-
out.set(
|
|
15324
|
+
for (const record3 of created) out.set(record3.canonicalName, entityToStored(record3));
|
|
15325
|
+
for (const { record: record3, kind } of kindBackfills) {
|
|
15326
|
+
out.set(record3.canonicalName, { ...entityToStored(record3), kind });
|
|
14898
15327
|
}
|
|
14899
15328
|
return { entities: out, operations: created, kindBackfills };
|
|
14900
15329
|
}
|
|
14901
15330
|
function prepareKindBackfills(backfills) {
|
|
14902
15331
|
return backfills.map(
|
|
14903
|
-
({ record:
|
|
15332
|
+
({ record: record3, kind }) => record3.prepareUpdate((r) => {
|
|
14904
15333
|
r._setRaw("kind", kind);
|
|
14905
15334
|
})
|
|
14906
15335
|
);
|
|
@@ -15028,10 +15457,10 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
15028
15457
|
return;
|
|
15029
15458
|
}
|
|
15030
15459
|
const linkOps = toCreate.map(
|
|
15031
|
-
(e) => ctx.memoryEntityCollection.prepareCreate((
|
|
15032
|
-
|
|
15033
|
-
|
|
15034
|
-
if (userId !== void 0)
|
|
15460
|
+
(e) => ctx.memoryEntityCollection.prepareCreate((record3) => {
|
|
15461
|
+
record3._setRaw("memory_id", memoryId);
|
|
15462
|
+
record3._setRaw("entity_id", e.uniqueId);
|
|
15463
|
+
if (userId !== void 0) record3._setRaw("user_id", userId);
|
|
15035
15464
|
})
|
|
15036
15465
|
);
|
|
15037
15466
|
await ctx.database.batch(
|
|
@@ -15101,10 +15530,10 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
15101
15530
|
...entityOps,
|
|
15102
15531
|
...prepareKindBackfills(kindBackfills),
|
|
15103
15532
|
...toCreate.map(
|
|
15104
|
-
(e) => ctx.memoryEntityCollection.prepareCreate((
|
|
15105
|
-
|
|
15106
|
-
|
|
15107
|
-
if (userId !== void 0)
|
|
15533
|
+
(e) => ctx.memoryEntityCollection.prepareCreate((record3) => {
|
|
15534
|
+
record3._setRaw("memory_id", memoryId);
|
|
15535
|
+
record3._setRaw("entity_id", e.uniqueId);
|
|
15536
|
+
if (userId !== void 0) record3._setRaw("user_id", userId);
|
|
15108
15537
|
})
|
|
15109
15538
|
),
|
|
15110
15539
|
...toDestroy.map((l) => l.prepareDestroyPermanently()),
|
|
@@ -16438,9 +16867,9 @@ var DatabaseManager = class {
|
|
|
16438
16867
|
*/
|
|
16439
16868
|
getDatabase(walletAddress) {
|
|
16440
16869
|
const dbName = this.getDbName(walletAddress);
|
|
16441
|
-
const
|
|
16442
|
-
if (
|
|
16443
|
-
return
|
|
16870
|
+
const cached2 = this.databases.get(dbName);
|
|
16871
|
+
if (cached2) {
|
|
16872
|
+
return cached2;
|
|
16444
16873
|
}
|
|
16445
16874
|
const needsMigration = this.handleSchemaMigration(walletAddress);
|
|
16446
16875
|
if (needsMigration) {
|
|
@@ -17575,8 +18004,8 @@ function visibilityConditions(requested) {
|
|
|
17575
18004
|
if (excluded.length === 0) return [];
|
|
17576
18005
|
return [Q9.or(Q9.where("visibility", null), Q9.where("visibility", Q9.notIn(excluded)))];
|
|
17577
18006
|
}
|
|
17578
|
-
function isKinded(
|
|
17579
|
-
return
|
|
18007
|
+
function isKinded(record3) {
|
|
18008
|
+
return record3.kind !== null && record3.kind !== void 0;
|
|
17580
18009
|
}
|
|
17581
18010
|
async function assertCanWrite2(ctx) {
|
|
17582
18011
|
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
@@ -17630,8 +18059,8 @@ function levelConditions(requested) {
|
|
|
17630
18059
|
}
|
|
17631
18060
|
return [byLevel];
|
|
17632
18061
|
}
|
|
17633
|
-
function isOwnedByCtxUser(ctx,
|
|
17634
|
-
return ctx.userId === void 0 ||
|
|
18062
|
+
function isOwnedByCtxUser(ctx, record3) {
|
|
18063
|
+
return ctx.userId === void 0 || record3.userId === ctx.userId;
|
|
17635
18064
|
}
|
|
17636
18065
|
function baseVaultConditions(ctx, options) {
|
|
17637
18066
|
return [
|
|
@@ -17714,43 +18143,43 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
|
|
|
17714
18143
|
}
|
|
17715
18144
|
return raw;
|
|
17716
18145
|
}
|
|
17717
|
-
function populateNewVaultMemory(
|
|
18146
|
+
function populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue) {
|
|
17718
18147
|
const { level, scope } = resolveCreateLevel(opts);
|
|
17719
|
-
|
|
17720
|
-
|
|
17721
|
-
|
|
17722
|
-
|
|
17723
|
-
|
|
17724
|
-
|
|
17725
|
-
|
|
17726
|
-
|
|
18148
|
+
record3._setRaw("content", encryptedContent);
|
|
18149
|
+
record3._setRaw("scope", scope);
|
|
18150
|
+
record3._setRaw("level", level);
|
|
18151
|
+
record3._setRaw("kind", opts.kind ?? null);
|
|
18152
|
+
record3._setRaw("kind_value", encryptedKindValue ?? null);
|
|
18153
|
+
record3._setRaw("folder_id", opts.folderId ?? null);
|
|
18154
|
+
record3._setRaw("user_id", ctx.userId ?? null);
|
|
18155
|
+
record3._setRaw("is_deleted", false);
|
|
17727
18156
|
if (opts.embedding !== void 0) {
|
|
17728
|
-
|
|
17729
|
-
|
|
18157
|
+
record3._setRaw("embedding", opts.embedding);
|
|
18158
|
+
record3._setRaw("embedding_model", opts.embeddingModel ?? null);
|
|
17730
18159
|
}
|
|
17731
18160
|
if (opts.sourceChunkIds !== void 0) {
|
|
17732
|
-
|
|
18161
|
+
record3._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
|
|
17733
18162
|
}
|
|
17734
|
-
|
|
17735
|
-
|
|
18163
|
+
record3._setRaw("proof_count", opts.proofCount ?? 1);
|
|
18164
|
+
record3._setRaw("source", opts.source ?? "manual");
|
|
17736
18165
|
if (opts.eventTime) {
|
|
17737
|
-
|
|
17738
|
-
|
|
17739
|
-
|
|
18166
|
+
record3._setRaw("event_time_start", opts.eventTime.start ?? null);
|
|
18167
|
+
record3._setRaw("event_time_end", opts.eventTime.end ?? null);
|
|
18168
|
+
record3._setRaw("event_time_kind", opts.eventTime.kind ?? null);
|
|
17740
18169
|
}
|
|
17741
18170
|
if (opts.factType !== void 0) {
|
|
17742
|
-
|
|
18171
|
+
record3._setRaw("fact_type", opts.factType);
|
|
17743
18172
|
}
|
|
17744
18173
|
if (opts.trustTier !== void 0) {
|
|
17745
|
-
|
|
18174
|
+
record3._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
|
|
17746
18175
|
}
|
|
17747
|
-
|
|
17748
|
-
|
|
18176
|
+
record3._setRaw("visibility", opts.visibility ?? "private");
|
|
18177
|
+
record3._setRaw(
|
|
17749
18178
|
"published_at",
|
|
17750
18179
|
opts.visibility && opts.visibility !== "private" ? opts.publishedAt ?? Date.now() : null
|
|
17751
18180
|
);
|
|
17752
18181
|
if (opts.geohash !== void 0) {
|
|
17753
|
-
|
|
18182
|
+
record3._setRaw("geohash", opts.geohash);
|
|
17754
18183
|
}
|
|
17755
18184
|
}
|
|
17756
18185
|
async function createVaultMemoryOp(ctx, opts) {
|
|
@@ -17765,7 +18194,7 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
17765
18194
|
const created = await ctx.database.write(async () => {
|
|
17766
18195
|
await assertCanWrite2(ctx);
|
|
17767
18196
|
return ctx.vaultMemoryCollection.create(
|
|
17768
|
-
(
|
|
18197
|
+
(record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue)
|
|
17769
18198
|
);
|
|
17770
18199
|
});
|
|
17771
18200
|
return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
@@ -17792,7 +18221,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
17792
18221
|
if (target.isDeleted || target.supersededBy || isKinded(target) || !isOwnedByCtxUser(ctx, target))
|
|
17793
18222
|
return;
|
|
17794
18223
|
createdRecord = await ctx.vaultMemoryCollection.create(
|
|
17795
|
-
(
|
|
18224
|
+
(record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue)
|
|
17796
18225
|
);
|
|
17797
18226
|
await target.update((r) => {
|
|
17798
18227
|
r._setRaw("superseded_by", createdRecord.id);
|
|
@@ -17877,7 +18306,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
17877
18306
|
await assertCanWrite2(ctx);
|
|
17878
18307
|
const prepared = optionsArray.map(
|
|
17879
18308
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate(
|
|
17880
|
-
(
|
|
18309
|
+
(record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContents[i], encryptedKindValues[i])
|
|
17881
18310
|
)
|
|
17882
18311
|
);
|
|
17883
18312
|
await ctx.database.batch(...prepared);
|
|
@@ -17885,16 +18314,16 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
17885
18314
|
});
|
|
17886
18315
|
return Promise.all(
|
|
17887
18316
|
created.map(
|
|
17888
|
-
(
|
|
18317
|
+
(record3) => vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
17889
18318
|
)
|
|
17890
18319
|
);
|
|
17891
18320
|
}
|
|
17892
18321
|
async function getVaultMemoryOp(ctx, id2) {
|
|
17893
18322
|
try {
|
|
17894
|
-
const
|
|
17895
|
-
if (
|
|
18323
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
18324
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
|
|
17896
18325
|
return vaultMemoryToStored(
|
|
17897
|
-
|
|
18326
|
+
record3,
|
|
17898
18327
|
ctx.walletAddress,
|
|
17899
18328
|
ctx.signMessage,
|
|
17900
18329
|
ctx.embeddedWalletSigner
|
|
@@ -18233,29 +18662,29 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
18233
18662
|
ctx.embeddedWalletSigner
|
|
18234
18663
|
) : opts.content;
|
|
18235
18664
|
let stale = false;
|
|
18236
|
-
const
|
|
18665
|
+
const record3 = probe;
|
|
18237
18666
|
await ctx.database.write(async () => {
|
|
18238
18667
|
await assertCanWrite2(ctx);
|
|
18239
|
-
if (
|
|
18668
|
+
if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3) || opts.freeFormOnly && isKinded(record3) || opts.expectedContent !== void 0 && record3._getRaw("content") !== readStoredContent) {
|
|
18240
18669
|
stale = true;
|
|
18241
18670
|
return;
|
|
18242
18671
|
}
|
|
18243
|
-
const originalUpdatedAt =
|
|
18244
|
-
const nextKind = opts.kind !== void 0 ? opts.kind :
|
|
18245
|
-
const nextLevel = levelAfter(
|
|
18672
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
18673
|
+
const nextKind = opts.kind !== void 0 ? opts.kind : record3.kind;
|
|
18674
|
+
const nextLevel = levelAfter(record3);
|
|
18246
18675
|
assertValidKindLevel(nextKind, nextLevel);
|
|
18247
18676
|
let observedSources = [];
|
|
18248
18677
|
let replayedObservation = false;
|
|
18249
18678
|
if (opts.observationSourceIds?.length) {
|
|
18250
18679
|
try {
|
|
18251
|
-
const parsed = JSON.parse(
|
|
18680
|
+
const parsed = JSON.parse(record3.sourceChunkIds ?? "[]");
|
|
18252
18681
|
if (Array.isArray(parsed))
|
|
18253
18682
|
observedSources = parsed.filter((id3) => typeof id3 === "string");
|
|
18254
18683
|
} catch {
|
|
18255
18684
|
}
|
|
18256
18685
|
replayedObservation = opts.observationSourceIds.every((id3) => observedSources.includes(id3));
|
|
18257
18686
|
}
|
|
18258
|
-
await
|
|
18687
|
+
await record3.update((r) => {
|
|
18259
18688
|
if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
|
|
18260
18689
|
if (opts.level !== void 0) {
|
|
18261
18690
|
r._setRaw("level", nextLevel);
|
|
@@ -18322,7 +18751,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
18322
18751
|
});
|
|
18323
18752
|
if (stale) return null;
|
|
18324
18753
|
return vaultMemoryToStored(
|
|
18325
|
-
|
|
18754
|
+
record3,
|
|
18326
18755
|
ctx.walletAddress,
|
|
18327
18756
|
ctx.signMessage,
|
|
18328
18757
|
ctx.embeddedWalletSigner
|
|
@@ -18337,22 +18766,22 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
18337
18766
|
if (!entityCtx) {
|
|
18338
18767
|
throw new Error("setMemoryEntitiesOp requires ctx.entityCtx (entity collections)");
|
|
18339
18768
|
}
|
|
18340
|
-
let
|
|
18769
|
+
let record3;
|
|
18341
18770
|
try {
|
|
18342
|
-
|
|
18771
|
+
record3 = await ctx.vaultMemoryCollection.find(memoryId);
|
|
18343
18772
|
} catch {
|
|
18344
18773
|
return null;
|
|
18345
18774
|
}
|
|
18346
|
-
if (
|
|
18775
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
|
|
18347
18776
|
let stale = false;
|
|
18348
|
-
const originalUpdatedAt =
|
|
18777
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
18349
18778
|
await ctx.database.write(async (writer) => {
|
|
18350
18779
|
await assertCanWrite2(ctx);
|
|
18351
|
-
if (
|
|
18780
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
|
|
18352
18781
|
stale = true;
|
|
18353
18782
|
return;
|
|
18354
18783
|
}
|
|
18355
|
-
await
|
|
18784
|
+
await record3.update((r) => {
|
|
18356
18785
|
r._setRaw("topics_user_managed", true);
|
|
18357
18786
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
18358
18787
|
});
|
|
@@ -18376,26 +18805,26 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
18376
18805
|
);
|
|
18377
18806
|
});
|
|
18378
18807
|
if (stale) return null;
|
|
18379
|
-
return vaultMemoryToStored(
|
|
18808
|
+
return vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
18380
18809
|
}
|
|
18381
18810
|
async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
18382
|
-
let
|
|
18811
|
+
let record3;
|
|
18383
18812
|
try {
|
|
18384
|
-
|
|
18813
|
+
record3 = await ctx.vaultMemoryCollection.find(memoryId);
|
|
18385
18814
|
} catch {
|
|
18386
18815
|
return false;
|
|
18387
18816
|
}
|
|
18388
|
-
if (
|
|
18389
|
-
const originalUpdatedAt =
|
|
18817
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
18818
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
18390
18819
|
let cleared = false;
|
|
18391
18820
|
await ctx.database.write(async () => {
|
|
18392
18821
|
await assertCanWrite2(ctx);
|
|
18393
|
-
if (options?.unlessTopicsRecorded && parseTopics(
|
|
18822
|
+
if (options?.unlessTopicsRecorded && parseTopics(record3.topics) !== null) return;
|
|
18394
18823
|
cleared = true;
|
|
18395
|
-
await
|
|
18824
|
+
await record3.update((r) => {
|
|
18396
18825
|
r._setRaw("topics_user_managed", false);
|
|
18397
18826
|
r._setRaw("topics_extracted_version", null);
|
|
18398
|
-
if (
|
|
18827
|
+
if (record3.topicsExtractedAt === null) {
|
|
18399
18828
|
r._setRaw("topics_extracted_at", originalUpdatedAt);
|
|
18400
18829
|
}
|
|
18401
18830
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
@@ -18404,23 +18833,23 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
|
18404
18833
|
return cleared;
|
|
18405
18834
|
}
|
|
18406
18835
|
async function setMemoryVisibilityOp(ctx, id2, opts) {
|
|
18407
|
-
let
|
|
18836
|
+
let record3;
|
|
18408
18837
|
try {
|
|
18409
|
-
|
|
18838
|
+
record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
18410
18839
|
} catch {
|
|
18411
18840
|
return null;
|
|
18412
18841
|
}
|
|
18413
|
-
if (
|
|
18842
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
|
|
18414
18843
|
let stale = false;
|
|
18415
18844
|
await ctx.database.write(async () => {
|
|
18416
18845
|
await assertCanWrite2(ctx);
|
|
18417
|
-
if (
|
|
18846
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
|
|
18418
18847
|
stale = true;
|
|
18419
18848
|
return;
|
|
18420
18849
|
}
|
|
18421
|
-
const currentUpdatedAt =
|
|
18422
|
-
const currentPublishedAt =
|
|
18423
|
-
await
|
|
18850
|
+
const currentUpdatedAt = record3.updatedAt.getTime();
|
|
18851
|
+
const currentPublishedAt = record3.publishedAt ?? null;
|
|
18852
|
+
await record3.update((r) => {
|
|
18424
18853
|
r._setRaw("visibility", opts.visibility);
|
|
18425
18854
|
if (opts.visibility === "private") {
|
|
18426
18855
|
r._setRaw("published_at", null);
|
|
@@ -18434,20 +18863,20 @@ async function setMemoryVisibilityOp(ctx, id2, opts) {
|
|
|
18434
18863
|
});
|
|
18435
18864
|
});
|
|
18436
18865
|
if (stale) return null;
|
|
18437
|
-
return vaultMemoryToStored(
|
|
18866
|
+
return vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
18438
18867
|
}
|
|
18439
18868
|
async function deleteVaultMemoryOp(ctx, id2) {
|
|
18440
18869
|
try {
|
|
18441
|
-
const
|
|
18442
|
-
if (
|
|
18870
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
18871
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
18443
18872
|
let stale = false;
|
|
18444
18873
|
await ctx.database.write(async () => {
|
|
18445
18874
|
await assertCanWrite2(ctx);
|
|
18446
|
-
if (
|
|
18875
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
|
|
18447
18876
|
stale = true;
|
|
18448
18877
|
return;
|
|
18449
18878
|
}
|
|
18450
|
-
await
|
|
18879
|
+
await record3.update((r) => {
|
|
18451
18880
|
r._setRaw("is_deleted", true);
|
|
18452
18881
|
});
|
|
18453
18882
|
});
|
|
@@ -18466,9 +18895,9 @@ async function deleteVaultMemoryOp(ctx, id2) {
|
|
|
18466
18895
|
async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
|
|
18467
18896
|
if (id2 === supersededById) return false;
|
|
18468
18897
|
try {
|
|
18469
|
-
const
|
|
18470
|
-
if (
|
|
18471
|
-
if (isKinded(
|
|
18898
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
18899
|
+
if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
18900
|
+
if (isKinded(record3)) return false;
|
|
18472
18901
|
let successor;
|
|
18473
18902
|
try {
|
|
18474
18903
|
successor = await ctx.vaultMemoryCollection.find(supersededById);
|
|
@@ -18481,7 +18910,7 @@ async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
|
|
|
18481
18910
|
let stale = false;
|
|
18482
18911
|
await ctx.database.write(async () => {
|
|
18483
18912
|
await assertCanWrite2(ctx);
|
|
18484
|
-
if (
|
|
18913
|
+
if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3)) {
|
|
18485
18914
|
stale = true;
|
|
18486
18915
|
return;
|
|
18487
18916
|
}
|
|
@@ -18489,7 +18918,7 @@ async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
|
|
|
18489
18918
|
stale = true;
|
|
18490
18919
|
return;
|
|
18491
18920
|
}
|
|
18492
|
-
await
|
|
18921
|
+
await record3.update((r) => {
|
|
18493
18922
|
r._setRaw("superseded_by", supersededById);
|
|
18494
18923
|
r._setRaw("superseded_at", Date.now());
|
|
18495
18924
|
});
|
|
@@ -18508,7 +18937,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
|
|
|
18508
18937
|
const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
|
|
18509
18938
|
return mapInBatches(
|
|
18510
18939
|
results,
|
|
18511
|
-
(
|
|
18940
|
+
(record3) => vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
18512
18941
|
);
|
|
18513
18942
|
}
|
|
18514
18943
|
var TOPICS_EXTRACTION_VERSION = 3;
|
|
@@ -18669,17 +19098,17 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
|
|
|
18669
19098
|
}
|
|
18670
19099
|
}
|
|
18671
19100
|
const eligible = records.filter(
|
|
18672
|
-
(
|
|
19101
|
+
(record3) => !record3.isDeleted && isOwnedByCtxUser(ctx, record3) && !record3.topicsUserManaged
|
|
18673
19102
|
);
|
|
18674
|
-
const prepared = eligible.map((
|
|
18675
|
-
const originalUpdatedAt =
|
|
18676
|
-
return
|
|
19103
|
+
const prepared = eligible.map((record3) => {
|
|
19104
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
19105
|
+
return record3.prepareUpdate((r) => {
|
|
18677
19106
|
r._setRaw("topics_extracted_at", extractedAt);
|
|
18678
19107
|
r._setRaw("topics_extracted_version", version);
|
|
18679
19108
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
18680
19109
|
});
|
|
18681
19110
|
});
|
|
18682
|
-
for (const
|
|
19111
|
+
for (const record3 of eligible) stamped.push(record3.id);
|
|
18683
19112
|
if (prepared.length > 0) await ctx.database.batch(...prepared);
|
|
18684
19113
|
});
|
|
18685
19114
|
}
|
|
@@ -18695,14 +19124,14 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
|
|
|
18695
19124
|
try {
|
|
18696
19125
|
await ctx.database.write(async (writer) => {
|
|
18697
19126
|
await assertCanWrite2(ctx);
|
|
18698
|
-
let
|
|
19127
|
+
let record3;
|
|
18699
19128
|
try {
|
|
18700
|
-
|
|
19129
|
+
record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
18701
19130
|
} catch {
|
|
18702
19131
|
return;
|
|
18703
19132
|
}
|
|
18704
|
-
if (
|
|
18705
|
-
const topics = parseTopics(
|
|
19133
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return;
|
|
19134
|
+
const topics = parseTopics(record3.topics);
|
|
18706
19135
|
if (topics === null) return;
|
|
18707
19136
|
await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id2, topics));
|
|
18708
19137
|
relinked.push(id2);
|
|
@@ -18728,18 +19157,18 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
18728
19157
|
await assertCanWrite2(ctx);
|
|
18729
19158
|
const records = [];
|
|
18730
19159
|
for (const id2 of chunkIds) {
|
|
18731
|
-
let
|
|
19160
|
+
let record3;
|
|
18732
19161
|
try {
|
|
18733
|
-
|
|
19162
|
+
record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
18734
19163
|
} catch {
|
|
18735
19164
|
continue;
|
|
18736
19165
|
}
|
|
18737
|
-
if (
|
|
18738
|
-
if (parseTopics(
|
|
18739
|
-
records.push(
|
|
19166
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) continue;
|
|
19167
|
+
if (parseTopics(record3.topics) !== null) continue;
|
|
19168
|
+
records.push(record3);
|
|
18740
19169
|
}
|
|
18741
19170
|
if (records.length === 0) return;
|
|
18742
|
-
const links2 = await entityCtx.memoryEntityCollection.query(Q9.where("memory_id", Q9.oneOf(records.map((
|
|
19171
|
+
const links2 = await entityCtx.memoryEntityCollection.query(Q9.where("memory_id", Q9.oneOf(records.map((record3) => record3.id)))).unsafeFetchRaw();
|
|
18743
19172
|
const entityIds = Array.from(new Set(links2.map((link) => String(link.entity_id))));
|
|
18744
19173
|
const entitiesById = /* @__PURE__ */ new Map();
|
|
18745
19174
|
for (let j = 0; j < entityIds.length; j += CHUNK) {
|
|
@@ -18759,13 +19188,13 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
18759
19188
|
entities.add(entity);
|
|
18760
19189
|
}
|
|
18761
19190
|
const writes = [];
|
|
18762
|
-
for (const
|
|
18763
|
-
const entities = entitiesByMemory.get(
|
|
19191
|
+
for (const record3 of records) {
|
|
19192
|
+
const entities = entitiesByMemory.get(record3.id);
|
|
18764
19193
|
if (!entities?.size) continue;
|
|
18765
|
-
const source =
|
|
19194
|
+
const source = record3.topicsUserManaged ? "user" : "auto";
|
|
18766
19195
|
const write = await resolveMemoryTopicsWrite(
|
|
18767
19196
|
entityCtx,
|
|
18768
|
-
|
|
19197
|
+
record3.id,
|
|
18769
19198
|
Array.from(entities),
|
|
18770
19199
|
[],
|
|
18771
19200
|
source
|
|
@@ -18787,7 +19216,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
|
18787
19216
|
await ctx.database.write(async () => {
|
|
18788
19217
|
await assertCanWrite2(ctx);
|
|
18789
19218
|
const prepared = records.map(
|
|
18790
|
-
(
|
|
19219
|
+
(record3) => record3.prepareUpdate((r) => {
|
|
18791
19220
|
r._setRaw("is_deleted", true);
|
|
18792
19221
|
})
|
|
18793
19222
|
);
|
|
@@ -18858,22 +19287,22 @@ async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
|
18858
19287
|
Q9.where("id", Q9.oneOf(ids.slice(i, i + CHUNK))),
|
|
18859
19288
|
...ctx.userId !== void 0 ? [Q9.where("user_id", ctx.userId)] : []
|
|
18860
19289
|
).fetch();
|
|
18861
|
-
const eligible = records.filter((
|
|
18862
|
-
if (
|
|
19290
|
+
const eligible = records.filter((record3) => {
|
|
19291
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
18863
19292
|
if (opts.transition === "delete") {
|
|
18864
|
-
return
|
|
19293
|
+
return record3.archivedAt !== null && opts.now - record3.archivedAt > opts.hardDeleteWindowMs;
|
|
18865
19294
|
}
|
|
18866
|
-
const candidate = byId.get(
|
|
18867
|
-
return
|
|
19295
|
+
const candidate = byId.get(record3.id);
|
|
19296
|
+
return record3.archivedAt === null && record3.updatedAt.getTime() === candidate.updatedAt && (record3.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
|
|
18868
19297
|
});
|
|
18869
19298
|
const prepared = eligible.map(
|
|
18870
|
-
(
|
|
19299
|
+
(record3) => record3.prepareUpdate((row) => {
|
|
18871
19300
|
if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
|
|
18872
19301
|
else row._setRaw("is_deleted", true);
|
|
18873
19302
|
})
|
|
18874
19303
|
);
|
|
18875
19304
|
if (prepared.length > 0) await ctx.database.batch(prepared);
|
|
18876
|
-
applied = eligible.map((
|
|
19305
|
+
applied = eligible.map((record3) => record3.id);
|
|
18877
19306
|
});
|
|
18878
19307
|
} catch {
|
|
18879
19308
|
continue;
|
|
@@ -18891,21 +19320,21 @@ async function applyDecayTransitionsOp(ctx, candidates, opts) {
|
|
|
18891
19320
|
}
|
|
18892
19321
|
async function archiveVaultMemoryOp(ctx, id2, opts) {
|
|
18893
19322
|
try {
|
|
18894
|
-
const
|
|
18895
|
-
if (
|
|
19323
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
19324
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
18896
19325
|
let stale = false;
|
|
18897
19326
|
const archivedAtValue = opts?.now ?? Date.now();
|
|
18898
19327
|
await ctx.database.write(async () => {
|
|
18899
19328
|
await assertCanWrite2(ctx);
|
|
18900
|
-
if (
|
|
19329
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3) || record3.archivedAt !== null) {
|
|
18901
19330
|
stale = true;
|
|
18902
19331
|
return;
|
|
18903
19332
|
}
|
|
18904
|
-
if (opts?.expectedUpdatedAt !== void 0 &&
|
|
19333
|
+
if (opts?.expectedUpdatedAt !== void 0 && record3.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record3.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
|
|
18905
19334
|
stale = true;
|
|
18906
19335
|
return;
|
|
18907
19336
|
}
|
|
18908
|
-
await
|
|
19337
|
+
await record3.update((r) => {
|
|
18909
19338
|
r._setRaw("archived_at", archivedAtValue);
|
|
18910
19339
|
});
|
|
18911
19340
|
});
|
|
@@ -18916,16 +19345,16 @@ async function archiveVaultMemoryOp(ctx, id2, opts) {
|
|
|
18916
19345
|
}
|
|
18917
19346
|
async function restoreVaultMemoryOp(ctx, id2) {
|
|
18918
19347
|
try {
|
|
18919
|
-
const
|
|
18920
|
-
if (
|
|
19348
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
19349
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
18921
19350
|
let stale = false;
|
|
18922
19351
|
await ctx.database.write(async () => {
|
|
18923
19352
|
await assertCanWrite2(ctx);
|
|
18924
|
-
if (
|
|
19353
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
|
|
18925
19354
|
stale = true;
|
|
18926
19355
|
return;
|
|
18927
19356
|
}
|
|
18928
|
-
await
|
|
19357
|
+
await record3.update((r) => {
|
|
18929
19358
|
r._setRaw("archived_at", null);
|
|
18930
19359
|
});
|
|
18931
19360
|
});
|
|
@@ -18936,18 +19365,18 @@ async function restoreVaultMemoryOp(ctx, id2) {
|
|
|
18936
19365
|
}
|
|
18937
19366
|
async function hardDeleteDecayedOp(ctx, id2, opts) {
|
|
18938
19367
|
try {
|
|
18939
|
-
const
|
|
18940
|
-
if (
|
|
19368
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
19369
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
18941
19370
|
const now = opts.now ?? Date.now();
|
|
18942
19371
|
let stale = false;
|
|
18943
19372
|
await ctx.database.write(async () => {
|
|
18944
19373
|
await assertCanWrite2(ctx);
|
|
18945
|
-
const archivedAt =
|
|
18946
|
-
if (
|
|
19374
|
+
const archivedAt = record3.archivedAt;
|
|
19375
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
|
|
18947
19376
|
stale = true;
|
|
18948
19377
|
return;
|
|
18949
19378
|
}
|
|
18950
|
-
await
|
|
19379
|
+
await record3.update((r) => {
|
|
18951
19380
|
r._setRaw("is_deleted", true);
|
|
18952
19381
|
});
|
|
18953
19382
|
});
|
|
@@ -18965,14 +19394,14 @@ async function hardDeleteDecayedOp(ctx, id2, opts) {
|
|
|
18965
19394
|
}
|
|
18966
19395
|
async function updateVaultMemoryEmbeddingOp(ctx, id2, embedding2, embeddingModel, expected) {
|
|
18967
19396
|
try {
|
|
18968
|
-
const
|
|
18969
|
-
if (
|
|
18970
|
-
const readUpdatedAt =
|
|
18971
|
-
const readStoredContent =
|
|
19397
|
+
const record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
19398
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
|
|
19399
|
+
const readUpdatedAt = record3.updatedAt.getTime();
|
|
19400
|
+
const readStoredContent = record3._getRaw("content");
|
|
18972
19401
|
if (expected?.updatedAt !== void 0 && expected.updatedAt !== readUpdatedAt) return false;
|
|
18973
19402
|
if (expected?.content !== void 0) {
|
|
18974
19403
|
const current = await vaultMemoryToStored(
|
|
18975
|
-
|
|
19404
|
+
record3,
|
|
18976
19405
|
ctx.walletAddress,
|
|
18977
19406
|
ctx.signMessage,
|
|
18978
19407
|
ctx.embeddedWalletSigner
|
|
@@ -18982,11 +19411,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id2, embedding2, embeddingModel
|
|
|
18982
19411
|
let written = false;
|
|
18983
19412
|
await ctx.database.write(async () => {
|
|
18984
19413
|
await assertCanWrite2(ctx);
|
|
18985
|
-
if (
|
|
18986
|
-
const originalUpdatedAt =
|
|
18987
|
-
if (originalUpdatedAt !== readUpdatedAt ||
|
|
19414
|
+
if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return;
|
|
19415
|
+
const originalUpdatedAt = record3.updatedAt.getTime();
|
|
19416
|
+
if (originalUpdatedAt !== readUpdatedAt || record3._getRaw("content") !== readStoredContent)
|
|
18988
19417
|
return;
|
|
18989
|
-
await
|
|
19418
|
+
await record3.update((r) => {
|
|
18990
19419
|
r._setRaw("embedding", embedding2);
|
|
18991
19420
|
r._setRaw("embedding_model", embeddingModel);
|
|
18992
19421
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
@@ -19150,26 +19579,26 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
|
|
|
19150
19579
|
inserted = writable.length;
|
|
19151
19580
|
if (writable.length === 0) return;
|
|
19152
19581
|
const prepared = writable.map(
|
|
19153
|
-
({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((
|
|
19154
|
-
|
|
19155
|
-
|
|
19156
|
-
|
|
19157
|
-
|
|
19158
|
-
|
|
19159
|
-
|
|
19160
|
-
|
|
19161
|
-
|
|
19162
|
-
|
|
19163
|
-
|
|
19582
|
+
({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record3) => {
|
|
19583
|
+
record3._raw.id = row.memoryId;
|
|
19584
|
+
record3._setRaw("content", content);
|
|
19585
|
+
record3._setRaw("scope", "shared");
|
|
19586
|
+
record3._setRaw("level", "matching");
|
|
19587
|
+
record3._setRaw("folder_id", null);
|
|
19588
|
+
record3._setRaw("user_id", ctx.userId ?? null);
|
|
19589
|
+
record3._setRaw("is_deleted", false);
|
|
19590
|
+
record3._setRaw("proof_count", 1);
|
|
19591
|
+
record3._setRaw("source", SOURCE_PHOTO);
|
|
19592
|
+
record3._setRaw(
|
|
19164
19593
|
"media",
|
|
19165
19594
|
row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
|
|
19166
19595
|
);
|
|
19167
|
-
|
|
19168
|
-
|
|
19596
|
+
record3._setRaw("visibility", "public");
|
|
19597
|
+
record3._setRaw("published_at", now);
|
|
19169
19598
|
if (row.eventTime) {
|
|
19170
|
-
|
|
19171
|
-
|
|
19172
|
-
|
|
19599
|
+
record3._setRaw("event_time_start", row.eventTime.start ?? null);
|
|
19600
|
+
record3._setRaw("event_time_end", row.eventTime.end ?? null);
|
|
19601
|
+
record3._setRaw("event_time_kind", row.eventTime.kind ?? null);
|
|
19173
19602
|
}
|
|
19174
19603
|
})
|
|
19175
19604
|
);
|
|
@@ -20000,11 +20429,11 @@ function folderToStored(folder) {
|
|
|
20000
20429
|
}
|
|
20001
20430
|
async function createVaultFolderOp(ctx, opts) {
|
|
20002
20431
|
const created = await ctx.database.write(async () => {
|
|
20003
|
-
return ctx.vaultFolderCollection.create((
|
|
20004
|
-
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20432
|
+
return ctx.vaultFolderCollection.create((record3) => {
|
|
20433
|
+
record3._setRaw("name", opts.name);
|
|
20434
|
+
record3._setRaw("scope", opts.scope ?? "private");
|
|
20435
|
+
record3._setRaw("is_system", opts.isSystem ?? false);
|
|
20436
|
+
record3._setRaw("is_deleted", false);
|
|
20008
20437
|
});
|
|
20009
20438
|
});
|
|
20010
20439
|
return folderToStored(created);
|
|
@@ -20015,14 +20444,14 @@ async function getAllVaultFoldersOp(ctx) {
|
|
|
20015
20444
|
}
|
|
20016
20445
|
async function updateVaultFolderOp(ctx, id2, opts) {
|
|
20017
20446
|
try {
|
|
20018
|
-
const
|
|
20019
|
-
if (
|
|
20020
|
-
const scopeChanged = opts.scope !== void 0 && opts.scope !==
|
|
20447
|
+
const record3 = await ctx.vaultFolderCollection.find(id2);
|
|
20448
|
+
if (record3.isDeleted) return null;
|
|
20449
|
+
const scopeChanged = opts.scope !== void 0 && opts.scope !== record3.scope;
|
|
20021
20450
|
const updated = await ctx.database.write(async () => {
|
|
20022
20451
|
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q15.where("folder_id", id2), Q15.where("is_deleted", false)).fetch() : [];
|
|
20023
20452
|
const updates = [];
|
|
20024
20453
|
updates.push(
|
|
20025
|
-
|
|
20454
|
+
record3.prepareUpdate((r) => {
|
|
20026
20455
|
if (opts.name !== void 0) r._setRaw("name", opts.name);
|
|
20027
20456
|
if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
|
|
20028
20457
|
})
|
|
@@ -20045,8 +20474,8 @@ async function updateVaultFolderOp(ctx, id2, opts) {
|
|
|
20045
20474
|
}
|
|
20046
20475
|
async function deleteVaultFolderOp(ctx, id2) {
|
|
20047
20476
|
try {
|
|
20048
|
-
const
|
|
20049
|
-
if (
|
|
20477
|
+
const record3 = await ctx.vaultFolderCollection.find(id2);
|
|
20478
|
+
if (record3.isDeleted) return false;
|
|
20050
20479
|
await ctx.database.write(async () => {
|
|
20051
20480
|
const memories = await ctx.vaultMemoryCollection.query(Q15.where("folder_id", id2), Q15.where("is_deleted", false)).fetch();
|
|
20052
20481
|
const preparedMemories = memories.map(
|
|
@@ -20056,7 +20485,7 @@ async function deleteVaultFolderOp(ctx, id2) {
|
|
|
20056
20485
|
r._setRaw("scope", "private");
|
|
20057
20486
|
})
|
|
20058
20487
|
);
|
|
20059
|
-
const preparedFolder =
|
|
20488
|
+
const preparedFolder = record3.prepareUpdate((r) => {
|
|
20060
20489
|
r._setRaw("is_deleted", true);
|
|
20061
20490
|
});
|
|
20062
20491
|
await ctx.database.batch(...preparedMemories, preparedFolder);
|
|
@@ -20103,11 +20532,11 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
|
|
|
20103
20532
|
}
|
|
20104
20533
|
async function updateVaultFolderContextOp(ctx, id2, context) {
|
|
20105
20534
|
try {
|
|
20106
|
-
const
|
|
20107
|
-
if (
|
|
20535
|
+
const record3 = await ctx.vaultFolderCollection.find(id2);
|
|
20536
|
+
if (record3.isDeleted) return null;
|
|
20108
20537
|
const updated = await ctx.database.write(async () => {
|
|
20109
20538
|
await ctx.database.batch(
|
|
20110
|
-
|
|
20539
|
+
record3.prepareUpdate((r) => {
|
|
20111
20540
|
r._setRaw("context", context);
|
|
20112
20541
|
})
|
|
20113
20542
|
);
|
|
@@ -21201,9 +21630,9 @@ function loadVaultCorpus(ctx, options, preparation) {
|
|
|
21201
21630
|
const key3 = JSON.stringify(options ?? {});
|
|
21202
21631
|
let request = pending.get(key3);
|
|
21203
21632
|
if (!request) {
|
|
21204
|
-
const
|
|
21633
|
+
const entries2 = pending;
|
|
21205
21634
|
request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
|
|
21206
|
-
|
|
21635
|
+
entries2.delete(key3);
|
|
21207
21636
|
throw error;
|
|
21208
21637
|
});
|
|
21209
21638
|
pending.set(key3, request);
|
|
@@ -21244,7 +21673,7 @@ function embedVaultRows(ctx, options, rows, preparation) {
|
|
|
21244
21673
|
if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing2.set(keys[index], row);
|
|
21245
21674
|
});
|
|
21246
21675
|
if (missing2.size > 0) {
|
|
21247
|
-
const
|
|
21676
|
+
const entries2 = pending;
|
|
21248
21677
|
const batch = Promise.resolve().then(
|
|
21249
21678
|
() => generateEmbeddings(
|
|
21250
21679
|
[...missing2.values()].map((row) => row.content),
|
|
@@ -21261,16 +21690,16 @@ function embedVaultRows(ctx, options, rows, preparation) {
|
|
|
21261
21690
|
});
|
|
21262
21691
|
return vector2;
|
|
21263
21692
|
}).finally(() => {
|
|
21264
|
-
|
|
21265
|
-
if (
|
|
21693
|
+
entries2.delete(key3);
|
|
21694
|
+
if (entries2.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
|
|
21266
21695
|
});
|
|
21267
21696
|
pending.set(key3, request);
|
|
21268
21697
|
});
|
|
21269
21698
|
}
|
|
21270
21699
|
return Promise.all(
|
|
21271
21700
|
keys.map((key3) => {
|
|
21272
|
-
const
|
|
21273
|
-
if (
|
|
21701
|
+
const cached2 = prepared?.get(key3);
|
|
21702
|
+
if (cached2) return cached2;
|
|
21274
21703
|
const request = pending.get(key3);
|
|
21275
21704
|
if (!prepared) return request;
|
|
21276
21705
|
const retained = request.catch((error) => {
|
|
@@ -21970,10 +22399,10 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
21970
22399
|
const resolvedThisCall = /* @__PURE__ */ new Set();
|
|
21971
22400
|
if (!embeddingsDegraded) {
|
|
21972
22401
|
for (const k2 of keys) {
|
|
21973
|
-
const
|
|
21974
|
-
if (
|
|
22402
|
+
const cached2 = cachedRowVector(cache, k2.uniqueId, k2.updatedAt);
|
|
22403
|
+
if (cached2 && cached2.length === queryEmbedding.length) {
|
|
21975
22404
|
corpusStats.cacheHits++;
|
|
21976
|
-
vectored.push({ uniqueId: k2.uniqueId, embedding:
|
|
22405
|
+
vectored.push({ uniqueId: k2.uniqueId, embedding: cached2, updatedAt: k2.updatedAt });
|
|
21977
22406
|
continue;
|
|
21978
22407
|
}
|
|
21979
22408
|
corpusStats.cacheMisses++;
|
|
@@ -22271,12 +22700,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
22271
22700
|
for (let i = 0; queryEmbedding.length > 0 && i < memories.length; i++) {
|
|
22272
22701
|
const content = memories[i].content;
|
|
22273
22702
|
const memoryId = memories[i].uniqueId;
|
|
22274
|
-
const
|
|
22275
|
-
if (
|
|
22276
|
-
resolvedVectors.set(memoryId,
|
|
22703
|
+
const cached2 = cachedRowVector(cache, memoryId, memories[i].updatedAt, content);
|
|
22704
|
+
if (cached2 && cached2.length === queryEmbedding.length) {
|
|
22705
|
+
resolvedVectors.set(memoryId, cached2);
|
|
22277
22706
|
continue;
|
|
22278
22707
|
}
|
|
22279
|
-
if (
|
|
22708
|
+
if (cached2) cache.delete(memoryId);
|
|
22280
22709
|
const storedModel = memories[i].embeddingModel;
|
|
22281
22710
|
const modelCompatible = (storedModel ?? currentModel) === currentModel;
|
|
22282
22711
|
if (memories[i].embedding && modelCompatible) {
|
|
@@ -23960,9 +24389,9 @@ function createDecaySweeperOver(backend, options) {
|
|
|
23960
24389
|
if (ruleVerdict !== "keep") return rule;
|
|
23961
24390
|
if (!classifier || !isBorderline(input)) return rule;
|
|
23962
24391
|
if (input.id) {
|
|
23963
|
-
const
|
|
23964
|
-
if (
|
|
23965
|
-
return { verdict:
|
|
24392
|
+
const cached2 = classifierCache.get(input.id);
|
|
24393
|
+
if (cached2 && cached2.activityAt === lastActivityAt(input))
|
|
24394
|
+
return { verdict: cached2.verdict, source: "classifierDriven" };
|
|
23966
24395
|
}
|
|
23967
24396
|
if (sweep.classifierCalls >= maxClassifierCalls) {
|
|
23968
24397
|
sweep.classifierCapHits++;
|
|
@@ -25811,21 +26240,21 @@ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
|
|
|
25811
26240
|
};
|
|
25812
26241
|
const inputs = [];
|
|
25813
26242
|
for (const id2 of new Set(memoryIds)) {
|
|
25814
|
-
let
|
|
26243
|
+
let record3;
|
|
25815
26244
|
try {
|
|
25816
|
-
|
|
26245
|
+
record3 = await ctx.vaultMemoryCollection.find(id2);
|
|
25817
26246
|
} catch (err) {
|
|
25818
26247
|
log.warn("[memory/topics] vault lookup failed for extraction", err);
|
|
25819
26248
|
skip(id2, "not-found");
|
|
25820
26249
|
continue;
|
|
25821
26250
|
}
|
|
25822
|
-
if (
|
|
26251
|
+
if (record3.isDeleted || ctx.userId !== void 0 && record3.userId !== ctx.userId || record3.topicsUserManaged) {
|
|
25823
26252
|
skip(id2, "excluded");
|
|
25824
26253
|
continue;
|
|
25825
26254
|
}
|
|
25826
26255
|
try {
|
|
25827
26256
|
const stored2 = await vaultMemoryToStored(
|
|
25828
|
-
|
|
26257
|
+
record3,
|
|
25829
26258
|
ctx.walletAddress,
|
|
25830
26259
|
ctx.signMessage,
|
|
25831
26260
|
ctx.embeddedWalletSigner
|
|
@@ -26132,6 +26561,7 @@ function createLocalMemoryStore(options) {
|
|
|
26132
26561
|
|
|
26133
26562
|
// src/lib/memory/store/memoryKeys.ts
|
|
26134
26563
|
var KEY_ID_DOMAIN = "anuma-private-memory-key-id-v1";
|
|
26564
|
+
var TOPIC_HASH_INFO = "anuma-private-memory-topic-hash-v1";
|
|
26135
26565
|
var MemoryKeyError = class extends Error {
|
|
26136
26566
|
constructor(message) {
|
|
26137
26567
|
super(message);
|
|
@@ -26147,17 +26577,40 @@ async function importAesKey(hex) {
|
|
|
26147
26577
|
["encrypt", "decrypt"]
|
|
26148
26578
|
);
|
|
26149
26579
|
}
|
|
26580
|
+
async function deriveTopicHashKey(hex) {
|
|
26581
|
+
const material = await crypto.subtle.importKey(
|
|
26582
|
+
"raw",
|
|
26583
|
+
hexToBytes(hex).buffer,
|
|
26584
|
+
{ name: "HKDF" },
|
|
26585
|
+
false,
|
|
26586
|
+
["deriveBits"]
|
|
26587
|
+
);
|
|
26588
|
+
const bits = await crypto.subtle.deriveBits(
|
|
26589
|
+
{
|
|
26590
|
+
name: "HKDF",
|
|
26591
|
+
hash: "SHA-256",
|
|
26592
|
+
salt: new Uint8Array(32),
|
|
26593
|
+
info: new TextEncoder().encode(TOPIC_HASH_INFO)
|
|
26594
|
+
},
|
|
26595
|
+
material,
|
|
26596
|
+
256
|
|
26597
|
+
);
|
|
26598
|
+
return crypto.subtle.importKey("raw", bits, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
26599
|
+
}
|
|
26600
|
+
function toHex(bytes4) {
|
|
26601
|
+
return Array.from(new Uint8Array(bytes4), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
26602
|
+
}
|
|
26150
26603
|
async function deriveMemoryKeyRing(signatureHex) {
|
|
26151
26604
|
const v3Hex = await deriveKeyFromSignatureV3(signatureHex);
|
|
26152
26605
|
const digest = await crypto.subtle.digest(
|
|
26153
26606
|
"SHA-256",
|
|
26154
26607
|
new TextEncoder().encode(`${KEY_ID_DOMAIN}:${v3Hex}`)
|
|
26155
26608
|
);
|
|
26156
|
-
const keyId = "v3:" + Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
26157
26609
|
return {
|
|
26158
|
-
keyId,
|
|
26610
|
+
keyId: "v3:" + toHex(digest),
|
|
26159
26611
|
v3: await importAesKey(v3Hex),
|
|
26160
|
-
v2: await importAesKey(await deriveKeyFromSignature(signatureHex))
|
|
26612
|
+
v2: await importAesKey(await deriveKeyFromSignature(signatureHex)),
|
|
26613
|
+
topicHash: await deriveTopicHashKey(v3Hex)
|
|
26161
26614
|
};
|
|
26162
26615
|
}
|
|
26163
26616
|
async function decryptWith(value, rings) {
|
|
@@ -26178,7 +26631,10 @@ function memoryCipher(canonical) {
|
|
|
26178
26631
|
if (!ciphertext.startsWith("enc:v3:") || !isEncrypted(ciphertext))
|
|
26179
26632
|
throw new MemoryKeyError("Remote memory content must be enc:v3 ciphertext");
|
|
26180
26633
|
return decryptWith(ciphertext, [canonical]);
|
|
26181
|
-
}
|
|
26634
|
+
},
|
|
26635
|
+
hashTopic: async (normalized2) => toHex(
|
|
26636
|
+
await crypto.subtle.sign("HMAC", canonical.topicHash, new TextEncoder().encode(normalized2))
|
|
26637
|
+
)
|
|
26182
26638
|
};
|
|
26183
26639
|
}
|
|
26184
26640
|
async function reencryptMemoryField(value, canonical, fallbacks = []) {
|
|
@@ -26610,8 +27066,9 @@ var DEFAULT_RATE_LIMIT_WAIT_MS = 1e4;
|
|
|
26610
27066
|
var MAX_ID_BYTES = 128;
|
|
26611
27067
|
var MAX_CONTENT_BYTES = 32 << 10;
|
|
26612
27068
|
var MAX_TEXT_BYTES = 16 << 10;
|
|
27069
|
+
var MAX_TOPICS_BYTES = 32 << 10;
|
|
26613
27070
|
var MAX_SHORT_BYTES = 256;
|
|
26614
|
-
var TEXT_FIELDS = ["
|
|
27071
|
+
var TEXT_FIELDS = ["media", "source_chunk_ids"];
|
|
26615
27072
|
var SHORT_FIELDS = [
|
|
26616
27073
|
"scope",
|
|
26617
27074
|
"kind",
|
|
@@ -26714,7 +27171,7 @@ function bytes3(value) {
|
|
|
26714
27171
|
return value === void 0 ? 0 : utf82.encode(value).length;
|
|
26715
27172
|
}
|
|
26716
27173
|
function fitsNearby(row) {
|
|
26717
|
-
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);
|
|
27174
|
+
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);
|
|
26718
27175
|
}
|
|
26719
27176
|
function invalid2(raw) {
|
|
26720
27177
|
const id2 = raw.id;
|
|
@@ -26758,7 +27215,7 @@ function defined(value) {
|
|
|
26758
27215
|
Object.entries(value).filter(([, field10]) => field10 !== void 0)
|
|
26759
27216
|
);
|
|
26760
27217
|
}
|
|
26761
|
-
async function prepareRow(raw, canonical, rings, model, updatedAt) {
|
|
27218
|
+
async function prepareRow(raw, canonical, codec, rings, model, updatedAt) {
|
|
26762
27219
|
const deleted = bool(raw.is_deleted) ?? false;
|
|
26763
27220
|
const { encrypt } = memoryCipher(canonical);
|
|
26764
27221
|
const localKindValue = text15(raw.kind_value);
|
|
@@ -26772,10 +27229,12 @@ async function prepareRow(raw, canonical, rings, model, updatedAt) {
|
|
|
26772
27229
|
plaintext = void 0;
|
|
26773
27230
|
kindValue = void 0;
|
|
26774
27231
|
}
|
|
27232
|
+
const fields = metadata2(raw, model);
|
|
26775
27233
|
const row = {
|
|
26776
27234
|
...defined({
|
|
26777
|
-
...
|
|
26778
|
-
kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue)
|
|
27235
|
+
...fields,
|
|
27236
|
+
kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue),
|
|
27237
|
+
topics: fields.topics === void 0 ? void 0 : await codec.encodeTopics(fields.topics)
|
|
26779
27238
|
}),
|
|
26780
27239
|
memory_id: raw.id,
|
|
26781
27240
|
content: await encrypt(plaintext ?? ""),
|
|
@@ -26819,6 +27278,8 @@ function sameMetadata2(local, remote, model) {
|
|
|
26819
27278
|
if (field10 === "visibility") return (a ?? "private") === (b ?? "private");
|
|
26820
27279
|
if (field10 === "is_deleted" || field10 === "topics_user_managed" || field10 === "twin_opt_in")
|
|
26821
27280
|
return (a ?? false) === (b ?? false);
|
|
27281
|
+
if (field10 === "topics")
|
|
27282
|
+
return JSON.stringify(parseTopics(a)) === JSON.stringify(parseTopics(b));
|
|
26822
27283
|
return a === b;
|
|
26823
27284
|
});
|
|
26824
27285
|
}
|
|
@@ -26874,7 +27335,7 @@ async function missingIds(request, revisions, signal) {
|
|
|
26874
27335
|
}
|
|
26875
27336
|
return missing2;
|
|
26876
27337
|
}
|
|
26877
|
-
async function remoteMetadata(request, ids, signal) {
|
|
27338
|
+
async function remoteMetadata(request, codec, ids, signal) {
|
|
26878
27339
|
const rows = /* @__PURE__ */ new Map();
|
|
26879
27340
|
for (const batch of chunks(ids, QUERY_IDS)) {
|
|
26880
27341
|
let cursor;
|
|
@@ -26898,7 +27359,12 @@ async function remoteMetadata(request, ids, signal) {
|
|
|
26898
27359
|
if (!Array.isArray(page.items)) throw new Error("Invalid nearby private-memory page");
|
|
26899
27360
|
for (const item of page.items)
|
|
26900
27361
|
if (item.memory && typeof item.memory.memory_id === "string")
|
|
26901
|
-
rows.set(item.memory.memory_id,
|
|
27362
|
+
rows.set(item.memory.memory_id, {
|
|
27363
|
+
...item.memory,
|
|
27364
|
+
...typeof item.memory.topics === "string" && {
|
|
27365
|
+
topics: await codec.decodeTopics(item.memory.topics).catch(() => null)
|
|
27366
|
+
}
|
|
27367
|
+
});
|
|
26902
27368
|
cursor = typeof page.next_cursor === "string" ? page.next_cursor : void 0;
|
|
26903
27369
|
} while (cursor);
|
|
26904
27370
|
}
|
|
@@ -26916,6 +27382,7 @@ async function migrateMemoriesToRemote(options) {
|
|
|
26916
27382
|
const rings = [canonical, ...options.fallbacks ?? []];
|
|
26917
27383
|
const model = options.embeddingOptions?.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
26918
27384
|
const request = createNearbyRequest(options);
|
|
27385
|
+
const codec = createTopicCodec(memoryCipher(canonical));
|
|
26919
27386
|
const account = await request("/account", {}, signal);
|
|
26920
27387
|
if (typeof account.key_id === "string" && account.key_id !== canonical.keyId)
|
|
26921
27388
|
throw new RemoteMemoryError(
|
|
@@ -26932,7 +27399,7 @@ async function migrateMemoriesToRemote(options) {
|
|
|
26932
27399
|
...typeof t.kind === "string" && { kind: t.kind }
|
|
26933
27400
|
})).filter((t) => t.name.length > 0) : []);
|
|
26934
27401
|
if (localTopics.length)
|
|
26935
|
-
await createRemoteTopicPersistence(request).importTopics(localTopics, signal);
|
|
27402
|
+
await createRemoteTopicPersistence(request, codec).importTopics(localTopics, signal);
|
|
26936
27403
|
const skipped = /* @__PURE__ */ new Map();
|
|
26937
27404
|
const reembedded = /* @__PURE__ */ new Set();
|
|
26938
27405
|
const unembedded = /* @__PURE__ */ new Set();
|
|
@@ -26951,6 +27418,7 @@ async function migrateMemoriesToRemote(options) {
|
|
|
26951
27418
|
if (pending.size === 0 && !active) {
|
|
26952
27419
|
const remote = await remoteMetadata(
|
|
26953
27420
|
request,
|
|
27421
|
+
codec,
|
|
26954
27422
|
candidates.map((raw) => raw.id),
|
|
26955
27423
|
signal
|
|
26956
27424
|
);
|
|
@@ -26995,7 +27463,7 @@ async function migrateMemoriesToRemote(options) {
|
|
|
26995
27463
|
const updatedAt = pending.get(raw.id);
|
|
26996
27464
|
if (updatedAt === void 0) continue;
|
|
26997
27465
|
try {
|
|
26998
|
-
prepared.push(await prepareRow(raw, canonical, rings, model, updatedAt));
|
|
27466
|
+
prepared.push(await prepareRow(raw, canonical, codec, rings, model, updatedAt));
|
|
26999
27467
|
} catch (error) {
|
|
27000
27468
|
if (!(error instanceof MemoryKeyError)) throw error;
|
|
27001
27469
|
skipped.set(raw.id, "unreadable");
|
|
@@ -27154,7 +27622,7 @@ function topicInputs(topics, source) {
|
|
|
27154
27622
|
function mergeTopics(existing, added) {
|
|
27155
27623
|
const byName = /* @__PURE__ */ new Map();
|
|
27156
27624
|
for (const topic2 of [...existing, ...added]) {
|
|
27157
|
-
const key3 =
|
|
27625
|
+
const key3 = normalizeTopicName(topic2.name);
|
|
27158
27626
|
const kept = byName.get(key3);
|
|
27159
27627
|
if (!kept) byName.set(key3, topic2);
|
|
27160
27628
|
else if (kept.weight !== void 0 && topic2.weight !== void 0 && topic2.weight > kept.weight)
|
|
@@ -27169,7 +27637,7 @@ function sameTopics(stored2, next) {
|
|
|
27169
27637
|
return next.every((t) => keys.has(key3(t)));
|
|
27170
27638
|
}
|
|
27171
27639
|
function canonicalTopics(row) {
|
|
27172
|
-
return new Set((parseTopics(row.topics) ?? []).map((topic2) =>
|
|
27640
|
+
return new Set((parseTopics(row.topics) ?? []).map((topic2) => normalizeTopicName(topic2.name)));
|
|
27173
27641
|
}
|
|
27174
27642
|
function createRemoteMemoryStore(options) {
|
|
27175
27643
|
const { persistence, embeddingOptions } = options;
|
|
@@ -27216,10 +27684,10 @@ function createRemoteMemoryStore(options) {
|
|
|
27216
27684
|
const notify = (change, records = []) => {
|
|
27217
27685
|
invalidateReads();
|
|
27218
27686
|
if (subscribers.size)
|
|
27219
|
-
for (const
|
|
27220
|
-
const previous = seen.get(
|
|
27221
|
-
if ((previous?.version ?? 0) + 1 ===
|
|
27222
|
-
seen.set(
|
|
27687
|
+
for (const record3 of records) {
|
|
27688
|
+
const previous = seen.get(record3.memory.memory_id);
|
|
27689
|
+
if ((previous?.version ?? 0) + 1 === record3.version)
|
|
27690
|
+
seen.set(record3.memory.memory_id, subscriptionState(record3));
|
|
27223
27691
|
}
|
|
27224
27692
|
for (const subscriber of [...subscribers])
|
|
27225
27693
|
if (relevant(change, subscriber.options)) safely(subscriber.onChange);
|
|
@@ -27272,7 +27740,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27272
27740
|
};
|
|
27273
27741
|
const enumerate = (filters, max = Infinity) => pages(decrypted, filters, max);
|
|
27274
27742
|
const memoriesByTopics = async (names) => {
|
|
27275
|
-
const wanted = new Set(names.map(
|
|
27743
|
+
const wanted = new Set(names.map(normalizeTopicName).filter(Boolean));
|
|
27276
27744
|
const out = /* @__PURE__ */ new Map();
|
|
27277
27745
|
const pages2 = await Promise.all(
|
|
27278
27746
|
chunks2([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
|
|
@@ -27284,7 +27752,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27284
27752
|
return out;
|
|
27285
27753
|
};
|
|
27286
27754
|
const topicGraphRanking = async (query, recallOptions = {}) => {
|
|
27287
|
-
const wanted = new Set(extractQueryEntities(query).map(
|
|
27755
|
+
const wanted = new Set(extractQueryEntities(query).map(normalizeTopicName).filter(Boolean));
|
|
27288
27756
|
if (wanted.size === 0 || recallOptions.memoryIds?.length === 0) return [];
|
|
27289
27757
|
const rows = await pages(
|
|
27290
27758
|
metadata3,
|
|
@@ -27342,25 +27810,25 @@ function createRemoteMemoryStore(options) {
|
|
|
27342
27810
|
return run;
|
|
27343
27811
|
};
|
|
27344
27812
|
const live2 = async (id2) => {
|
|
27345
|
-
const
|
|
27346
|
-
return
|
|
27813
|
+
const record3 = await persistence.get(id2);
|
|
27814
|
+
return record3 && !record3.memory.is_deleted ? record3 : null;
|
|
27347
27815
|
};
|
|
27348
27816
|
const mutateLocked = async (id2, change, edit, writeOptions) => {
|
|
27349
27817
|
writeOptions?.signal?.throwIfAborted();
|
|
27350
|
-
const
|
|
27351
|
-
if (!
|
|
27352
|
-
if (
|
|
27818
|
+
const record3 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await live2(id2);
|
|
27819
|
+
if (!record3) return null;
|
|
27820
|
+
if (record3.memory.is_deleted) return null;
|
|
27353
27821
|
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
27354
27822
|
throw new MemorySourceIneligibleError();
|
|
27355
27823
|
writeOptions?.signal?.throwIfAborted();
|
|
27356
|
-
const next = edit(structuredClone(
|
|
27824
|
+
const next = edit(structuredClone(record3.memory));
|
|
27357
27825
|
if (!next) return null;
|
|
27358
27826
|
const saved = writeOptions?.leaseToken ? (await persistence.putMany(
|
|
27359
|
-
[{ memory: next, expectedVersion:
|
|
27827
|
+
[{ memory: next, expectedVersion: record3 }],
|
|
27360
27828
|
writeOptions.signal,
|
|
27361
27829
|
writeOptions.leaseToken
|
|
27362
|
-
))[0] : writeOptions?.signal ? await persistence.put(next,
|
|
27363
|
-
notify(typeof change === "function" ? change(
|
|
27830
|
+
))[0] : writeOptions?.signal ? await persistence.put(next, record3, writeOptions.signal) : await persistence.put(next, record3);
|
|
27831
|
+
notify(typeof change === "function" ? change(record3.memory) : change, [saved]);
|
|
27364
27832
|
return saved;
|
|
27365
27833
|
};
|
|
27366
27834
|
const mutate = (id2, change, edit, writeOptions) => serialized(id2, () => mutateLocked(id2, change, edit, writeOptions));
|
|
@@ -27382,12 +27850,12 @@ function createRemoteMemoryStore(options) {
|
|
|
27382
27850
|
}
|
|
27383
27851
|
const { records, unreadable } = read;
|
|
27384
27852
|
for (const id2 of slice) {
|
|
27385
|
-
const
|
|
27853
|
+
const record3 = records.get(id2);
|
|
27386
27854
|
if (unreadable.has(id2)) failed.set(id2, new Error(`Memory ${id2} could not be decrypted`));
|
|
27387
|
-
else if (!
|
|
27388
|
-
else if (!
|
|
27389
|
-
const memory = edit(structuredClone(
|
|
27390
|
-
if (memory) writes.push({ before:
|
|
27855
|
+
else if (!record3) failed.set(id2, new Error(`Memory ${id2} was not found`));
|
|
27856
|
+
else if (!record3.memory.is_deleted) {
|
|
27857
|
+
const memory = edit(structuredClone(record3.memory));
|
|
27858
|
+
if (memory) writes.push({ before: record3, memory });
|
|
27391
27859
|
}
|
|
27392
27860
|
}
|
|
27393
27861
|
if (writes.length === 0) return;
|
|
@@ -27398,10 +27866,10 @@ function createRemoteMemoryStore(options) {
|
|
|
27398
27866
|
leaseToken
|
|
27399
27867
|
);
|
|
27400
27868
|
const byChange = /* @__PURE__ */ new Map();
|
|
27401
|
-
written.forEach((
|
|
27402
|
-
saved.set(
|
|
27869
|
+
written.forEach((record3, i) => {
|
|
27870
|
+
saved.set(record3.memory.memory_id, record3);
|
|
27403
27871
|
const kind = change(writes[i].before.memory);
|
|
27404
|
-
byChange.set(kind, [...byChange.get(kind) ?? [],
|
|
27872
|
+
byChange.set(kind, [...byChange.get(kind) ?? [], record3]);
|
|
27405
27873
|
});
|
|
27406
27874
|
for (const [kind, changed] of byChange) notify(kind, changed);
|
|
27407
27875
|
} catch (error) {
|
|
@@ -27415,13 +27883,13 @@ function createRemoteMemoryStore(options) {
|
|
|
27415
27883
|
continue;
|
|
27416
27884
|
}
|
|
27417
27885
|
try {
|
|
27418
|
-
const
|
|
27886
|
+
const record3 = await mutateLocked(
|
|
27419
27887
|
id2,
|
|
27420
27888
|
change,
|
|
27421
27889
|
edit,
|
|
27422
27890
|
leaseToken || signal ? { leaseToken, signal } : void 0
|
|
27423
27891
|
);
|
|
27424
|
-
if (
|
|
27892
|
+
if (record3) saved.set(id2, record3);
|
|
27425
27893
|
} catch (rowError) {
|
|
27426
27894
|
signal?.throwIfAborted();
|
|
27427
27895
|
if (isRemoteWorkLeaseExpired(rowError)) throw rowError;
|
|
@@ -27517,12 +27985,12 @@ function createRemoteMemoryStore(options) {
|
|
|
27517
27985
|
const created = (records, inputs) => {
|
|
27518
27986
|
embedInBackground(records.filter((_, i) => inputs[i].embedding === void 0));
|
|
27519
27987
|
notify("membership", records);
|
|
27520
|
-
return records.map((
|
|
27988
|
+
return records.map((record3) => stored(record3.memory));
|
|
27521
27989
|
};
|
|
27522
|
-
const asStored = (
|
|
27990
|
+
const asStored = (record3) => record3 ? stored(record3.memory) : null;
|
|
27523
27991
|
const knownKinds = async (topics, signal) => {
|
|
27524
27992
|
const unkinded = [
|
|
27525
|
-
...new Set(topics.filter((t) => !t.kind).map((t) =>
|
|
27993
|
+
...new Set(topics.filter((t) => !t.kind).map((t) => normalizeTopicName(t.name)))
|
|
27526
27994
|
];
|
|
27527
27995
|
const kinds2 = /* @__PURE__ */ new Map();
|
|
27528
27996
|
for (const names of chunks2(unkinded, MAX_QUERY_TOPICS)) {
|
|
@@ -27534,13 +28002,13 @@ function createRemoteMemoryStore(options) {
|
|
|
27534
28002
|
...signal && { signal }
|
|
27535
28003
|
})) {
|
|
27536
28004
|
for (const topic2 of parseTopics(memory.topics) ?? []) {
|
|
27537
|
-
const name =
|
|
28005
|
+
const name = normalizeTopicName(topic2.name);
|
|
27538
28006
|
if (topic2.kind && !kinds2.has(name)) kinds2.set(name, topic2.kind);
|
|
27539
28007
|
}
|
|
27540
28008
|
}
|
|
27541
28009
|
}
|
|
27542
28010
|
return (topic2) => {
|
|
27543
|
-
const kind = topic2.kind ?? kinds2.get(
|
|
28011
|
+
const kind = topic2.kind ?? kinds2.get(normalizeTopicName(topic2.name));
|
|
27544
28012
|
return kind ? { ...topic2, kind } : topic2;
|
|
27545
28013
|
};
|
|
27546
28014
|
};
|
|
@@ -27563,7 +28031,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27563
28031
|
...cursor2 && { cursor: cursor2 }
|
|
27564
28032
|
});
|
|
27565
28033
|
warnFailed(page.failed);
|
|
27566
|
-
for (const
|
|
28034
|
+
for (const record3 of page.items) records.set(record3.memory.memory_id, record3);
|
|
27567
28035
|
for (const failure of page.failed) unreadable.add(failure.memory_id);
|
|
27568
28036
|
cursor2 = page.next_cursor;
|
|
27569
28037
|
} while (cursor2);
|
|
@@ -27759,8 +28227,8 @@ function createRemoteMemoryStore(options) {
|
|
|
27759
28227
|
const failed = /* @__PURE__ */ new Map();
|
|
27760
28228
|
const collect = (page) => {
|
|
27761
28229
|
warnFailed(page.failed);
|
|
27762
|
-
for (const
|
|
27763
|
-
records.push({ id:
|
|
28230
|
+
for (const record3 of page.items)
|
|
28231
|
+
records.push({ id: record3.memory.memory_id, state: subscriptionState(record3) });
|
|
27764
28232
|
for (const failure of page.failed) failed.set(failure.memory_id, failure.version);
|
|
27765
28233
|
};
|
|
27766
28234
|
let resume = cursor2;
|
|
@@ -27965,7 +28433,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27965
28433
|
result.failed += targets.length;
|
|
27966
28434
|
return finish();
|
|
27967
28435
|
}
|
|
27968
|
-
const writes = targets.flatMap((
|
|
28436
|
+
const writes = targets.flatMap((record3, i) => {
|
|
27969
28437
|
const vector2 = vectors[i];
|
|
27970
28438
|
if (!vector2) {
|
|
27971
28439
|
result.failed++;
|
|
@@ -27975,11 +28443,11 @@ function createRemoteMemoryStore(options) {
|
|
|
27975
28443
|
return [
|
|
27976
28444
|
{
|
|
27977
28445
|
memory: {
|
|
27978
|
-
...
|
|
28446
|
+
...record3.memory,
|
|
27979
28447
|
embedding: storedVector(vector2),
|
|
27980
28448
|
embedding_model: model
|
|
27981
28449
|
},
|
|
27982
|
-
expectedVersion:
|
|
28450
|
+
expectedVersion: record3
|
|
27983
28451
|
}
|
|
27984
28452
|
];
|
|
27985
28453
|
} catch {
|
|
@@ -27994,7 +28462,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27994
28462
|
signal?.throwIfAborted();
|
|
27995
28463
|
const commit = async (slice) => {
|
|
27996
28464
|
const saved = await persistence.putMany(slice, signal, leaseToken);
|
|
27997
|
-
for (const
|
|
28465
|
+
for (const record3 of saved) repaired.add(record3.memory.memory_id);
|
|
27998
28466
|
result.reembedded += saved.length;
|
|
27999
28467
|
notify("embedding", saved);
|
|
28000
28468
|
};
|
|
@@ -28078,7 +28546,7 @@ function createRemoteMemoryStore(options) {
|
|
|
28078
28546
|
if (!topics.length) return;
|
|
28079
28547
|
const existing = new Set((await readTopics()).map((topic2) => topic2.name));
|
|
28080
28548
|
const missing2 = topics.flatMap((topic2) => {
|
|
28081
|
-
const name =
|
|
28549
|
+
const name = normalizeTopicName(topic2.name);
|
|
28082
28550
|
if (existing.has(name)) return [];
|
|
28083
28551
|
existing.add(name);
|
|
28084
28552
|
return [{ ...topic2, name }];
|
|
@@ -28109,7 +28577,7 @@ function createRemoteMemoryStore(options) {
|
|
|
28109
28577
|
include_superseded: true
|
|
28110
28578
|
})) {
|
|
28111
28579
|
for (const topic2 of parseTopics(memory.topics) ?? []) {
|
|
28112
|
-
const name =
|
|
28580
|
+
const name = normalizeTopicName(topic2.name);
|
|
28113
28581
|
if (!name) continue;
|
|
28114
28582
|
const entry = topics.get(name) ?? {
|
|
28115
28583
|
name,
|
|
@@ -28147,7 +28615,7 @@ function createRemoteMemoryStore(options) {
|
|
|
28147
28615
|
},
|
|
28148
28616
|
get: async (id2) => asStored(await live2(id2)),
|
|
28149
28617
|
listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
|
|
28150
|
-
(
|
|
28618
|
+
(record3) => stored(record3.memory)
|
|
28151
28619
|
),
|
|
28152
28620
|
memoriesByTopics,
|
|
28153
28621
|
topicsByMemories: async (memoryIds) => {
|
|
@@ -28163,8 +28631,8 @@ function createRemoteMemoryStore(options) {
|
|
|
28163
28631
|
return out;
|
|
28164
28632
|
},
|
|
28165
28633
|
create: async (input) => {
|
|
28166
|
-
const
|
|
28167
|
-
return created([
|
|
28634
|
+
const record3 = await persistence.put(newRow(input), 0);
|
|
28635
|
+
return created([record3], [input])[0];
|
|
28168
28636
|
},
|
|
28169
28637
|
createMany: async (inputs) => {
|
|
28170
28638
|
const out = [];
|
|
@@ -28251,12 +28719,12 @@ function createRemoteMemoryStore(options) {
|
|
|
28251
28719
|
(memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
|
|
28252
28720
|
),
|
|
28253
28721
|
restore: (id2) => serialized(id2, async () => {
|
|
28254
|
-
const
|
|
28255
|
-
if (!
|
|
28256
|
-
if (
|
|
28722
|
+
const record3 = await live2(id2);
|
|
28723
|
+
if (!record3) return false;
|
|
28724
|
+
if (record3.memory.archived_at === void 0 || record3.memory.archived_at === null)
|
|
28257
28725
|
return true;
|
|
28258
|
-
const { archived_at: _archivedAt, ...memory } =
|
|
28259
|
-
notify("edit", [await persistence.put(memory,
|
|
28726
|
+
const { archived_at: _archivedAt, ...memory } = record3.memory;
|
|
28727
|
+
notify("edit", [await persistence.put(memory, record3)]);
|
|
28260
28728
|
return true;
|
|
28261
28729
|
}),
|
|
28262
28730
|
setTopics: async (memoryId, topics) => {
|
|
@@ -28289,8 +28757,8 @@ function createRemoteMemoryStore(options) {
|
|
|
28289
28757
|
const now = /* @__PURE__ */ new Date();
|
|
28290
28758
|
return mergeTopics([], added).map(
|
|
28291
28759
|
(topic2) => ({
|
|
28292
|
-
uniqueId:
|
|
28293
|
-
canonicalName:
|
|
28760
|
+
uniqueId: normalizeTopicName(topic2.name),
|
|
28761
|
+
canonicalName: normalizeTopicName(topic2.name),
|
|
28294
28762
|
kind: topic2.kind ?? null,
|
|
28295
28763
|
createdAt: now,
|
|
28296
28764
|
updatedAt: now
|
|
@@ -31652,16 +32120,16 @@ var ZipProcessor = class {
|
|
|
31652
32120
|
try {
|
|
31653
32121
|
const arrayBuffer = await dataUrlToArrayBuffer(file.dataUrl);
|
|
31654
32122
|
const zip = await JSZip.loadAsync(arrayBuffer);
|
|
31655
|
-
const
|
|
32123
|
+
const entries2 = [];
|
|
31656
32124
|
const processedContents = [];
|
|
31657
32125
|
zip.forEach((relativePath, zipEntry) => {
|
|
31658
|
-
|
|
32126
|
+
entries2.push({
|
|
31659
32127
|
path: relativePath,
|
|
31660
32128
|
isDirectory: zipEntry.dir,
|
|
31661
32129
|
zipObject: zipEntry
|
|
31662
32130
|
});
|
|
31663
32131
|
});
|
|
31664
|
-
const visibleEntries = this.includeHidden ?
|
|
32132
|
+
const visibleEntries = this.includeHidden ? entries2 : entries2.filter((entry) => !this.isHidden(entry.path));
|
|
31665
32133
|
visibleEntries.sort((a, b) => {
|
|
31666
32134
|
if (a.isDirectory !== b.isDirectory) {
|
|
31667
32135
|
return a.isDirectory ? -1 : 1;
|
|
@@ -31775,17 +32243,17 @@ var ZipProcessor = class {
|
|
|
31775
32243
|
/**
|
|
31776
32244
|
* Format the output with file listing and processed contents
|
|
31777
32245
|
*/
|
|
31778
|
-
formatOutput(
|
|
32246
|
+
formatOutput(entries2, processedContents) {
|
|
31779
32247
|
const lines = [];
|
|
31780
32248
|
lines.push("## Archive Contents\n");
|
|
31781
32249
|
lines.push("```");
|
|
31782
|
-
for (const entry of
|
|
32250
|
+
for (const entry of entries2) {
|
|
31783
32251
|
const icon = entry.isDirectory ? "\u{1F4C1}" : "\u{1F4C4}";
|
|
31784
32252
|
lines.push(`${icon} ${entry.path}`);
|
|
31785
32253
|
}
|
|
31786
32254
|
lines.push("```\n");
|
|
31787
|
-
const fileCount =
|
|
31788
|
-
const dirCount =
|
|
32255
|
+
const fileCount = entries2.filter((e) => !e.isDirectory).length;
|
|
32256
|
+
const dirCount = entries2.filter((e) => e.isDirectory).length;
|
|
31789
32257
|
lines.push(
|
|
31790
32258
|
`**Summary:** ${fileCount} file${fileCount !== 1 ? "s" : ""}, ${dirCount} director${dirCount !== 1 ? "ies" : "y"}
|
|
31791
32259
|
`
|
|
@@ -32968,13 +33436,13 @@ function serializeInline(node) {
|
|
|
32968
33436
|
function openTag(node, indent, depth, selfClose, maxLineWidth) {
|
|
32969
33437
|
const head = `<${tagName(node.tag)}`;
|
|
32970
33438
|
const tail = selfClose ? " />" : ">";
|
|
32971
|
-
const
|
|
32972
|
-
if (
|
|
32973
|
-
const single = `${head} ${
|
|
33439
|
+
const entries2 = Object.entries(node.attrs);
|
|
33440
|
+
if (entries2.length === 0) return `${head}${tail}`;
|
|
33441
|
+
const single = `${head} ${entries2.map(([k, v]) => formatAttr(k, v)).join(" ")}${tail}`;
|
|
32974
33442
|
if (single.length <= maxLineWidth) return single;
|
|
32975
33443
|
const attrPad = indent.repeat(depth + 1);
|
|
32976
33444
|
const closePad = indent.repeat(depth);
|
|
32977
|
-
const body =
|
|
33445
|
+
const body = entries2.map(([k, v]) => `${attrPad}${formatAttr(k, v)}`).join("\n");
|
|
32978
33446
|
return `${head}
|
|
32979
33447
|
${body}
|
|
32980
33448
|
${closePad}${selfClose ? "/>" : ">"}`;
|
|
@@ -32986,13 +33454,13 @@ function formatAttr(name, value) {
|
|
|
32986
33454
|
return `${name}={${formatObjectAttr(value)}}`;
|
|
32987
33455
|
}
|
|
32988
33456
|
function formatObjectAttr(obj) {
|
|
32989
|
-
const
|
|
33457
|
+
const entries2 = Object.entries(obj).map(([k, v]) => {
|
|
32990
33458
|
const key3 = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k) ? k : JSON.stringify(k);
|
|
32991
33459
|
if (typeof v === "string") return `${key3}: ${JSON.stringify(v)}`;
|
|
32992
33460
|
if (typeof v === "number") return `${key3}: ${String(v)}`;
|
|
32993
33461
|
return `${key3}: ${v ? "true" : "false"}`;
|
|
32994
33462
|
});
|
|
32995
|
-
return `{ ${
|
|
33463
|
+
return `{ ${entries2.join(", ")} }`;
|
|
32996
33464
|
}
|
|
32997
33465
|
function isSafeJsxText(text16) {
|
|
32998
33466
|
if (/[<>{}&]/.test(text16)) return false;
|
|
@@ -33957,6 +34425,12 @@ function cx(...classes) {
|
|
|
33957
34425
|
return classes.filter(Boolean).join(" ");
|
|
33958
34426
|
}
|
|
33959
34427
|
var THEMES = { light: "", dark: ".dark" };
|
|
34428
|
+
var SAFE_CSS_KEY = /^[\w-]+$/;
|
|
34429
|
+
var SAFE_CSS_COLOR = /^(?:#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|[a-z]+|(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch)\([\w\s.,%/+-]*\)|var\(--[\w-]+\))$/i;
|
|
34430
|
+
function isSafeCssColor(value) {
|
|
34431
|
+
if (typeof value !== "string" || !SAFE_CSS_COLOR.test(value)) return false;
|
|
34432
|
+
return typeof CSS === "undefined" || typeof CSS.supports !== "function" || CSS.supports("color", value);
|
|
34433
|
+
}
|
|
33960
34434
|
var ChartContext = React2.createContext(null);
|
|
33961
34435
|
function useChart() {
|
|
33962
34436
|
const context = React2.useContext(ChartContext);
|
|
@@ -33966,7 +34440,9 @@ function useChart() {
|
|
|
33966
34440
|
return context;
|
|
33967
34441
|
}
|
|
33968
34442
|
function ChartStyle({ id: id2, config }) {
|
|
33969
|
-
const colorConfig = Object.entries(config).filter(
|
|
34443
|
+
const colorConfig = Object.entries(config).filter(
|
|
34444
|
+
([key3, cfg]) => SAFE_CSS_KEY.test(key3) && (cfg.theme || cfg.color)
|
|
34445
|
+
);
|
|
33970
34446
|
if (!colorConfig.length) return null;
|
|
33971
34447
|
return /* @__PURE__ */ jsx2(
|
|
33972
34448
|
"style",
|
|
@@ -33977,7 +34453,7 @@ function ChartStyle({ id: id2, config }) {
|
|
|
33977
34453
|
${prefix} [data-chart=${id2}] {
|
|
33978
34454
|
${colorConfig.map(([key3, itemConfig]) => {
|
|
33979
34455
|
const color = itemConfig.theme?.[theme] || itemConfig.color;
|
|
33980
|
-
return color ? ` --color-${key3}: ${color};` : null;
|
|
34456
|
+
return isSafeCssColor(color) ? ` --color-${key3}: ${color};` : null;
|
|
33981
34457
|
}).join("\n")}
|
|
33982
34458
|
}
|
|
33983
34459
|
`
|
|
@@ -34166,12 +34642,37 @@ var DEFAULT_COLORS = [
|
|
|
34166
34642
|
"var(--chart-4)",
|
|
34167
34643
|
"var(--chart-5)"
|
|
34168
34644
|
];
|
|
34645
|
+
function paletteColor(index) {
|
|
34646
|
+
return index < DEFAULT_COLORS.length ? DEFAULT_COLORS[index] : `hsl(${Math.round(index * 137.508 % 360)} 65% 55%)`;
|
|
34647
|
+
}
|
|
34648
|
+
var compactNumber = new Intl.NumberFormat(void 0, {
|
|
34649
|
+
notation: "compact",
|
|
34650
|
+
maximumSignificantDigits: 3
|
|
34651
|
+
});
|
|
34652
|
+
function cellText(value) {
|
|
34653
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : "";
|
|
34654
|
+
}
|
|
34655
|
+
function formatTick(value) {
|
|
34656
|
+
return typeof value === "number" ? compactNumber.format(value) : String(value);
|
|
34657
|
+
}
|
|
34658
|
+
var VISUALLY_HIDDEN = {
|
|
34659
|
+
position: "absolute",
|
|
34660
|
+
width: 1,
|
|
34661
|
+
height: 1,
|
|
34662
|
+
padding: 0,
|
|
34663
|
+
margin: -1,
|
|
34664
|
+
overflow: "hidden",
|
|
34665
|
+
clip: "rect(0, 0, 0, 0)",
|
|
34666
|
+
whiteSpace: "nowrap",
|
|
34667
|
+
border: 0
|
|
34668
|
+
};
|
|
34169
34669
|
function buildChartConfig(dataKeys, colors) {
|
|
34170
34670
|
const config = {};
|
|
34171
34671
|
dataKeys.forEach((key3, i) => {
|
|
34672
|
+
const custom = colors?.[key3];
|
|
34172
34673
|
config[key3] = {
|
|
34173
34674
|
label: key3.charAt(0).toUpperCase() + key3.slice(1),
|
|
34174
|
-
color:
|
|
34675
|
+
color: isSafeCssColor(custom) ? custom : paletteColor(i)
|
|
34175
34676
|
};
|
|
34176
34677
|
});
|
|
34177
34678
|
return config;
|
|
@@ -34184,68 +34685,106 @@ function ChartCard({ data }) {
|
|
|
34184
34685
|
return () => cancelAnimationFrame(frame);
|
|
34185
34686
|
}, []);
|
|
34186
34687
|
if ("error" in data) {
|
|
34187
|
-
return /* @__PURE__ */ jsx2("div", { className: "my-4 max-w-lg", children: /* @__PURE__ */ jsx2("div", { className: "rounded-xl bg-sidebar dark:bg-card px-4 py-3", children: /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground", children:
|
|
34688
|
+
return /* @__PURE__ */ jsx2("div", { className: "my-4 max-w-lg", children: /* @__PURE__ */ jsx2("div", { className: "rounded-xl bg-sidebar dark:bg-card px-4 py-3", children: /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground", children: "Couldn't display this chart." }) }) });
|
|
34188
34689
|
}
|
|
34189
34690
|
const { chartType, title, data: chartData, dataKeys, xAxisKey, colors } = data;
|
|
34190
34691
|
const chartConfig = buildChartConfig(dataKeys, colors);
|
|
34191
|
-
|
|
34192
|
-
|
|
34193
|
-
|
|
34194
|
-
|
|
34195
|
-
|
|
34196
|
-
|
|
34197
|
-
|
|
34198
|
-
|
|
34199
|
-
|
|
34200
|
-
|
|
34201
|
-
|
|
34202
|
-
|
|
34203
|
-
|
|
34204
|
-
|
|
34205
|
-
|
|
34206
|
-
|
|
34207
|
-
|
|
34208
|
-
|
|
34209
|
-
|
|
34210
|
-
|
|
34211
|
-
|
|
34212
|
-
|
|
34213
|
-
|
|
34214
|
-
|
|
34215
|
-
|
|
34216
|
-
|
|
34217
|
-
|
|
34218
|
-
|
|
34219
|
-
|
|
34220
|
-
|
|
34221
|
-
|
|
34222
|
-
|
|
34223
|
-
|
|
34224
|
-
|
|
34225
|
-
|
|
34226
|
-
|
|
34227
|
-
|
|
34228
|
-
|
|
34229
|
-
|
|
34230
|
-
|
|
34231
|
-
|
|
34232
|
-
|
|
34233
|
-
|
|
34234
|
-
|
|
34235
|
-
|
|
34236
|
-
|
|
34237
|
-
|
|
34238
|
-
|
|
34239
|
-
|
|
34240
|
-
|
|
34241
|
-
|
|
34242
|
-
|
|
34243
|
-
|
|
34244
|
-
|
|
34245
|
-
|
|
34246
|
-
|
|
34247
|
-
|
|
34248
|
-
|
|
34692
|
+
const seriesColor = (key3) => chartConfig[key3]?.color;
|
|
34693
|
+
const longestTick = chartData.reduce(
|
|
34694
|
+
(longest, point) => dataKeys.reduce((max, key3) => {
|
|
34695
|
+
const value = point[key3];
|
|
34696
|
+
return typeof value === "number" ? Math.max(max, formatTick(value).length) : max;
|
|
34697
|
+
}, longest),
|
|
34698
|
+
0
|
|
34699
|
+
);
|
|
34700
|
+
const yAxisProps = {
|
|
34701
|
+
tickLine: false,
|
|
34702
|
+
axisLine: false,
|
|
34703
|
+
tickFormatter: formatTick,
|
|
34704
|
+
width: Math.min(120, Math.max(40, longestTick * 7 + 16))
|
|
34705
|
+
};
|
|
34706
|
+
const labelKey = chartType === "pie" ? xAxisKey || "name" : xAxisKey;
|
|
34707
|
+
const valueKeys = chartType === "pie" ? dataKeys.slice(0, 1) : dataKeys;
|
|
34708
|
+
const tableColumns = labelKey ? [labelKey, ...valueKeys] : valueKeys;
|
|
34709
|
+
return /* @__PURE__ */ jsx2(
|
|
34710
|
+
"div",
|
|
34711
|
+
{
|
|
34712
|
+
className: "my-4 max-w-lg",
|
|
34713
|
+
ref: containerRef,
|
|
34714
|
+
role: "figure",
|
|
34715
|
+
"aria-label": [title, `${chartType} chart`].filter(Boolean).join(", "),
|
|
34716
|
+
children: /* @__PURE__ */ jsxs("div", { className: "rounded-xl bg-sidebar dark:bg-card px-5 py-4", children: [
|
|
34717
|
+
title && /* @__PURE__ */ jsx2("p", { className: "text-sm font-medium mb-3", children: title }),
|
|
34718
|
+
/* @__PURE__ */ jsxs("table", { style: VISUALLY_HIDDEN, children: [
|
|
34719
|
+
/* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { children: tableColumns.map((column) => /* @__PURE__ */ jsx2("th", { scope: "col", children: column }, column)) }) }),
|
|
34720
|
+
/* @__PURE__ */ jsx2("tbody", { children: chartData.map((point, row) => /* @__PURE__ */ jsx2("tr", { children: tableColumns.map((column) => /* @__PURE__ */ jsx2("td", { children: cellText(point[column]) }, column)) }, row)) })
|
|
34721
|
+
] }),
|
|
34722
|
+
ready ? /* @__PURE__ */ jsx2(
|
|
34723
|
+
ChartContainer,
|
|
34724
|
+
{
|
|
34725
|
+
config: chartConfig,
|
|
34726
|
+
className: "aspect-auto h-[250px] w-full",
|
|
34727
|
+
"aria-hidden": "true",
|
|
34728
|
+
children: chartType === "bar" ? /* @__PURE__ */ jsxs(BarChart, { data: chartData, children: [
|
|
34729
|
+
/* @__PURE__ */ jsx2(CartesianGrid, { vertical: false }),
|
|
34730
|
+
xAxisKey && /* @__PURE__ */ jsx2(XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
|
|
34731
|
+
/* @__PURE__ */ jsx2(YAxis, { ...yAxisProps }),
|
|
34732
|
+
/* @__PURE__ */ jsx2(ChartTooltip, { content: /* @__PURE__ */ jsx2(ChartTooltipContent, {}) }),
|
|
34733
|
+
dataKeys.length > 1 && /* @__PURE__ */ jsx2(ChartLegend, { content: /* @__PURE__ */ jsx2(ChartLegendContent, {}) }),
|
|
34734
|
+
dataKeys.map((key3) => /* @__PURE__ */ jsx2(Bar, { dataKey: key3, fill: seriesColor(key3), radius: 4 }, key3))
|
|
34735
|
+
] }) : chartType === "line" ? /* @__PURE__ */ jsxs(LineChart, { data: chartData, children: [
|
|
34736
|
+
/* @__PURE__ */ jsx2(CartesianGrid, { vertical: false }),
|
|
34737
|
+
xAxisKey && /* @__PURE__ */ jsx2(XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
|
|
34738
|
+
/* @__PURE__ */ jsx2(YAxis, { ...yAxisProps }),
|
|
34739
|
+
/* @__PURE__ */ jsx2(ChartTooltip, { content: /* @__PURE__ */ jsx2(ChartTooltipContent, {}) }),
|
|
34740
|
+
dataKeys.length > 1 && /* @__PURE__ */ jsx2(ChartLegend, { content: /* @__PURE__ */ jsx2(ChartLegendContent, {}) }),
|
|
34741
|
+
dataKeys.map((key3) => /* @__PURE__ */ jsx2(
|
|
34742
|
+
Line2,
|
|
34743
|
+
{
|
|
34744
|
+
dataKey: key3,
|
|
34745
|
+
stroke: seriesColor(key3),
|
|
34746
|
+
strokeWidth: 2,
|
|
34747
|
+
dot: false
|
|
34748
|
+
},
|
|
34749
|
+
key3
|
|
34750
|
+
))
|
|
34751
|
+
] }) : chartType === "area" ? /* @__PURE__ */ jsxs(AreaChart, { data: chartData, children: [
|
|
34752
|
+
/* @__PURE__ */ jsx2(CartesianGrid, { vertical: false }),
|
|
34753
|
+
xAxisKey && /* @__PURE__ */ jsx2(XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
|
|
34754
|
+
/* @__PURE__ */ jsx2(YAxis, { ...yAxisProps }),
|
|
34755
|
+
/* @__PURE__ */ jsx2(ChartTooltip, { content: /* @__PURE__ */ jsx2(ChartTooltipContent, {}) }),
|
|
34756
|
+
dataKeys.length > 1 && /* @__PURE__ */ jsx2(ChartLegend, { content: /* @__PURE__ */ jsx2(ChartLegendContent, {}) }),
|
|
34757
|
+
dataKeys.map((key3) => /* @__PURE__ */ jsx2(
|
|
34758
|
+
Area,
|
|
34759
|
+
{
|
|
34760
|
+
dataKey: key3,
|
|
34761
|
+
fill: seriesColor(key3),
|
|
34762
|
+
stroke: seriesColor(key3),
|
|
34763
|
+
fillOpacity: 0.3
|
|
34764
|
+
},
|
|
34765
|
+
key3
|
|
34766
|
+
))
|
|
34767
|
+
] }) : /* @__PURE__ */ jsxs(PieChart, { children: [
|
|
34768
|
+
/* @__PURE__ */ jsx2(ChartTooltip, { content: /* @__PURE__ */ jsx2(ChartTooltipContent, {}) }),
|
|
34769
|
+
/* @__PURE__ */ jsx2(
|
|
34770
|
+
Pie,
|
|
34771
|
+
{
|
|
34772
|
+
data: chartData,
|
|
34773
|
+
dataKey: dataKeys[0],
|
|
34774
|
+
nameKey: xAxisKey || "name",
|
|
34775
|
+
cx: "50%",
|
|
34776
|
+
cy: "50%",
|
|
34777
|
+
outerRadius: 80,
|
|
34778
|
+
children: chartData.map((_, index) => /* @__PURE__ */ jsx2(Cell, { fill: paletteColor(index) }, index))
|
|
34779
|
+
}
|
|
34780
|
+
),
|
|
34781
|
+
/* @__PURE__ */ jsx2(ChartLegend, { content: /* @__PURE__ */ jsx2(ChartLegendContent, { nameKey: xAxisKey || "name" }) })
|
|
34782
|
+
] })
|
|
34783
|
+
}
|
|
34784
|
+
) : /* @__PURE__ */ jsx2("div", { className: "h-[250px] w-full" })
|
|
34785
|
+
] })
|
|
34786
|
+
}
|
|
34787
|
+
);
|
|
34249
34788
|
}
|
|
34250
34789
|
|
|
34251
34790
|
// src/react/LoggerProvider.tsx
|
|
@@ -34390,7 +34929,7 @@ async function uploadFileToICloud(filename, content, backupRevision) {
|
|
|
34390
34929
|
const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
34391
34930
|
const arrayBuffer = await content.arrayBuffer();
|
|
34392
34931
|
const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
|
|
34393
|
-
const
|
|
34932
|
+
const record3 = {
|
|
34394
34933
|
recordType: RECORD_TYPE,
|
|
34395
34934
|
recordName,
|
|
34396
34935
|
fields: {
|
|
@@ -34401,7 +34940,7 @@ async function uploadFileToICloud(filename, content, backupRevision) {
|
|
|
34401
34940
|
...backupRevision ? { backupRevision: { value: backupRevision } } : {}
|
|
34402
34941
|
}
|
|
34403
34942
|
};
|
|
34404
|
-
const response = await database.saveRecords(
|
|
34943
|
+
const response = await database.saveRecords(record3);
|
|
34405
34944
|
if (!response.records || response.records.length === 0) {
|
|
34406
34945
|
throw new Error("Failed to upload file to iCloud");
|
|
34407
34946
|
}
|
|
@@ -34428,12 +34967,12 @@ async function listICloudFiles() {
|
|
|
34428
34967
|
while (response.continuationMarker) {
|
|
34429
34968
|
break;
|
|
34430
34969
|
}
|
|
34431
|
-
const files = allRecords.map((
|
|
34432
|
-
recordName:
|
|
34433
|
-
filename:
|
|
34434
|
-
modifiedAt: new Date(
|
|
34435
|
-
backupRevision:
|
|
34436
|
-
size: typeof
|
|
34970
|
+
const files = allRecords.map((record3) => ({
|
|
34971
|
+
recordName: record3.recordName,
|
|
34972
|
+
filename: record3.fields.filename?.value ?? "",
|
|
34973
|
+
modifiedAt: new Date(record3.modified?.timestamp ?? Date.now()),
|
|
34974
|
+
backupRevision: record3.fields.backupRevision?.value,
|
|
34975
|
+
size: typeof record3.fields.data?.value === "object" && record3.fields.data?.value !== null ? record3.fields.data.value.size : 0
|
|
34437
34976
|
}));
|
|
34438
34977
|
return files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
|
|
34439
34978
|
}
|
|
@@ -34446,8 +34985,8 @@ async function downloadICloudFile(recordName) {
|
|
|
34446
34985
|
if (!response.records || response.records.length === 0) {
|
|
34447
34986
|
throw new Error(`File not found: ${recordName}`);
|
|
34448
34987
|
}
|
|
34449
|
-
const
|
|
34450
|
-
const dataField =
|
|
34988
|
+
const record3 = response.records[0];
|
|
34989
|
+
const dataField = record3.fields.data?.value;
|
|
34451
34990
|
if (!dataField) {
|
|
34452
34991
|
throw new Error("No data in record");
|
|
34453
34992
|
}
|
|
@@ -34481,13 +35020,13 @@ async function findICloudFile(filename) {
|
|
|
34481
35020
|
if (!response.records || response.records.length === 0) {
|
|
34482
35021
|
return null;
|
|
34483
35022
|
}
|
|
34484
|
-
const
|
|
35023
|
+
const record3 = response.records[0];
|
|
34485
35024
|
return {
|
|
34486
|
-
recordName:
|
|
34487
|
-
filename:
|
|
34488
|
-
modifiedAt: new Date(
|
|
34489
|
-
backupRevision:
|
|
34490
|
-
size: typeof
|
|
35025
|
+
recordName: record3.recordName,
|
|
35026
|
+
filename: record3.fields.filename?.value ?? "",
|
|
35027
|
+
modifiedAt: new Date(record3.modified?.timestamp ?? Date.now()),
|
|
35028
|
+
backupRevision: record3.fields.backupRevision?.value,
|
|
35029
|
+
size: typeof record3.fields.data?.value === "object" && record3.fields.data?.value !== null ? record3.fields.data.value.size : 0
|
|
34491
35030
|
};
|
|
34492
35031
|
}
|
|
34493
35032
|
|
|
@@ -35837,13 +36376,13 @@ function useConversationRedactors(database, account, storage, secondaryStorage)
|
|
|
35837
36376
|
return useCallback4(
|
|
35838
36377
|
(conversationId, nerDetector) => {
|
|
35839
36378
|
if (!scope.active) return retiredRedactor;
|
|
35840
|
-
const
|
|
35841
|
-
if (
|
|
36379
|
+
const cached2 = scope.redactors.get(conversationId);
|
|
36380
|
+
if (cached2 && cached2.detector === nerDetector) {
|
|
35842
36381
|
scope.redactors.delete(conversationId);
|
|
35843
|
-
scope.redactors.set(conversationId,
|
|
35844
|
-
return
|
|
36382
|
+
scope.redactors.set(conversationId, cached2);
|
|
36383
|
+
return cached2.redactor;
|
|
35845
36384
|
}
|
|
35846
|
-
if (
|
|
36385
|
+
if (cached2) scope.evicted.push(cached2.redactor);
|
|
35847
36386
|
const redactor = new PiiRedactor({ nerDetector });
|
|
35848
36387
|
scope.redactors.set(conversationId, { redactor, detector: nerDetector });
|
|
35849
36388
|
if (scope.redactors.size > REDACTOR_LIMIT) {
|
|
@@ -39338,11 +39877,11 @@ async function fetchAllModelPages(baseUrl, provider, headers, previous, signal)
|
|
|
39338
39877
|
return { pages, models, fetchedAt: Date.now() };
|
|
39339
39878
|
}
|
|
39340
39879
|
function loadModels(key3, baseUrl, provider, headers, force, signal) {
|
|
39341
|
-
const
|
|
39342
|
-
if (
|
|
39343
|
-
return Promise.resolve([...
|
|
39880
|
+
const cached2 = modelsCache.get(key3);
|
|
39881
|
+
if (cached2 && !force && Date.now() - cached2.fetchedAt < MODELS_CACHE_TTL_MS) {
|
|
39882
|
+
return Promise.resolve([...cached2.models]);
|
|
39344
39883
|
}
|
|
39345
|
-
const shared = (force ? void 0 : modelsInFlight.get(key3)) ?? startSharedRequest(key3, baseUrl, provider, headers,
|
|
39884
|
+
const shared = (force ? void 0 : modelsInFlight.get(key3)) ?? startSharedRequest(key3, baseUrl, provider, headers, cached2);
|
|
39346
39885
|
return waitForSharedRequest(key3, shared, signal).then((models) => [...models]);
|
|
39347
39886
|
}
|
|
39348
39887
|
function startSharedRequest(key3, baseUrl, provider, headers, previous) {
|
|
@@ -40195,20 +40734,20 @@ function startObserve(entry, walletAddress) {
|
|
|
40195
40734
|
"updated_at"
|
|
40196
40735
|
]).subscribe({
|
|
40197
40736
|
next: (records) => {
|
|
40198
|
-
const
|
|
40199
|
-
if (!
|
|
40737
|
+
const record3 = records[0];
|
|
40738
|
+
if (!record3) return;
|
|
40200
40739
|
const patch = {
|
|
40201
40740
|
userPreference: {
|
|
40202
|
-
uniqueId:
|
|
40203
|
-
walletAddress:
|
|
40204
|
-
nickname:
|
|
40205
|
-
occupation:
|
|
40206
|
-
description:
|
|
40207
|
-
models:
|
|
40208
|
-
personality:
|
|
40209
|
-
externalWallets:
|
|
40210
|
-
createdAt:
|
|
40211
|
-
updatedAt:
|
|
40741
|
+
uniqueId: record3.id,
|
|
40742
|
+
walletAddress: record3.walletAddress,
|
|
40743
|
+
nickname: record3.nickname,
|
|
40744
|
+
occupation: record3.occupation,
|
|
40745
|
+
description: record3.description,
|
|
40746
|
+
models: record3.models,
|
|
40747
|
+
personality: record3.personality,
|
|
40748
|
+
externalWallets: record3.externalWallets,
|
|
40749
|
+
createdAt: record3.createdAt,
|
|
40750
|
+
updatedAt: record3.updatedAt
|
|
40212
40751
|
}
|
|
40213
40752
|
};
|
|
40214
40753
|
if (isInitialEmission) {
|