@anuma/sdk 1.1.4 → 1.1.6
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/{chunk-RYLI53HN.mjs → chunk-OZ357R4P.mjs} +94 -46
- package/dist/expo/index.cjs +124 -49
- package/dist/expo/index.d.mts +15 -0
- package/dist/expo/index.d.ts +15 -0
- package/dist/expo/index.mjs +30 -3
- package/dist/expo/{recall-U6SVHL5Q.mjs → recall-EMFBX3WU.mjs} +1 -1
- package/dist/index.cjs +13 -6
- package/dist/index.mjs +13 -6
- package/dist/react/{chunk-DVGJ5NBT.mjs → chunk-DC6J5RX5.mjs} +94 -46
- package/dist/react/index.cjs +124 -49
- package/dist/react/index.d.mts +15 -0
- package/dist/react/index.d.ts +15 -0
- package/dist/react/index.mjs +30 -3
- package/dist/react/{recall-6AQ4WFJO.mjs → recall-RGKS2OIP.mjs} +1 -1
- package/dist/server/{chunk-RCNBXNOI.mjs → chunk-MKRSHU4S.mjs} +20 -7
- package/dist/server/index.cjs +49 -9
- package/dist/server/index.d.mts +15 -0
- package/dist/server/index.d.ts +15 -0
- package/dist/server/index.mjs +30 -3
- package/dist/server/{recall-2XUT7CCN.mjs → recall-V4763HKS.mjs} +1 -1
- package/package.json +1 -1
|
@@ -1210,50 +1210,85 @@ async function getMessagesPageOp(ctx, convId, opts) {
|
|
|
1210
1210
|
)
|
|
1211
1211
|
);
|
|
1212
1212
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1213
|
+
var SKELETON_PAGE_SIZE = 2e3;
|
|
1214
|
+
function narrowSkeletonRow(raw) {
|
|
1215
|
+
return {
|
|
1216
|
+
id: raw.id,
|
|
1217
|
+
message_id: raw.message_id,
|
|
1218
|
+
conversation_id: raw.conversation_id,
|
|
1219
|
+
role: raw.role,
|
|
1220
|
+
created_at: raw.created_at,
|
|
1221
|
+
parent_message_id: raw.parent_message_id ?? null,
|
|
1222
|
+
model: raw.model ?? null,
|
|
1223
|
+
content: raw.content ?? null
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
async function fetchThreadSkeletonRawPaged(collection, convId, pageSize = SKELETON_PAGE_SIZE) {
|
|
1227
|
+
const all = [];
|
|
1228
|
+
let cursor;
|
|
1229
|
+
for (; ; ) {
|
|
1230
|
+
const clauses = [Q.where("conversation_id", convId)];
|
|
1231
|
+
if (cursor) {
|
|
1232
|
+
clauses.push(
|
|
1233
|
+
Q.or(
|
|
1234
|
+
Q.where("message_id", Q.gt(cursor.messageId)),
|
|
1235
|
+
Q.and(Q.where("message_id", cursor.messageId), Q.where("id", Q.gt(cursor.id)))
|
|
1236
|
+
)
|
|
1237
|
+
);
|
|
1236
1238
|
}
|
|
1239
|
+
const page = await collection.query(...clauses, Q.sortBy("message_id", Q.asc), Q.sortBy("id", Q.asc), Q.take(pageSize)).unsafeFetchRaw();
|
|
1240
|
+
if (page.length === 0) break;
|
|
1241
|
+
for (const raw of page) all.push(narrowSkeletonRow(raw));
|
|
1242
|
+
if (page.length < pageSize) break;
|
|
1243
|
+
const last = all[all.length - 1];
|
|
1244
|
+
cursor = { messageId: last.message_id, id: last.id };
|
|
1237
1245
|
}
|
|
1246
|
+
return all;
|
|
1247
|
+
}
|
|
1248
|
+
function collectArtifactIndices(rows, roleById) {
|
|
1249
|
+
const indices = [];
|
|
1250
|
+
for (let i = 0; i < rows.length; i++) {
|
|
1251
|
+
const row = rows[i];
|
|
1252
|
+
if (row.role !== "user" || !row.parent_message_id) continue;
|
|
1253
|
+
if (roleById.get(row.parent_message_id) === "user") indices.push(i);
|
|
1254
|
+
}
|
|
1255
|
+
return indices;
|
|
1256
|
+
}
|
|
1257
|
+
async function decryptArtifactContent(skeletons, rows, artifactIndices, ctx) {
|
|
1238
1258
|
const address = ctx.walletAddress;
|
|
1239
|
-
if (artifactIndices.length
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
artifactIndices.map(async (i) => {
|
|
1249
|
-
skeletons[i].content = await decryptField(results[i].content, address);
|
|
1250
|
-
})
|
|
1251
|
-
);
|
|
1252
|
-
} else {
|
|
1253
|
-
for (const i of artifactIndices) {
|
|
1254
|
-
skeletons[i].content = results[i].content;
|
|
1259
|
+
if (artifactIndices.length === 0 || !address) {
|
|
1260
|
+
for (const i of artifactIndices) skeletons[i].content = rows[i].content ?? void 0;
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1263
|
+
if (ctx.signMessage) {
|
|
1264
|
+
try {
|
|
1265
|
+
await requestEncryptionKey(address, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
1266
|
+
} catch (error) {
|
|
1267
|
+
getLogger().warn("Failed to request encryption key for skeleton decryption:", error);
|
|
1255
1268
|
}
|
|
1256
1269
|
}
|
|
1270
|
+
await Promise.all(
|
|
1271
|
+
artifactIndices.map(async (i) => {
|
|
1272
|
+
skeletons[i].content = await decryptField(rows[i].content ?? "", address);
|
|
1273
|
+
})
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
async function getMessageSkeletonsOp(ctx, convId) {
|
|
1277
|
+
const rows = await fetchThreadSkeletonRawPaged(ctx.messagesCollection, convId);
|
|
1278
|
+
const roleById = /* @__PURE__ */ new Map();
|
|
1279
|
+
for (const row of rows) roleById.set(row.id, row.role);
|
|
1280
|
+
const skeletons = rows.map((row) => ({
|
|
1281
|
+
uniqueId: row.id,
|
|
1282
|
+
messageId: row.message_id,
|
|
1283
|
+
conversationId: String(row.conversation_id),
|
|
1284
|
+
role: row.role,
|
|
1285
|
+
createdAt: new Date(row.created_at),
|
|
1286
|
+
// WatermelonDB surfaces unset text columns as null at runtime — normalize
|
|
1287
|
+
// to undefined so `parentMessageId ?? undefined` keying works everywhere.
|
|
1288
|
+
parentMessageId: row.parent_message_id ?? void 0,
|
|
1289
|
+
model: row.model ?? void 0
|
|
1290
|
+
}));
|
|
1291
|
+
await decryptArtifactContent(skeletons, rows, collectArtifactIndices(rows, roleById), ctx);
|
|
1257
1292
|
return skeletons;
|
|
1258
1293
|
}
|
|
1259
1294
|
async function clearMessagesOp(ctx, convId) {
|
|
@@ -3170,6 +3205,20 @@ async function withEmbeddingRetry(call) {
|
|
|
3170
3205
|
if (threw) throw lastThrown;
|
|
3171
3206
|
return last;
|
|
3172
3207
|
}
|
|
3208
|
+
var EmbeddingHttpError = class extends Error {
|
|
3209
|
+
constructor(message, status) {
|
|
3210
|
+
super(message);
|
|
3211
|
+
this.name = "EmbeddingHttpError";
|
|
3212
|
+
this.status = status;
|
|
3213
|
+
}
|
|
3214
|
+
};
|
|
3215
|
+
function isFatalEmbeddingError(err) {
|
|
3216
|
+
return err instanceof EmbeddingHttpError && (err.status === 401 || err.status === 402 || err.status === 403);
|
|
3217
|
+
}
|
|
3218
|
+
function embeddingErrorFrom(response) {
|
|
3219
|
+
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
3220
|
+
return new EmbeddingHttpError(message, response.response?.status);
|
|
3221
|
+
}
|
|
3173
3222
|
async function generateEmbedding(text, options) {
|
|
3174
3223
|
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
3175
3224
|
if (cache) {
|
|
@@ -3201,9 +3250,7 @@ async function generateEmbedding(text, options) {
|
|
|
3201
3250
|
})
|
|
3202
3251
|
);
|
|
3203
3252
|
if (response.error) {
|
|
3204
|
-
throw
|
|
3205
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
3206
|
-
);
|
|
3253
|
+
throw embeddingErrorFrom(response);
|
|
3207
3254
|
}
|
|
3208
3255
|
if (!response.data?.data?.[0]?.embedding) {
|
|
3209
3256
|
throw new Error("No embedding returned from API");
|
|
@@ -3232,9 +3279,7 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
3232
3279
|
})
|
|
3233
3280
|
);
|
|
3234
3281
|
if (response.error) {
|
|
3235
|
-
throw
|
|
3236
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
3237
|
-
);
|
|
3282
|
+
throw embeddingErrorFrom(response);
|
|
3238
3283
|
}
|
|
3239
3284
|
if (!response.data?.data) {
|
|
3240
3285
|
throw new Error("No embeddings returned from API");
|
|
@@ -3370,6 +3415,7 @@ async function embedAllMessages(ctx, options, filter) {
|
|
|
3370
3415
|
await updateMessageEmbeddingOp(ctx, message.uniqueId, embedding, embeddingModel);
|
|
3371
3416
|
embeddedCount++;
|
|
3372
3417
|
} catch (error) {
|
|
3418
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3373
3419
|
getLogger().error(`Failed to embed message ${message.uniqueId}:`, error);
|
|
3374
3420
|
}
|
|
3375
3421
|
}
|
|
@@ -3457,6 +3503,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3457
3503
|
}
|
|
3458
3504
|
}
|
|
3459
3505
|
} catch (error) {
|
|
3506
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3460
3507
|
getLogger().error("Failed to batch-embed short messages:", error);
|
|
3461
3508
|
}
|
|
3462
3509
|
}
|
|
@@ -3473,6 +3520,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3473
3520
|
await updateMessageChunksOp(ctx, msg.uniqueId, messageChunks, embeddingModel);
|
|
3474
3521
|
embeddedCount++;
|
|
3475
3522
|
} catch (error) {
|
|
3523
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3476
3524
|
getLogger().error(`Failed to embed message ${msg.uniqueId}:`, error);
|
|
3477
3525
|
}
|
|
3478
3526
|
}
|
|
@@ -4667,7 +4715,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
4667
4715
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
4668
4716
|
);
|
|
4669
4717
|
}
|
|
4670
|
-
const { recall: recall2 } = await import("./recall-
|
|
4718
|
+
const { recall: recall2 } = await import("./recall-EMFBX3WU.mjs");
|
|
4671
4719
|
const result = await recall2(
|
|
4672
4720
|
query,
|
|
4673
4721
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|
package/dist/expo/index.cjs
CHANGED
|
@@ -2265,50 +2265,84 @@ async function getMessagesPageOp(ctx, convId, opts) {
|
|
|
2265
2265
|
)
|
|
2266
2266
|
);
|
|
2267
2267
|
}
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2268
|
+
function narrowSkeletonRow(raw) {
|
|
2269
|
+
return {
|
|
2270
|
+
id: raw.id,
|
|
2271
|
+
message_id: raw.message_id,
|
|
2272
|
+
conversation_id: raw.conversation_id,
|
|
2273
|
+
role: raw.role,
|
|
2274
|
+
created_at: raw.created_at,
|
|
2275
|
+
parent_message_id: raw.parent_message_id ?? null,
|
|
2276
|
+
model: raw.model ?? null,
|
|
2277
|
+
content: raw.content ?? null
|
|
2278
|
+
};
|
|
2279
|
+
}
|
|
2280
|
+
async function fetchThreadSkeletonRawPaged(collection, convId, pageSize = SKELETON_PAGE_SIZE) {
|
|
2281
|
+
const all = [];
|
|
2282
|
+
let cursor;
|
|
2283
|
+
for (; ; ) {
|
|
2284
|
+
const clauses = [import_watermelondb.Q.where("conversation_id", convId)];
|
|
2285
|
+
if (cursor) {
|
|
2286
|
+
clauses.push(
|
|
2287
|
+
import_watermelondb.Q.or(
|
|
2288
|
+
import_watermelondb.Q.where("message_id", import_watermelondb.Q.gt(cursor.messageId)),
|
|
2289
|
+
import_watermelondb.Q.and(import_watermelondb.Q.where("message_id", cursor.messageId), import_watermelondb.Q.where("id", import_watermelondb.Q.gt(cursor.id)))
|
|
2290
|
+
)
|
|
2291
|
+
);
|
|
2291
2292
|
}
|
|
2293
|
+
const page = await collection.query(...clauses, import_watermelondb.Q.sortBy("message_id", import_watermelondb.Q.asc), import_watermelondb.Q.sortBy("id", import_watermelondb.Q.asc), import_watermelondb.Q.take(pageSize)).unsafeFetchRaw();
|
|
2294
|
+
if (page.length === 0) break;
|
|
2295
|
+
for (const raw of page) all.push(narrowSkeletonRow(raw));
|
|
2296
|
+
if (page.length < pageSize) break;
|
|
2297
|
+
const last = all[all.length - 1];
|
|
2298
|
+
cursor = { messageId: last.message_id, id: last.id };
|
|
2292
2299
|
}
|
|
2300
|
+
return all;
|
|
2301
|
+
}
|
|
2302
|
+
function collectArtifactIndices(rows, roleById) {
|
|
2303
|
+
const indices = [];
|
|
2304
|
+
for (let i = 0; i < rows.length; i++) {
|
|
2305
|
+
const row = rows[i];
|
|
2306
|
+
if (row.role !== "user" || !row.parent_message_id) continue;
|
|
2307
|
+
if (roleById.get(row.parent_message_id) === "user") indices.push(i);
|
|
2308
|
+
}
|
|
2309
|
+
return indices;
|
|
2310
|
+
}
|
|
2311
|
+
async function decryptArtifactContent(skeletons, rows, artifactIndices, ctx) {
|
|
2293
2312
|
const address = ctx.walletAddress;
|
|
2294
|
-
if (artifactIndices.length
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
}
|
|
2302
|
-
|
|
2303
|
-
artifactIndices.map(async (i) => {
|
|
2304
|
-
skeletons[i].content = await decryptField(results[i].content, address);
|
|
2305
|
-
})
|
|
2306
|
-
);
|
|
2307
|
-
} else {
|
|
2308
|
-
for (const i of artifactIndices) {
|
|
2309
|
-
skeletons[i].content = results[i].content;
|
|
2313
|
+
if (artifactIndices.length === 0 || !address) {
|
|
2314
|
+
for (const i of artifactIndices) skeletons[i].content = rows[i].content ?? void 0;
|
|
2315
|
+
return;
|
|
2316
|
+
}
|
|
2317
|
+
if (ctx.signMessage) {
|
|
2318
|
+
try {
|
|
2319
|
+
await requestEncryptionKey(address, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
2320
|
+
} catch (error) {
|
|
2321
|
+
getLogger().warn("Failed to request encryption key for skeleton decryption:", error);
|
|
2310
2322
|
}
|
|
2311
2323
|
}
|
|
2324
|
+
await Promise.all(
|
|
2325
|
+
artifactIndices.map(async (i) => {
|
|
2326
|
+
skeletons[i].content = await decryptField(rows[i].content ?? "", address);
|
|
2327
|
+
})
|
|
2328
|
+
);
|
|
2329
|
+
}
|
|
2330
|
+
async function getMessageSkeletonsOp(ctx, convId) {
|
|
2331
|
+
const rows = await fetchThreadSkeletonRawPaged(ctx.messagesCollection, convId);
|
|
2332
|
+
const roleById = /* @__PURE__ */ new Map();
|
|
2333
|
+
for (const row of rows) roleById.set(row.id, row.role);
|
|
2334
|
+
const skeletons = rows.map((row) => ({
|
|
2335
|
+
uniqueId: row.id,
|
|
2336
|
+
messageId: row.message_id,
|
|
2337
|
+
conversationId: String(row.conversation_id),
|
|
2338
|
+
role: row.role,
|
|
2339
|
+
createdAt: new Date(row.created_at),
|
|
2340
|
+
// WatermelonDB surfaces unset text columns as null at runtime — normalize
|
|
2341
|
+
// to undefined so `parentMessageId ?? undefined` keying works everywhere.
|
|
2342
|
+
parentMessageId: row.parent_message_id ?? void 0,
|
|
2343
|
+
model: row.model ?? void 0
|
|
2344
|
+
}));
|
|
2345
|
+
await decryptArtifactContent(skeletons, rows, collectArtifactIndices(rows, roleById), ctx);
|
|
2312
2346
|
return skeletons;
|
|
2313
2347
|
}
|
|
2314
2348
|
async function clearMessagesOp(ctx, convId) {
|
|
@@ -2646,7 +2680,7 @@ function makeSyntheticStoredConversation(opts, defaultTitle) {
|
|
|
2646
2680
|
isDeleted: false
|
|
2647
2681
|
};
|
|
2648
2682
|
}
|
|
2649
|
-
var import_watermelondb, import_uuid2;
|
|
2683
|
+
var import_watermelondb, import_uuid2, SKELETON_PAGE_SIZE;
|
|
2650
2684
|
var init_operations = __esm({
|
|
2651
2685
|
"src/lib/db/chat/operations.ts"() {
|
|
2652
2686
|
"use strict";
|
|
@@ -2659,6 +2693,7 @@ var init_operations = __esm({
|
|
|
2659
2693
|
init_conversationEncryption();
|
|
2660
2694
|
init_encryption();
|
|
2661
2695
|
init_types2();
|
|
2696
|
+
SKELETON_PAGE_SIZE = 2e3;
|
|
2662
2697
|
}
|
|
2663
2698
|
});
|
|
2664
2699
|
|
|
@@ -2837,6 +2872,13 @@ async function withEmbeddingRetry(call) {
|
|
|
2837
2872
|
if (threw) throw lastThrown;
|
|
2838
2873
|
return last;
|
|
2839
2874
|
}
|
|
2875
|
+
function isFatalEmbeddingError(err) {
|
|
2876
|
+
return err instanceof EmbeddingHttpError && (err.status === 401 || err.status === 402 || err.status === 403);
|
|
2877
|
+
}
|
|
2878
|
+
function embeddingErrorFrom(response) {
|
|
2879
|
+
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
2880
|
+
return new EmbeddingHttpError(message, response.response?.status);
|
|
2881
|
+
}
|
|
2840
2882
|
async function generateEmbedding(text11, options) {
|
|
2841
2883
|
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
2842
2884
|
if (cache) {
|
|
@@ -2868,9 +2910,7 @@ async function generateEmbedding(text11, options) {
|
|
|
2868
2910
|
})
|
|
2869
2911
|
);
|
|
2870
2912
|
if (response.error) {
|
|
2871
|
-
throw
|
|
2872
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
2873
|
-
);
|
|
2913
|
+
throw embeddingErrorFrom(response);
|
|
2874
2914
|
}
|
|
2875
2915
|
if (!response.data?.data?.[0]?.embedding) {
|
|
2876
2916
|
throw new Error("No embedding returned from API");
|
|
@@ -2897,9 +2937,7 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
2897
2937
|
})
|
|
2898
2938
|
);
|
|
2899
2939
|
if (response.error) {
|
|
2900
|
-
throw
|
|
2901
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
2902
|
-
);
|
|
2940
|
+
throw embeddingErrorFrom(response);
|
|
2903
2941
|
}
|
|
2904
2942
|
if (!response.data?.data) {
|
|
2905
2943
|
throw new Error("No embeddings returned from API");
|
|
@@ -3035,6 +3073,7 @@ async function embedAllMessages(ctx, options, filter) {
|
|
|
3035
3073
|
await updateMessageEmbeddingOp(ctx, message.uniqueId, embedding, embeddingModel);
|
|
3036
3074
|
embeddedCount++;
|
|
3037
3075
|
} catch (error) {
|
|
3076
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3038
3077
|
getLogger().error(`Failed to embed message ${message.uniqueId}:`, error);
|
|
3039
3078
|
}
|
|
3040
3079
|
}
|
|
@@ -3122,6 +3161,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3122
3161
|
}
|
|
3123
3162
|
}
|
|
3124
3163
|
} catch (error) {
|
|
3164
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3125
3165
|
getLogger().error("Failed to batch-embed short messages:", error);
|
|
3126
3166
|
}
|
|
3127
3167
|
}
|
|
@@ -3138,12 +3178,13 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3138
3178
|
await updateMessageChunksOp(ctx, msg.uniqueId, messageChunks, embeddingModel);
|
|
3139
3179
|
embeddedCount++;
|
|
3140
3180
|
} catch (error) {
|
|
3181
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3141
3182
|
getLogger().error(`Failed to embed message ${msg.uniqueId}:`, error);
|
|
3142
3183
|
}
|
|
3143
3184
|
}
|
|
3144
3185
|
return embeddedCount;
|
|
3145
3186
|
}
|
|
3146
|
-
var DEFAULT_MIN_CONTENT_LENGTH, EMBED_MAX_ATTEMPTS, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
|
|
3187
|
+
var DEFAULT_MIN_CONTENT_LENGTH, EMBED_MAX_ATTEMPTS, EmbeddingHttpError, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
|
|
3147
3188
|
var init_embeddings = __esm({
|
|
3148
3189
|
"src/lib/memoryEngine/embeddings.ts"() {
|
|
3149
3190
|
"use strict";
|
|
@@ -3155,6 +3196,13 @@ var init_embeddings = __esm({
|
|
|
3155
3196
|
init_constants();
|
|
3156
3197
|
DEFAULT_MIN_CONTENT_LENGTH = 10;
|
|
3157
3198
|
EMBED_MAX_ATTEMPTS = 4;
|
|
3199
|
+
EmbeddingHttpError = class extends Error {
|
|
3200
|
+
constructor(message, status) {
|
|
3201
|
+
super(message);
|
|
3202
|
+
this.name = "EmbeddingHttpError";
|
|
3203
|
+
this.status = status;
|
|
3204
|
+
}
|
|
3205
|
+
};
|
|
3158
3206
|
DEFAULT_EMBEDDING_BATCH_SIZE = 100;
|
|
3159
3207
|
DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
|
|
3160
3208
|
}
|
|
@@ -16734,6 +16782,7 @@ var DatabaseManager = class {
|
|
|
16734
16782
|
from: this.currentWalletAddress,
|
|
16735
16783
|
to: walletAddress
|
|
16736
16784
|
});
|
|
16785
|
+
void this.disposeAdapter(this.database);
|
|
16737
16786
|
this.database = null;
|
|
16738
16787
|
}
|
|
16739
16788
|
if (this.database) {
|
|
@@ -16763,11 +16812,37 @@ var DatabaseManager = class {
|
|
|
16763
16812
|
async resetDatabase() {
|
|
16764
16813
|
const db = this.database;
|
|
16765
16814
|
if (db) {
|
|
16815
|
+
this.database = null;
|
|
16816
|
+
this.currentWalletAddress = void 0;
|
|
16766
16817
|
await db.write(async () => {
|
|
16767
16818
|
await db.unsafeResetDatabase();
|
|
16768
16819
|
});
|
|
16769
|
-
this.
|
|
16770
|
-
|
|
16820
|
+
await this.disposeAdapter(db);
|
|
16821
|
+
}
|
|
16822
|
+
}
|
|
16823
|
+
/**
|
|
16824
|
+
* Best-effort dispose of the adapter backing a Database, if it exposes one.
|
|
16825
|
+
*
|
|
16826
|
+
* OPFS/SQLite adapters use this to terminate their dedicated worker and release
|
|
16827
|
+
* the exclusive SAHPool (+ WASM heap) they hold. The SDK only sees a generic
|
|
16828
|
+
* `DatabaseAdapter`, so we probe `adapter.underlyingAdapter.dispose` rather than
|
|
16829
|
+
* type it. Client-side implementations are refcounted + idempotent, so calling
|
|
16830
|
+
* this is safe even when the adapter factory also disposes.
|
|
16831
|
+
*
|
|
16832
|
+
* Awaitable and never rejects: a sync throw or async rejection from `dispose`
|
|
16833
|
+
* is caught + logged. Awaited on the async `resetDatabase` path so teardown
|
|
16834
|
+
* completes before the caller reopens; fire-and-forget on the synchronous
|
|
16835
|
+
* `getDatabase` path (which cannot block).
|
|
16836
|
+
*/
|
|
16837
|
+
async disposeAdapter(db) {
|
|
16838
|
+
try {
|
|
16839
|
+
const underlying = db.adapter?.underlyingAdapter;
|
|
16840
|
+
await underlying?.dispose?.();
|
|
16841
|
+
} catch (error) {
|
|
16842
|
+
this.logger.warn?.("Adapter dispose failed", {
|
|
16843
|
+
component: "DatabaseManager",
|
|
16844
|
+
error
|
|
16845
|
+
});
|
|
16771
16846
|
}
|
|
16772
16847
|
}
|
|
16773
16848
|
/**
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -6568,6 +6568,21 @@ declare class DatabaseManager {
|
|
|
6568
6568
|
* Reset the current database (useful for logout or testing).
|
|
6569
6569
|
*/
|
|
6570
6570
|
resetDatabase(): Promise<void>;
|
|
6571
|
+
/**
|
|
6572
|
+
* Best-effort dispose of the adapter backing a Database, if it exposes one.
|
|
6573
|
+
*
|
|
6574
|
+
* OPFS/SQLite adapters use this to terminate their dedicated worker and release
|
|
6575
|
+
* the exclusive SAHPool (+ WASM heap) they hold. The SDK only sees a generic
|
|
6576
|
+
* `DatabaseAdapter`, so we probe `adapter.underlyingAdapter.dispose` rather than
|
|
6577
|
+
* type it. Client-side implementations are refcounted + idempotent, so calling
|
|
6578
|
+
* this is safe even when the adapter factory also disposes.
|
|
6579
|
+
*
|
|
6580
|
+
* Awaitable and never rejects: a sync throw or async rejection from `dispose`
|
|
6581
|
+
* is caught + logged. Awaited on the async `resetDatabase` path so teardown
|
|
6582
|
+
* completes before the caller reopens; fire-and-forget on the synchronous
|
|
6583
|
+
* `getDatabase` path (which cannot block).
|
|
6584
|
+
*/
|
|
6585
|
+
private disposeAdapter;
|
|
6571
6586
|
/**
|
|
6572
6587
|
* Check and handle schema migrations for a specific wallet.
|
|
6573
6588
|
* Returns true if a destructive migration is in progress.
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -6568,6 +6568,21 @@ declare class DatabaseManager {
|
|
|
6568
6568
|
* Reset the current database (useful for logout or testing).
|
|
6569
6569
|
*/
|
|
6570
6570
|
resetDatabase(): Promise<void>;
|
|
6571
|
+
/**
|
|
6572
|
+
* Best-effort dispose of the adapter backing a Database, if it exposes one.
|
|
6573
|
+
*
|
|
6574
|
+
* OPFS/SQLite adapters use this to terminate their dedicated worker and release
|
|
6575
|
+
* the exclusive SAHPool (+ WASM heap) they hold. The SDK only sees a generic
|
|
6576
|
+
* `DatabaseAdapter`, so we probe `adapter.underlyingAdapter.dispose` rather than
|
|
6577
|
+
* type it. Client-side implementations are refcounted + idempotent, so calling
|
|
6578
|
+
* this is safe even when the adapter factory also disposes.
|
|
6579
|
+
*
|
|
6580
|
+
* Awaitable and never rejects: a sync throw or async rejection from `dispose`
|
|
6581
|
+
* is caught + logged. Awaited on the async `resetDatabase` path so teardown
|
|
6582
|
+
* completes before the caller reopens; fire-and-forget on the synchronous
|
|
6583
|
+
* `getDatabase` path (which cannot block).
|
|
6584
|
+
*/
|
|
6585
|
+
private disposeAdapter;
|
|
6571
6586
|
/**
|
|
6572
6587
|
* Check and handle schema migrations for a specific wallet.
|
|
6573
6588
|
* Returns true if a destructive migration is in progress.
|
package/dist/expo/index.mjs
CHANGED
|
@@ -79,7 +79,7 @@ import {
|
|
|
79
79
|
updateVaultMemoryOp,
|
|
80
80
|
upsertMessageOp,
|
|
81
81
|
useEncryption
|
|
82
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-OZ357R4P.mjs";
|
|
83
83
|
import {
|
|
84
84
|
PII_PATTERNS,
|
|
85
85
|
PiiRedactor,
|
|
@@ -10004,6 +10004,7 @@ var DatabaseManager = class {
|
|
|
10004
10004
|
from: this.currentWalletAddress,
|
|
10005
10005
|
to: walletAddress
|
|
10006
10006
|
});
|
|
10007
|
+
void this.disposeAdapter(this.database);
|
|
10007
10008
|
this.database = null;
|
|
10008
10009
|
}
|
|
10009
10010
|
if (this.database) {
|
|
@@ -10033,11 +10034,37 @@ var DatabaseManager = class {
|
|
|
10033
10034
|
async resetDatabase() {
|
|
10034
10035
|
const db = this.database;
|
|
10035
10036
|
if (db) {
|
|
10037
|
+
this.database = null;
|
|
10038
|
+
this.currentWalletAddress = void 0;
|
|
10036
10039
|
await db.write(async () => {
|
|
10037
10040
|
await db.unsafeResetDatabase();
|
|
10038
10041
|
});
|
|
10039
|
-
this.
|
|
10040
|
-
|
|
10042
|
+
await this.disposeAdapter(db);
|
|
10043
|
+
}
|
|
10044
|
+
}
|
|
10045
|
+
/**
|
|
10046
|
+
* Best-effort dispose of the adapter backing a Database, if it exposes one.
|
|
10047
|
+
*
|
|
10048
|
+
* OPFS/SQLite adapters use this to terminate their dedicated worker and release
|
|
10049
|
+
* the exclusive SAHPool (+ WASM heap) they hold. The SDK only sees a generic
|
|
10050
|
+
* `DatabaseAdapter`, so we probe `adapter.underlyingAdapter.dispose` rather than
|
|
10051
|
+
* type it. Client-side implementations are refcounted + idempotent, so calling
|
|
10052
|
+
* this is safe even when the adapter factory also disposes.
|
|
10053
|
+
*
|
|
10054
|
+
* Awaitable and never rejects: a sync throw or async rejection from `dispose`
|
|
10055
|
+
* is caught + logged. Awaited on the async `resetDatabase` path so teardown
|
|
10056
|
+
* completes before the caller reopens; fire-and-forget on the synchronous
|
|
10057
|
+
* `getDatabase` path (which cannot block).
|
|
10058
|
+
*/
|
|
10059
|
+
async disposeAdapter(db) {
|
|
10060
|
+
try {
|
|
10061
|
+
const underlying = db.adapter?.underlyingAdapter;
|
|
10062
|
+
await underlying?.dispose?.();
|
|
10063
|
+
} catch (error) {
|
|
10064
|
+
this.logger.warn?.("Adapter dispose failed", {
|
|
10065
|
+
component: "DatabaseManager",
|
|
10066
|
+
error
|
|
10067
|
+
});
|
|
10041
10068
|
}
|
|
10042
10069
|
}
|
|
10043
10070
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -2095,6 +2095,17 @@ async function withEmbeddingRetry(call) {
|
|
|
2095
2095
|
if (threw) throw lastThrown;
|
|
2096
2096
|
return last;
|
|
2097
2097
|
}
|
|
2098
|
+
var EmbeddingHttpError = class extends Error {
|
|
2099
|
+
constructor(message, status) {
|
|
2100
|
+
super(message);
|
|
2101
|
+
this.name = "EmbeddingHttpError";
|
|
2102
|
+
this.status = status;
|
|
2103
|
+
}
|
|
2104
|
+
};
|
|
2105
|
+
function embeddingErrorFrom(response) {
|
|
2106
|
+
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
2107
|
+
return new EmbeddingHttpError(message, response.response?.status);
|
|
2108
|
+
}
|
|
2098
2109
|
async function generateEmbedding(text, options) {
|
|
2099
2110
|
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
2100
2111
|
if (cache) {
|
|
@@ -2126,9 +2137,7 @@ async function generateEmbedding(text, options) {
|
|
|
2126
2137
|
})
|
|
2127
2138
|
);
|
|
2128
2139
|
if (response.error) {
|
|
2129
|
-
throw
|
|
2130
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
2131
|
-
);
|
|
2140
|
+
throw embeddingErrorFrom(response);
|
|
2132
2141
|
}
|
|
2133
2142
|
if (!response.data?.data?.[0]?.embedding) {
|
|
2134
2143
|
throw new Error("No embedding returned from API");
|
|
@@ -2157,9 +2166,7 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
2157
2166
|
})
|
|
2158
2167
|
);
|
|
2159
2168
|
if (response.error) {
|
|
2160
|
-
throw
|
|
2161
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
2162
|
-
);
|
|
2169
|
+
throw embeddingErrorFrom(response);
|
|
2163
2170
|
}
|
|
2164
2171
|
if (!response.data?.data) {
|
|
2165
2172
|
throw new Error("No embeddings returned from API");
|
package/dist/index.mjs
CHANGED
|
@@ -1904,6 +1904,17 @@ async function withEmbeddingRetry(call) {
|
|
|
1904
1904
|
if (threw) throw lastThrown;
|
|
1905
1905
|
return last;
|
|
1906
1906
|
}
|
|
1907
|
+
var EmbeddingHttpError = class extends Error {
|
|
1908
|
+
constructor(message, status) {
|
|
1909
|
+
super(message);
|
|
1910
|
+
this.name = "EmbeddingHttpError";
|
|
1911
|
+
this.status = status;
|
|
1912
|
+
}
|
|
1913
|
+
};
|
|
1914
|
+
function embeddingErrorFrom(response) {
|
|
1915
|
+
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
1916
|
+
return new EmbeddingHttpError(message, response.response?.status);
|
|
1917
|
+
}
|
|
1907
1918
|
async function generateEmbedding(text, options) {
|
|
1908
1919
|
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
1909
1920
|
if (cache) {
|
|
@@ -1935,9 +1946,7 @@ async function generateEmbedding(text, options) {
|
|
|
1935
1946
|
})
|
|
1936
1947
|
);
|
|
1937
1948
|
if (response.error) {
|
|
1938
|
-
throw
|
|
1939
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
1940
|
-
);
|
|
1949
|
+
throw embeddingErrorFrom(response);
|
|
1941
1950
|
}
|
|
1942
1951
|
if (!response.data?.data?.[0]?.embedding) {
|
|
1943
1952
|
throw new Error("No embedding returned from API");
|
|
@@ -1966,9 +1975,7 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
1966
1975
|
})
|
|
1967
1976
|
);
|
|
1968
1977
|
if (response.error) {
|
|
1969
|
-
throw
|
|
1970
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
1971
|
-
);
|
|
1978
|
+
throw embeddingErrorFrom(response);
|
|
1972
1979
|
}
|
|
1973
1980
|
if (!response.data?.data) {
|
|
1974
1981
|
throw new Error("No embeddings returned from API");
|