@reverbia/sdk 1.0.0-next.20260110155148 → 1.0.0-next.20260110210906
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/react/index.cjs +389 -16
- package/dist/react/index.d.mts +100 -1
- package/dist/react/index.d.ts +100 -1
- package/dist/react/index.mjs +415 -49
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -42,6 +42,7 @@ __export(index_exports, {
|
|
|
42
42
|
BACKUP_DRIVE_ROOT_FOLDER: () => DEFAULT_ROOT_FOLDER,
|
|
43
43
|
BACKUP_ICLOUD_FOLDER: () => DEFAULT_BACKUP_FOLDER2,
|
|
44
44
|
BackupAuthProvider: () => BackupAuthProvider,
|
|
45
|
+
BlobUrlManager: () => BlobUrlManager,
|
|
45
46
|
ChatConversation: () => Conversation,
|
|
46
47
|
ChatMessage: () => Message,
|
|
47
48
|
DEFAULT_BACKUP_FOLDER: () => DEFAULT_BACKUP_FOLDER,
|
|
@@ -71,9 +72,11 @@ __export(index_exports, {
|
|
|
71
72
|
createMemoryContextSystemMessage: () => createMemoryContextSystemMessage,
|
|
72
73
|
decryptData: () => decryptData,
|
|
73
74
|
decryptDataBytes: () => decryptDataBytes,
|
|
75
|
+
deleteEncryptedFile: () => deleteEncryptedFile,
|
|
74
76
|
encryptData: () => encryptData,
|
|
75
77
|
exportPublicKey: () => exportPublicKey,
|
|
76
78
|
extractConversationContext: () => extractConversationContext,
|
|
79
|
+
fileExists: () => fileExists,
|
|
77
80
|
findFileIdBySourceUrl: () => findFileIdBySourceUrl,
|
|
78
81
|
formatMemoriesForChat: () => formatMemoriesForChat,
|
|
79
82
|
generateCompositeKey: () => generateCompositeKey,
|
|
@@ -85,6 +88,7 @@ __export(index_exports, {
|
|
|
85
88
|
getAndClearDriveReturnUrl: () => getAndClearDriveReturnUrl,
|
|
86
89
|
getCalendarAccessToken: () => getCalendarAccessToken,
|
|
87
90
|
getDriveAccessToken: () => getDriveAccessToken,
|
|
91
|
+
getEncryptionKey: () => getEncryptionKey,
|
|
88
92
|
getGoogleDriveStoredToken: () => getGoogleDriveStoredToken,
|
|
89
93
|
getValidCalendarToken: () => getValidCalendarToken,
|
|
90
94
|
getValidDriveToken: () => getValidDriveToken,
|
|
@@ -99,7 +103,9 @@ __export(index_exports, {
|
|
|
99
103
|
hasKeyPair: () => hasKeyPair,
|
|
100
104
|
isCalendarCallback: () => isCalendarCallback,
|
|
101
105
|
isDriveCallback: () => isDriveCallback,
|
|
106
|
+
isOPFSSupported: () => isOPFSSupported,
|
|
102
107
|
memoryStorageSchema: () => memoryStorageSchema,
|
|
108
|
+
readEncryptedFile: () => readEncryptedFile,
|
|
103
109
|
refreshCalendarToken: () => refreshCalendarToken,
|
|
104
110
|
refreshDriveToken: () => refreshDriveToken,
|
|
105
111
|
replaceUrlWithMCPPlaceholder: () => replaceUrlWithMCPPlaceholder,
|
|
@@ -137,7 +143,8 @@ __export(index_exports, {
|
|
|
137
143
|
usePdf: () => usePdf,
|
|
138
144
|
useSearch: () => useSearch,
|
|
139
145
|
useSettings: () => useSettings,
|
|
140
|
-
userPreferencesStorageSchema: () => userPreferencesStorageSchema
|
|
146
|
+
userPreferencesStorageSchema: () => userPreferencesStorageSchema,
|
|
147
|
+
writeEncryptedFile: () => writeEncryptedFile
|
|
141
148
|
});
|
|
142
149
|
module.exports = __toCommonJS(index_exports);
|
|
143
150
|
|
|
@@ -2829,6 +2836,178 @@ async function searchMessagesOp(ctx, queryVector, options) {
|
|
|
2829
2836
|
return resultsWithSimilarity.sort((a, b) => b.similarity - a.similarity).slice(0, limit);
|
|
2830
2837
|
}
|
|
2831
2838
|
|
|
2839
|
+
// src/lib/storage/opfs.ts
|
|
2840
|
+
var FILE_PLACEHOLDER_PREFIX = "__SDKFILE__";
|
|
2841
|
+
var FILE_PLACEHOLDER_SUFFIX = "__";
|
|
2842
|
+
var FILE_PLACEHOLDER_REGEX = /__SDKFILE__([a-f0-9-]+)__/g;
|
|
2843
|
+
function createFilePlaceholder(fileId) {
|
|
2844
|
+
return `${FILE_PLACEHOLDER_PREFIX}${fileId}${FILE_PLACEHOLDER_SUFFIX}`;
|
|
2845
|
+
}
|
|
2846
|
+
function extractFileIds(content) {
|
|
2847
|
+
const matches = content.matchAll(FILE_PLACEHOLDER_REGEX);
|
|
2848
|
+
return Array.from(matches, (m) => m[1]);
|
|
2849
|
+
}
|
|
2850
|
+
function isOPFSSupported() {
|
|
2851
|
+
return typeof navigator !== "undefined" && "storage" in navigator && "getDirectory" in navigator.storage;
|
|
2852
|
+
}
|
|
2853
|
+
async function getSDKDirectory() {
|
|
2854
|
+
const root = await navigator.storage.getDirectory();
|
|
2855
|
+
return root.getDirectoryHandle("reverbia-sdk-files", { create: true });
|
|
2856
|
+
}
|
|
2857
|
+
function bytesToHex2(bytes) {
|
|
2858
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
2859
|
+
}
|
|
2860
|
+
function hexToBytes2(hex) {
|
|
2861
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
2862
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
2863
|
+
bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
|
|
2864
|
+
}
|
|
2865
|
+
return bytes;
|
|
2866
|
+
}
|
|
2867
|
+
async function encryptBlob(blob, encryptionKey) {
|
|
2868
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
2869
|
+
const plaintext = new Uint8Array(arrayBuffer);
|
|
2870
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
2871
|
+
const ciphertext = await crypto.subtle.encrypt(
|
|
2872
|
+
{ name: "AES-GCM", iv },
|
|
2873
|
+
encryptionKey,
|
|
2874
|
+
plaintext
|
|
2875
|
+
);
|
|
2876
|
+
const combined = new Uint8Array(iv.length + ciphertext.byteLength);
|
|
2877
|
+
combined.set(iv, 0);
|
|
2878
|
+
combined.set(new Uint8Array(ciphertext), iv.length);
|
|
2879
|
+
return bytesToHex2(combined);
|
|
2880
|
+
}
|
|
2881
|
+
async function decryptToBytes(encryptedHex, encryptionKey) {
|
|
2882
|
+
const combined = hexToBytes2(encryptedHex);
|
|
2883
|
+
const iv = combined.slice(0, 12);
|
|
2884
|
+
const ciphertext = combined.slice(12);
|
|
2885
|
+
const decrypted = await crypto.subtle.decrypt(
|
|
2886
|
+
{ name: "AES-GCM", iv },
|
|
2887
|
+
encryptionKey,
|
|
2888
|
+
ciphertext
|
|
2889
|
+
);
|
|
2890
|
+
return new Uint8Array(decrypted);
|
|
2891
|
+
}
|
|
2892
|
+
async function writeEncryptedFile(fileId, blob, encryptionKey, metadata) {
|
|
2893
|
+
if (!isOPFSSupported()) {
|
|
2894
|
+
throw new Error("OPFS is not supported in this browser");
|
|
2895
|
+
}
|
|
2896
|
+
const dir = await getSDKDirectory();
|
|
2897
|
+
const encryptedHex = await encryptBlob(blob, encryptionKey);
|
|
2898
|
+
const contentHandle = await dir.getFileHandle(`${fileId}.enc`, {
|
|
2899
|
+
create: true
|
|
2900
|
+
});
|
|
2901
|
+
const contentWritable = await contentHandle.createWritable();
|
|
2902
|
+
await contentWritable.write(encryptedHex);
|
|
2903
|
+
await contentWritable.close();
|
|
2904
|
+
const fileMetadata = {
|
|
2905
|
+
id: fileId,
|
|
2906
|
+
name: metadata?.name || `file-${fileId}`,
|
|
2907
|
+
type: blob.type || "application/octet-stream",
|
|
2908
|
+
size: blob.size,
|
|
2909
|
+
sourceUrl: metadata?.sourceUrl,
|
|
2910
|
+
createdAt: Date.now()
|
|
2911
|
+
};
|
|
2912
|
+
const metaHandle = await dir.getFileHandle(`${fileId}.meta.json`, {
|
|
2913
|
+
create: true
|
|
2914
|
+
});
|
|
2915
|
+
const metaWritable = await metaHandle.createWritable();
|
|
2916
|
+
await metaWritable.write(JSON.stringify(fileMetadata));
|
|
2917
|
+
await metaWritable.close();
|
|
2918
|
+
}
|
|
2919
|
+
async function readEncryptedFile(fileId, encryptionKey) {
|
|
2920
|
+
if (!isOPFSSupported()) {
|
|
2921
|
+
throw new Error("OPFS is not supported in this browser");
|
|
2922
|
+
}
|
|
2923
|
+
const dir = await getSDKDirectory();
|
|
2924
|
+
try {
|
|
2925
|
+
const contentHandle = await dir.getFileHandle(`${fileId}.enc`);
|
|
2926
|
+
const contentFile = await contentHandle.getFile();
|
|
2927
|
+
const encryptedHex = await contentFile.text();
|
|
2928
|
+
const metaHandle = await dir.getFileHandle(`${fileId}.meta.json`);
|
|
2929
|
+
const metaFile = await metaHandle.getFile();
|
|
2930
|
+
const metadata = JSON.parse(await metaFile.text());
|
|
2931
|
+
const decryptedBytes = await decryptToBytes(encryptedHex, encryptionKey);
|
|
2932
|
+
const blob = new Blob([decryptedBytes.buffer], { type: metadata.type });
|
|
2933
|
+
return { blob, metadata };
|
|
2934
|
+
} catch (error) {
|
|
2935
|
+
if (error instanceof DOMException && error.name === "NotFoundError") {
|
|
2936
|
+
return null;
|
|
2937
|
+
}
|
|
2938
|
+
throw error;
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
async function deleteEncryptedFile(fileId) {
|
|
2942
|
+
if (!isOPFSSupported()) {
|
|
2943
|
+
throw new Error("OPFS is not supported in this browser");
|
|
2944
|
+
}
|
|
2945
|
+
const dir = await getSDKDirectory();
|
|
2946
|
+
try {
|
|
2947
|
+
await dir.removeEntry(`${fileId}.enc`);
|
|
2948
|
+
await dir.removeEntry(`${fileId}.meta.json`);
|
|
2949
|
+
} catch {
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
async function fileExists(fileId) {
|
|
2953
|
+
if (!isOPFSSupported()) {
|
|
2954
|
+
return false;
|
|
2955
|
+
}
|
|
2956
|
+
const dir = await getSDKDirectory();
|
|
2957
|
+
try {
|
|
2958
|
+
await dir.getFileHandle(`${fileId}.enc`);
|
|
2959
|
+
return true;
|
|
2960
|
+
} catch {
|
|
2961
|
+
return false;
|
|
2962
|
+
}
|
|
2963
|
+
}
|
|
2964
|
+
var BlobUrlManager = class {
|
|
2965
|
+
constructor() {
|
|
2966
|
+
this.activeUrls = /* @__PURE__ */ new Map();
|
|
2967
|
+
}
|
|
2968
|
+
// fileId -> blobUrl
|
|
2969
|
+
/**
|
|
2970
|
+
* Creates a blob URL for a file and tracks it.
|
|
2971
|
+
*/
|
|
2972
|
+
createUrl(fileId, blob) {
|
|
2973
|
+
this.revokeUrl(fileId);
|
|
2974
|
+
const url = URL.createObjectURL(blob);
|
|
2975
|
+
this.activeUrls.set(fileId, url);
|
|
2976
|
+
return url;
|
|
2977
|
+
}
|
|
2978
|
+
/**
|
|
2979
|
+
* Gets the active blob URL for a file, if any.
|
|
2980
|
+
*/
|
|
2981
|
+
getUrl(fileId) {
|
|
2982
|
+
return this.activeUrls.get(fileId);
|
|
2983
|
+
}
|
|
2984
|
+
/**
|
|
2985
|
+
* Revokes a blob URL and removes it from tracking.
|
|
2986
|
+
*/
|
|
2987
|
+
revokeUrl(fileId) {
|
|
2988
|
+
const url = this.activeUrls.get(fileId);
|
|
2989
|
+
if (url) {
|
|
2990
|
+
URL.revokeObjectURL(url);
|
|
2991
|
+
this.activeUrls.delete(fileId);
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
/**
|
|
2995
|
+
* Revokes all tracked blob URLs.
|
|
2996
|
+
*/
|
|
2997
|
+
revokeAll() {
|
|
2998
|
+
for (const url of this.activeUrls.values()) {
|
|
2999
|
+
URL.revokeObjectURL(url);
|
|
3000
|
+
}
|
|
3001
|
+
this.activeUrls.clear();
|
|
3002
|
+
}
|
|
3003
|
+
/**
|
|
3004
|
+
* Gets the count of active blob URLs.
|
|
3005
|
+
*/
|
|
3006
|
+
get size() {
|
|
3007
|
+
return this.activeUrls.size;
|
|
3008
|
+
}
|
|
3009
|
+
};
|
|
3010
|
+
|
|
2832
3011
|
// src/react/useChatStorage.ts
|
|
2833
3012
|
function replaceUrlWithMCPPlaceholder(content, url, fileId) {
|
|
2834
3013
|
const escapedUrl = url.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -2850,20 +3029,69 @@ function replaceUrlWithMCPPlaceholder(content, url, fileId) {
|
|
|
2850
3029
|
function findFileIdBySourceUrl(files, sourceUrl) {
|
|
2851
3030
|
return files?.find((f) => f.sourceUrl === sourceUrl)?.id;
|
|
2852
3031
|
}
|
|
2853
|
-
function
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
3032
|
+
async function isUrlValid(url, timeoutMs = 5e3) {
|
|
3033
|
+
try {
|
|
3034
|
+
const controller = new AbortController();
|
|
3035
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
3036
|
+
const response = await fetch(url, {
|
|
3037
|
+
method: "GET",
|
|
3038
|
+
headers: { Range: "bytes=0-0" },
|
|
3039
|
+
signal: controller.signal
|
|
3040
|
+
});
|
|
3041
|
+
clearTimeout(timeoutId);
|
|
3042
|
+
return response.ok || response.status === 206;
|
|
3043
|
+
} catch {
|
|
3044
|
+
return false;
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
async function storedToLlmapiMessage(stored) {
|
|
3048
|
+
let textContent = stored.content;
|
|
3049
|
+
const fileUrlMap = /* @__PURE__ */ new Map();
|
|
3050
|
+
const imageParts = [];
|
|
2857
3051
|
if (stored.files?.length) {
|
|
2858
3052
|
for (const file of stored.files) {
|
|
2859
3053
|
if (file.url) {
|
|
2860
|
-
|
|
3054
|
+
imageParts.push({
|
|
2861
3055
|
type: "image_url",
|
|
2862
3056
|
image_url: { url: file.url }
|
|
2863
3057
|
});
|
|
3058
|
+
} else if (file.sourceUrl) {
|
|
3059
|
+
const isValid = await isUrlValid(file.sourceUrl);
|
|
3060
|
+
if (isValid) {
|
|
3061
|
+
imageParts.push({
|
|
3062
|
+
type: "image_url",
|
|
3063
|
+
image_url: { url: file.sourceUrl }
|
|
3064
|
+
});
|
|
3065
|
+
fileUrlMap.set(file.id, file.sourceUrl);
|
|
3066
|
+
}
|
|
2864
3067
|
}
|
|
2865
3068
|
}
|
|
2866
3069
|
}
|
|
3070
|
+
textContent = textContent.replace(
|
|
3071
|
+
/__SDKFILE__([a-f0-9-]+)__/g,
|
|
3072
|
+
(match, fileId) => {
|
|
3073
|
+
const sourceUrl = fileUrlMap.get(fileId);
|
|
3074
|
+
if (sourceUrl) {
|
|
3075
|
+
return ``;
|
|
3076
|
+
}
|
|
3077
|
+
return "";
|
|
3078
|
+
}
|
|
3079
|
+
);
|
|
3080
|
+
textContent = textContent.replace(
|
|
3081
|
+
/!\[MCP_IMAGE:([a-f0-9-]+)\]/g,
|
|
3082
|
+
(match, fileId) => {
|
|
3083
|
+
const sourceUrl = fileUrlMap.get(fileId);
|
|
3084
|
+
if (sourceUrl) {
|
|
3085
|
+
return ``;
|
|
3086
|
+
}
|
|
3087
|
+
return "";
|
|
3088
|
+
}
|
|
3089
|
+
);
|
|
3090
|
+
textContent = textContent.replace(/\n{3,}/g, "\n\n").trim();
|
|
3091
|
+
const content = [
|
|
3092
|
+
{ type: "text", text: textContent },
|
|
3093
|
+
...imageParts
|
|
3094
|
+
];
|
|
2867
3095
|
return {
|
|
2868
3096
|
role: stored.role,
|
|
2869
3097
|
content
|
|
@@ -2880,9 +3108,17 @@ function useChatStorage(options) {
|
|
|
2880
3108
|
onData,
|
|
2881
3109
|
onFinish,
|
|
2882
3110
|
onError,
|
|
2883
|
-
apiType
|
|
3111
|
+
apiType,
|
|
3112
|
+
walletAddress
|
|
2884
3113
|
} = options;
|
|
2885
3114
|
const [currentConversationId, setCurrentConversationId] = (0, import_react2.useState)(initialConversationId || null);
|
|
3115
|
+
const blobManagerRef = (0, import_react2.useRef)(new BlobUrlManager());
|
|
3116
|
+
(0, import_react2.useEffect)(() => {
|
|
3117
|
+
const manager = blobManagerRef.current;
|
|
3118
|
+
return () => {
|
|
3119
|
+
manager.revokeAll();
|
|
3120
|
+
};
|
|
3121
|
+
}, []);
|
|
2886
3122
|
const messagesCollection = (0, import_react2.useMemo)(
|
|
2887
3123
|
() => database.get("history"),
|
|
2888
3124
|
[database]
|
|
@@ -2950,9 +3186,49 @@ function useChatStorage(options) {
|
|
|
2950
3186
|
);
|
|
2951
3187
|
const getMessages = (0, import_react2.useCallback)(
|
|
2952
3188
|
async (convId) => {
|
|
2953
|
-
|
|
3189
|
+
const messages = await getMessagesOp(storageCtx, convId);
|
|
3190
|
+
if (walletAddress && hasEncryptionKey(walletAddress) && isOPFSSupported()) {
|
|
3191
|
+
try {
|
|
3192
|
+
const encryptionKey = await getEncryptionKey(walletAddress);
|
|
3193
|
+
const blobManager = blobManagerRef.current;
|
|
3194
|
+
const resolvedMessages = await Promise.all(
|
|
3195
|
+
messages.map(async (msg) => {
|
|
3196
|
+
const fileIds = extractFileIds(msg.content);
|
|
3197
|
+
if (fileIds.length === 0) {
|
|
3198
|
+
return msg;
|
|
3199
|
+
}
|
|
3200
|
+
let resolvedContent = msg.content;
|
|
3201
|
+
for (const fileId of fileIds) {
|
|
3202
|
+
let url = blobManager.getUrl(fileId);
|
|
3203
|
+
if (!url) {
|
|
3204
|
+
const result = await readEncryptedFile(fileId, encryptionKey);
|
|
3205
|
+
if (result) {
|
|
3206
|
+
url = blobManager.createUrl(fileId, result.blob);
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3209
|
+
if (url) {
|
|
3210
|
+
const placeholder = createFilePlaceholder(fileId);
|
|
3211
|
+
resolvedContent = resolvedContent.replace(
|
|
3212
|
+
new RegExp(
|
|
3213
|
+
placeholder.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
|
|
3214
|
+
"g"
|
|
3215
|
+
),
|
|
3216
|
+
``
|
|
3217
|
+
);
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
return { ...msg, content: resolvedContent };
|
|
3221
|
+
})
|
|
3222
|
+
);
|
|
3223
|
+
return resolvedMessages;
|
|
3224
|
+
} catch (error) {
|
|
3225
|
+
console.error("[useChatStorage] Failed to resolve file placeholders:", error);
|
|
3226
|
+
return messages;
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
return messages;
|
|
2954
3230
|
},
|
|
2955
|
-
[storageCtx]
|
|
3231
|
+
[storageCtx, walletAddress]
|
|
2956
3232
|
);
|
|
2957
3233
|
const getMessageCount = (0, import_react2.useCallback)(
|
|
2958
3234
|
async (convId) => {
|
|
@@ -3176,6 +3452,89 @@ function useChatStorage(options) {
|
|
|
3176
3452
|
},
|
|
3177
3453
|
[]
|
|
3178
3454
|
);
|
|
3455
|
+
const extractAndStoreEncryptedMCPImages = (0, import_react2.useCallback)(
|
|
3456
|
+
async (content, address) => {
|
|
3457
|
+
try {
|
|
3458
|
+
if (!isOPFSSupported()) {
|
|
3459
|
+
console.warn("[extractAndStoreEncryptedMCPImages] OPFS not supported");
|
|
3460
|
+
return { processedFiles: [], cleanedContent: content };
|
|
3461
|
+
}
|
|
3462
|
+
if (!hasEncryptionKey(address)) {
|
|
3463
|
+
console.warn("[extractAndStoreEncryptedMCPImages] Encryption key not available");
|
|
3464
|
+
return { processedFiles: [], cleanedContent: content };
|
|
3465
|
+
}
|
|
3466
|
+
const MCP_IMAGE_URL_PATTERN = new RegExp(
|
|
3467
|
+
`https://${MCP_R2_DOMAIN.replace(/\./g, "\\.")}[^\\s)]*`,
|
|
3468
|
+
"g"
|
|
3469
|
+
);
|
|
3470
|
+
const urlMatches = content.match(MCP_IMAGE_URL_PATTERN);
|
|
3471
|
+
if (!urlMatches || urlMatches.length === 0) {
|
|
3472
|
+
return { processedFiles: [], cleanedContent: content };
|
|
3473
|
+
}
|
|
3474
|
+
const uniqueUrls = [...new Set(urlMatches)];
|
|
3475
|
+
const encryptionKey = await getEncryptionKey(address);
|
|
3476
|
+
const processedFiles = [];
|
|
3477
|
+
let cleanedContent = content;
|
|
3478
|
+
const results = await Promise.allSettled(
|
|
3479
|
+
uniqueUrls.map(async (imageUrl) => {
|
|
3480
|
+
const controller = new AbortController();
|
|
3481
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
3482
|
+
try {
|
|
3483
|
+
const response = await fetch(imageUrl, {
|
|
3484
|
+
signal: controller.signal,
|
|
3485
|
+
cache: "no-store"
|
|
3486
|
+
});
|
|
3487
|
+
if (!response.ok) {
|
|
3488
|
+
throw new Error(`Failed to fetch image: ${response.status}`);
|
|
3489
|
+
}
|
|
3490
|
+
const blob = await response.blob();
|
|
3491
|
+
const fileId = crypto.randomUUID();
|
|
3492
|
+
const urlPath = imageUrl.split("?")[0] ?? imageUrl;
|
|
3493
|
+
const extension = urlPath.match(/\.([a-zA-Z0-9]+)$/)?.[1] || "png";
|
|
3494
|
+
const mimeType = blob.type || `image/${extension}`;
|
|
3495
|
+
const fileName = `mcp-image-${Date.now()}-${fileId.slice(0, 8)}.${extension}`;
|
|
3496
|
+
await writeEncryptedFile(fileId, blob, encryptionKey, {
|
|
3497
|
+
name: fileName,
|
|
3498
|
+
sourceUrl: imageUrl
|
|
3499
|
+
});
|
|
3500
|
+
return { fileId, fileName, mimeType, size: blob.size, imageUrl };
|
|
3501
|
+
} finally {
|
|
3502
|
+
clearTimeout(timeoutId);
|
|
3503
|
+
}
|
|
3504
|
+
})
|
|
3505
|
+
);
|
|
3506
|
+
results.forEach((result, i) => {
|
|
3507
|
+
const imageUrl = uniqueUrls[i];
|
|
3508
|
+
if (result.status === "fulfilled") {
|
|
3509
|
+
const { fileId, fileName, mimeType, size } = result.value;
|
|
3510
|
+
processedFiles.push({
|
|
3511
|
+
id: fileId,
|
|
3512
|
+
name: fileName,
|
|
3513
|
+
type: mimeType,
|
|
3514
|
+
size,
|
|
3515
|
+
sourceUrl: imageUrl
|
|
3516
|
+
});
|
|
3517
|
+
const placeholder = createFilePlaceholder(fileId);
|
|
3518
|
+
const escapedUrl = imageUrl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3519
|
+
const markdownImagePattern = new RegExp(
|
|
3520
|
+
`!\\[[^\\]]*\\]\\([\\s]*${escapedUrl}[\\s]*\\)`,
|
|
3521
|
+
"g"
|
|
3522
|
+
);
|
|
3523
|
+
cleanedContent = cleanedContent.replace(markdownImagePattern, placeholder);
|
|
3524
|
+
cleanedContent = cleanedContent.replace(new RegExp(escapedUrl, "g"), placeholder);
|
|
3525
|
+
} else {
|
|
3526
|
+
console.error("[extractAndStoreEncryptedMCPImages] Failed:", result.reason);
|
|
3527
|
+
}
|
|
3528
|
+
});
|
|
3529
|
+
cleanedContent = cleanedContent.replace(/\n{3,}/g, "\n\n").trim();
|
|
3530
|
+
return { processedFiles, cleanedContent };
|
|
3531
|
+
} catch (err) {
|
|
3532
|
+
console.error("[extractAndStoreEncryptedMCPImages] Unexpected error:", err);
|
|
3533
|
+
return { processedFiles: [], cleanedContent: content };
|
|
3534
|
+
}
|
|
3535
|
+
},
|
|
3536
|
+
[]
|
|
3537
|
+
);
|
|
3179
3538
|
const sendMessage = (0, import_react2.useCallback)(
|
|
3180
3539
|
async (args) => {
|
|
3181
3540
|
const {
|
|
@@ -3227,10 +3586,10 @@ function useChatStorage(options) {
|
|
|
3227
3586
|
const storedMessages = await getMessages(convId);
|
|
3228
3587
|
const validMessages = storedMessages.filter((msg) => !msg.error);
|
|
3229
3588
|
const limitedMessages = validMessages.slice(-maxHistoryMessages);
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
];
|
|
3589
|
+
const historyMessages = await Promise.all(
|
|
3590
|
+
limitedMessages.map(storedToLlmapiMessage)
|
|
3591
|
+
);
|
|
3592
|
+
messagesToSend = [...historyMessages, ...messages];
|
|
3234
3593
|
} else {
|
|
3235
3594
|
messagesToSend = [...messages];
|
|
3236
3595
|
}
|
|
@@ -3368,7 +3727,14 @@ function useChatStorage(options) {
|
|
|
3368
3727
|
let cleanedContent = assistantContent.replace(jsonSourcesBlockRegex, "").trim();
|
|
3369
3728
|
cleanedContent = cleanedContent.replace(/\n{3,}/g, "\n\n");
|
|
3370
3729
|
let processedFiles = [];
|
|
3371
|
-
if (
|
|
3730
|
+
if (walletAddress) {
|
|
3731
|
+
const result2 = await extractAndStoreEncryptedMCPImages(
|
|
3732
|
+
cleanedContent,
|
|
3733
|
+
walletAddress
|
|
3734
|
+
);
|
|
3735
|
+
processedFiles = result2.processedFiles;
|
|
3736
|
+
cleanedContent = result2.cleanedContent;
|
|
3737
|
+
} else if (writeFile) {
|
|
3372
3738
|
const result2 = await extractAndStoreMCPImages(
|
|
3373
3739
|
cleanedContent,
|
|
3374
3740
|
writeFile
|
|
@@ -3404,7 +3770,7 @@ function useChatStorage(options) {
|
|
|
3404
3770
|
assistantMessage: storedAssistantMessage
|
|
3405
3771
|
};
|
|
3406
3772
|
},
|
|
3407
|
-
[ensureConversation, getMessages, storageCtx, baseSendMessage]
|
|
3773
|
+
[ensureConversation, getMessages, storageCtx, baseSendMessage, walletAddress, extractAndStoreEncryptedMCPImages]
|
|
3408
3774
|
);
|
|
3409
3775
|
const searchMessages = (0, import_react2.useCallback)(
|
|
3410
3776
|
async (queryVector, options2) => {
|
|
@@ -9179,6 +9545,7 @@ function hasDriveCredentials() {
|
|
|
9179
9545
|
BACKUP_DRIVE_ROOT_FOLDER,
|
|
9180
9546
|
BACKUP_ICLOUD_FOLDER,
|
|
9181
9547
|
BackupAuthProvider,
|
|
9548
|
+
BlobUrlManager,
|
|
9182
9549
|
ChatConversation,
|
|
9183
9550
|
ChatMessage,
|
|
9184
9551
|
DEFAULT_BACKUP_FOLDER,
|
|
@@ -9208,9 +9575,11 @@ function hasDriveCredentials() {
|
|
|
9208
9575
|
createMemoryContextSystemMessage,
|
|
9209
9576
|
decryptData,
|
|
9210
9577
|
decryptDataBytes,
|
|
9578
|
+
deleteEncryptedFile,
|
|
9211
9579
|
encryptData,
|
|
9212
9580
|
exportPublicKey,
|
|
9213
9581
|
extractConversationContext,
|
|
9582
|
+
fileExists,
|
|
9214
9583
|
findFileIdBySourceUrl,
|
|
9215
9584
|
formatMemoriesForChat,
|
|
9216
9585
|
generateCompositeKey,
|
|
@@ -9222,6 +9591,7 @@ function hasDriveCredentials() {
|
|
|
9222
9591
|
getAndClearDriveReturnUrl,
|
|
9223
9592
|
getCalendarAccessToken,
|
|
9224
9593
|
getDriveAccessToken,
|
|
9594
|
+
getEncryptionKey,
|
|
9225
9595
|
getGoogleDriveStoredToken,
|
|
9226
9596
|
getValidCalendarToken,
|
|
9227
9597
|
getValidDriveToken,
|
|
@@ -9236,7 +9606,9 @@ function hasDriveCredentials() {
|
|
|
9236
9606
|
hasKeyPair,
|
|
9237
9607
|
isCalendarCallback,
|
|
9238
9608
|
isDriveCallback,
|
|
9609
|
+
isOPFSSupported,
|
|
9239
9610
|
memoryStorageSchema,
|
|
9611
|
+
readEncryptedFile,
|
|
9240
9612
|
refreshCalendarToken,
|
|
9241
9613
|
refreshDriveToken,
|
|
9242
9614
|
replaceUrlWithMCPPlaceholder,
|
|
@@ -9274,5 +9646,6 @@ function hasDriveCredentials() {
|
|
|
9274
9646
|
usePdf,
|
|
9275
9647
|
useSearch,
|
|
9276
9648
|
useSettings,
|
|
9277
|
-
userPreferencesStorageSchema
|
|
9649
|
+
userPreferencesStorageSchema,
|
|
9650
|
+
writeEncryptedFile
|
|
9278
9651
|
});
|
package/dist/react/index.d.mts
CHANGED
|
@@ -1055,6 +1055,15 @@ declare function clearEncryptionKey(address: string): void;
|
|
|
1055
1055
|
* Clears all encryption keys from memory
|
|
1056
1056
|
*/
|
|
1057
1057
|
declare function clearAllEncryptionKeys(): void;
|
|
1058
|
+
/**
|
|
1059
|
+
* Gets the encryption key from in-memory storage and imports it as a CryptoKey.
|
|
1060
|
+
* The key must have been previously requested via requestEncryptionKey.
|
|
1061
|
+
*
|
|
1062
|
+
* @param address - The wallet address
|
|
1063
|
+
* @returns The CryptoKey for AES-GCM encryption/decryption
|
|
1064
|
+
* @throws Error if the key hasn't been requested yet
|
|
1065
|
+
*/
|
|
1066
|
+
declare function getEncryptionKey(address: string): Promise<CryptoKey>;
|
|
1058
1067
|
/**
|
|
1059
1068
|
* Encrypts data using AES-GCM with the stored encryption key.
|
|
1060
1069
|
*
|
|
@@ -1816,6 +1825,18 @@ interface UseChatStorageOptions extends BaseUseChatStorageOptions {
|
|
|
1816
1825
|
* - "completions": OpenAI Chat Completions API (wider model compatibility)
|
|
1817
1826
|
*/
|
|
1818
1827
|
apiType?: ApiType;
|
|
1828
|
+
/**
|
|
1829
|
+
* Wallet address for encrypted file storage.
|
|
1830
|
+
* When provided, MCP-generated images are automatically encrypted and stored
|
|
1831
|
+
* in OPFS using wallet-derived keys. Messages are returned with working blob URLs.
|
|
1832
|
+
*
|
|
1833
|
+
* Requires:
|
|
1834
|
+
* - OPFS browser support
|
|
1835
|
+
* - Encryption key to be requested via `requestEncryptionKey` first
|
|
1836
|
+
*
|
|
1837
|
+
* When not provided, falls back to the `writeFile` callback in sendMessage args.
|
|
1838
|
+
*/
|
|
1839
|
+
walletAddress?: string;
|
|
1819
1840
|
}
|
|
1820
1841
|
/**
|
|
1821
1842
|
* Arguments for sendMessage with storage (React version)
|
|
@@ -1982,6 +2003,84 @@ interface UseChatStorageResult extends BaseUseChatStorageResult {
|
|
|
1982
2003
|
*/
|
|
1983
2004
|
declare function useChatStorage(options: UseChatStorageOptions): UseChatStorageResult;
|
|
1984
2005
|
|
|
2006
|
+
/**
|
|
2007
|
+
* Checks if the browser supports OPFS.
|
|
2008
|
+
*/
|
|
2009
|
+
declare function isOPFSSupported(): boolean;
|
|
2010
|
+
/**
|
|
2011
|
+
* File metadata stored alongside encrypted content.
|
|
2012
|
+
*/
|
|
2013
|
+
interface StoredFileMetadata {
|
|
2014
|
+
id: string;
|
|
2015
|
+
name: string;
|
|
2016
|
+
type: string;
|
|
2017
|
+
size: number;
|
|
2018
|
+
sourceUrl?: string;
|
|
2019
|
+
createdAt: number;
|
|
2020
|
+
}
|
|
2021
|
+
/**
|
|
2022
|
+
* Writes an encrypted file to OPFS.
|
|
2023
|
+
*
|
|
2024
|
+
* @param fileId - Unique identifier for the file
|
|
2025
|
+
* @param blob - The file content
|
|
2026
|
+
* @param encryptionKey - CryptoKey for encryption
|
|
2027
|
+
* @param metadata - Optional metadata (name, type, sourceUrl)
|
|
2028
|
+
*/
|
|
2029
|
+
declare function writeEncryptedFile(fileId: string, blob: Blob, encryptionKey: CryptoKey, metadata?: {
|
|
2030
|
+
name?: string;
|
|
2031
|
+
sourceUrl?: string;
|
|
2032
|
+
}): Promise<void>;
|
|
2033
|
+
/**
|
|
2034
|
+
* Reads and decrypts a file from OPFS.
|
|
2035
|
+
*
|
|
2036
|
+
* @param fileId - The file identifier
|
|
2037
|
+
* @param encryptionKey - CryptoKey for decryption
|
|
2038
|
+
* @returns The decrypted blob, or null if not found
|
|
2039
|
+
*/
|
|
2040
|
+
declare function readEncryptedFile(fileId: string, encryptionKey: CryptoKey): Promise<{
|
|
2041
|
+
blob: Blob;
|
|
2042
|
+
metadata: StoredFileMetadata;
|
|
2043
|
+
} | null>;
|
|
2044
|
+
/**
|
|
2045
|
+
* Deletes a file from OPFS.
|
|
2046
|
+
*
|
|
2047
|
+
* @param fileId - The file identifier
|
|
2048
|
+
*/
|
|
2049
|
+
declare function deleteEncryptedFile(fileId: string): Promise<void>;
|
|
2050
|
+
/**
|
|
2051
|
+
* Checks if a file exists in OPFS.
|
|
2052
|
+
*
|
|
2053
|
+
* @param fileId - The file identifier
|
|
2054
|
+
*/
|
|
2055
|
+
declare function fileExists(fileId: string): Promise<boolean>;
|
|
2056
|
+
/**
|
|
2057
|
+
* Manager for blob URLs to prevent memory leaks.
|
|
2058
|
+
* Tracks active blob URLs and provides cleanup functionality.
|
|
2059
|
+
*/
|
|
2060
|
+
declare class BlobUrlManager {
|
|
2061
|
+
private activeUrls;
|
|
2062
|
+
/**
|
|
2063
|
+
* Creates a blob URL for a file and tracks it.
|
|
2064
|
+
*/
|
|
2065
|
+
createUrl(fileId: string, blob: Blob): string;
|
|
2066
|
+
/**
|
|
2067
|
+
* Gets the active blob URL for a file, if any.
|
|
2068
|
+
*/
|
|
2069
|
+
getUrl(fileId: string): string | undefined;
|
|
2070
|
+
/**
|
|
2071
|
+
* Revokes a blob URL and removes it from tracking.
|
|
2072
|
+
*/
|
|
2073
|
+
revokeUrl(fileId: string): void;
|
|
2074
|
+
/**
|
|
2075
|
+
* Revokes all tracked blob URLs.
|
|
2076
|
+
*/
|
|
2077
|
+
revokeAll(): void;
|
|
2078
|
+
/**
|
|
2079
|
+
* Gets the count of active blob URLs.
|
|
2080
|
+
*/
|
|
2081
|
+
get size(): number;
|
|
2082
|
+
}
|
|
2083
|
+
|
|
1985
2084
|
/**
|
|
1986
2085
|
* Combined WatermelonDB schema for all SDK storage modules.
|
|
1987
2086
|
*
|
|
@@ -3801,4 +3900,4 @@ declare function storeDriveToken(accessToken: string, expiresIn?: number, refres
|
|
|
3801
3900
|
*/
|
|
3802
3901
|
declare function hasDriveCredentials(): boolean;
|
|
3803
3902
|
|
|
3804
|
-
export { DEFAULT_CONVERSATIONS_FOLDER as BACKUP_DRIVE_CONVERSATIONS_FOLDER, DEFAULT_ROOT_FOLDER as BACKUP_DRIVE_ROOT_FOLDER, DEFAULT_BACKUP_FOLDER as BACKUP_ICLOUD_FOLDER, type BackupAuthContextValue, BackupAuthProvider, type BackupAuthProviderProps, type BackupOperationOptions, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type CreateConversationOptions, type CreateMemoryOptions, type CreateMessageOptions, type CreateModelPreferenceOptions, type CreateUserPreferenceOptions, DEFAULT_BACKUP_FOLDER$1 as DEFAULT_BACKUP_FOLDER, DEFAULT_CONVERSATIONS_FOLDER as DEFAULT_DRIVE_CONVERSATIONS_FOLDER, DEFAULT_ROOT_FOLDER as DEFAULT_DRIVE_ROOT_FOLDER, DEFAULT_BACKUP_FOLDER$1 as DEFAULT_DROPBOX_FOLDER, DEFAULT_BACKUP_FOLDER as DEFAULT_ICLOUD_BACKUP_FOLDER, DEFAULT_PERSONALITY_SETTINGS, type DropboxAuthContextValue, DropboxAuthProvider, type DropboxAuthProviderProps, type DropboxExportResult, type DropboxImportResult, type EmbeddedWalletSignerFn, type FileMetadata, type GoogleDriveAuthContextValue, GoogleDriveAuthProvider, type GoogleDriveAuthProviderProps, type GoogleDriveExportResult, type GoogleDriveImportResult, type ICloudAuthContextValue, ICloudAuthProvider, type ICloudAuthProviderProps, type ICloudExportResult, type ICloudImportResult, type MemoryItem, type MemoryType, type OCRFile, type PdfFile, type PersonalitySettings, type PersonalitySliders, type PersonalityStyle, type ProfileUpdate, type ProgressCallback, type ProviderAuthState, type ProviderBackupState, SLIDER_CONFIG, type SearchMessagesOptions, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageResult, type SignMessageFn, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredMemory, Memory as StoredMemoryModel, type StoredMemoryWithSimilarity, type StoredMessage, type StoredMessageWithSimilarity, type StoredModelPreference, ModelPreference as StoredModelPreferenceModel, type StoredUserPreference, UserPreference as StoredUserPreferenceModel, type UpdateMemoryOptions, type UpdateModelPreferenceOptions, type UpdateUserPreferenceOptions, type UseBackupOptions, type UseBackupResult, type UseChatStorageOptions, type UseChatStorageResult, type UseDropboxBackupOptions, type UseDropboxBackupResult, type UseEncryptionResult, type UseGoogleDriveBackupOptions, type UseGoogleDriveBackupResult, type UseICloudBackupOptions, type UseICloudBackupResult, type UseImageGenerationResult, type UseMemoryStorageOptions, type UseMemoryStorageResult, type UseModelsResult, type UseOCRResult, type UsePdfResult, type UseSearchResult, type UseSettingsOptions, type UseSettingsResult, chatStorageMigrations, chatStorageSchema, clearAllEncryptionKeys, clearAllKeyPairs, clearCalendarToken, clearDriveToken, clearToken as clearDropboxToken, clearEncryptionKey, clearGoogleDriveToken, clearICloudAuth, clearKeyPair, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, exportPublicKey, extractConversationContext, findFileIdBySourceUrl, formatMemoriesForChat, generateCompositeKey, generateConversationId, generateUniqueKey, getAndClearCalendarPendingMessage, getAndClearCalendarReturnUrl, getAndClearDrivePendingMessage, getAndClearDriveReturnUrl, getCalendarAccessToken, getDriveAccessToken, getGoogleDriveStoredToken, getValidCalendarToken, getValidDriveToken, handleCalendarCallback, handleDriveCallback, hasCalendarCredentials, hasDriveCredentials, hasDropboxCredentials, hasEncryptionKey, hasGoogleDriveCredentials, hasICloudCredentials, hasKeyPair, isCalendarCallback, isDriveCallback, memoryStorageSchema, refreshCalendarToken, refreshDriveToken, replaceUrlWithMCPPlaceholder, requestEncryptionKey, requestKeyPair, revokeCalendarToken, revokeDriveToken, sdkMigrations, sdkModelClasses, sdkSchema, settingsStorageSchema, startCalendarAuth, startDriveAuth, storeCalendarPendingMessage, storeCalendarReturnUrl, storeCalendarToken, storeDrivePendingMessage, storeDriveReturnUrl, storeDriveToken, useBackup, useBackupAuth, useChat, useChatStorage, useDropboxAuth, useDropboxBackup, useEncryption, useGoogleDriveAuth, useGoogleDriveBackup, useICloudAuth, useICloudBackup, useImageGeneration, useMemoryStorage, useModels, useOCR, usePdf, useSearch, useSettings, userPreferencesStorageSchema };
|
|
3903
|
+
export { DEFAULT_CONVERSATIONS_FOLDER as BACKUP_DRIVE_CONVERSATIONS_FOLDER, DEFAULT_ROOT_FOLDER as BACKUP_DRIVE_ROOT_FOLDER, DEFAULT_BACKUP_FOLDER as BACKUP_ICLOUD_FOLDER, type BackupAuthContextValue, BackupAuthProvider, type BackupAuthProviderProps, type BackupOperationOptions, BlobUrlManager, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type CreateConversationOptions, type CreateMemoryOptions, type CreateMessageOptions, type CreateModelPreferenceOptions, type CreateUserPreferenceOptions, DEFAULT_BACKUP_FOLDER$1 as DEFAULT_BACKUP_FOLDER, DEFAULT_CONVERSATIONS_FOLDER as DEFAULT_DRIVE_CONVERSATIONS_FOLDER, DEFAULT_ROOT_FOLDER as DEFAULT_DRIVE_ROOT_FOLDER, DEFAULT_BACKUP_FOLDER$1 as DEFAULT_DROPBOX_FOLDER, DEFAULT_BACKUP_FOLDER as DEFAULT_ICLOUD_BACKUP_FOLDER, DEFAULT_PERSONALITY_SETTINGS, type DropboxAuthContextValue, DropboxAuthProvider, type DropboxAuthProviderProps, type DropboxExportResult, type DropboxImportResult, type EmbeddedWalletSignerFn, type FileMetadata, type GoogleDriveAuthContextValue, GoogleDriveAuthProvider, type GoogleDriveAuthProviderProps, type GoogleDriveExportResult, type GoogleDriveImportResult, type ICloudAuthContextValue, ICloudAuthProvider, type ICloudAuthProviderProps, type ICloudExportResult, type ICloudImportResult, type MemoryItem, type MemoryType, type OCRFile, type PdfFile, type PersonalitySettings, type PersonalitySliders, type PersonalityStyle, type ProfileUpdate, type ProgressCallback, type ProviderAuthState, type ProviderBackupState, SLIDER_CONFIG, type SearchMessagesOptions, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageResult, type SignMessageFn, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredMemory, Memory as StoredMemoryModel, type StoredMemoryWithSimilarity, type StoredMessage, type StoredMessageWithSimilarity, type StoredModelPreference, ModelPreference as StoredModelPreferenceModel, type StoredUserPreference, UserPreference as StoredUserPreferenceModel, type UpdateMemoryOptions, type UpdateModelPreferenceOptions, type UpdateUserPreferenceOptions, type UseBackupOptions, type UseBackupResult, type UseChatStorageOptions, type UseChatStorageResult, type UseDropboxBackupOptions, type UseDropboxBackupResult, type UseEncryptionResult, type UseGoogleDriveBackupOptions, type UseGoogleDriveBackupResult, type UseICloudBackupOptions, type UseICloudBackupResult, type UseImageGenerationResult, type UseMemoryStorageOptions, type UseMemoryStorageResult, type UseModelsResult, type UseOCRResult, type UsePdfResult, type UseSearchResult, type UseSettingsOptions, type UseSettingsResult, chatStorageMigrations, chatStorageSchema, clearAllEncryptionKeys, clearAllKeyPairs, clearCalendarToken, clearDriveToken, clearToken as clearDropboxToken, clearEncryptionKey, clearGoogleDriveToken, clearICloudAuth, clearKeyPair, createMemoryContextSystemMessage, decryptData, decryptDataBytes, deleteEncryptedFile, encryptData, exportPublicKey, extractConversationContext, fileExists, findFileIdBySourceUrl, formatMemoriesForChat, generateCompositeKey, generateConversationId, generateUniqueKey, getAndClearCalendarPendingMessage, getAndClearCalendarReturnUrl, getAndClearDrivePendingMessage, getAndClearDriveReturnUrl, getCalendarAccessToken, getDriveAccessToken, getEncryptionKey, getGoogleDriveStoredToken, getValidCalendarToken, getValidDriveToken, handleCalendarCallback, handleDriveCallback, hasCalendarCredentials, hasDriveCredentials, hasDropboxCredentials, hasEncryptionKey, hasGoogleDriveCredentials, hasICloudCredentials, hasKeyPair, isCalendarCallback, isDriveCallback, isOPFSSupported, memoryStorageSchema, readEncryptedFile, refreshCalendarToken, refreshDriveToken, replaceUrlWithMCPPlaceholder, requestEncryptionKey, requestKeyPair, revokeCalendarToken, revokeDriveToken, sdkMigrations, sdkModelClasses, sdkSchema, settingsStorageSchema, startCalendarAuth, startDriveAuth, storeCalendarPendingMessage, storeCalendarReturnUrl, storeCalendarToken, storeDrivePendingMessage, storeDriveReturnUrl, storeDriveToken, useBackup, useBackupAuth, useChat, useChatStorage, useDropboxAuth, useDropboxBackup, useEncryption, useGoogleDriveAuth, useGoogleDriveBackup, useICloudAuth, useICloudBackup, useImageGeneration, useMemoryStorage, useModels, useOCR, usePdf, useSearch, useSettings, userPreferencesStorageSchema, writeEncryptedFile };
|