@anuma/sdk 7.0.0 → 7.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 +137 -9
- package/dist/expo/index.d.mts +8 -1
- package/dist/expo/index.d.ts +8 -1
- package/dist/expo/index.mjs +136 -9
- package/dist/index.cjs +188 -182
- package/dist/index.mjs +188 -182
- package/dist/react/index.cjs +137 -9
- package/dist/react/index.d.mts +8 -1
- package/dist/react/index.d.ts +8 -1
- package/dist/react/index.mjs +136 -9
- package/dist/server/index.cjs +126 -5
- package/dist/server/index.d.mts +8 -1
- package/dist/server/index.d.ts +8 -1
- package/dist/server/index.mjs +125 -5
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1148,6 +1148,192 @@ function attachFileContextToLastUserMessage(messages, fileContext) {
|
|
|
1148
1148
|
return result;
|
|
1149
1149
|
}
|
|
1150
1150
|
|
|
1151
|
+
// src/lib/logger.ts
|
|
1152
|
+
var consoleLogger = {
|
|
1153
|
+
debug: console.log.bind(console),
|
|
1154
|
+
info: console.info.bind(console),
|
|
1155
|
+
warn: console.warn.bind(console),
|
|
1156
|
+
error: console.error.bind(console)
|
|
1157
|
+
};
|
|
1158
|
+
var noopLogger = {
|
|
1159
|
+
debug: () => {
|
|
1160
|
+
},
|
|
1161
|
+
info: () => {
|
|
1162
|
+
},
|
|
1163
|
+
warn: () => {
|
|
1164
|
+
},
|
|
1165
|
+
error: () => {
|
|
1166
|
+
}
|
|
1167
|
+
};
|
|
1168
|
+
var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
|
|
1169
|
+
var loggerGlobal = globalThis;
|
|
1170
|
+
var fallbackLoggerState = { logger: consoleLogger };
|
|
1171
|
+
var fallbackWarned = false;
|
|
1172
|
+
function getLoggerState() {
|
|
1173
|
+
try {
|
|
1174
|
+
return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
|
|
1175
|
+
} catch {
|
|
1176
|
+
if (!fallbackWarned) {
|
|
1177
|
+
fallbackWarned = true;
|
|
1178
|
+
fallbackLoggerState.logger.warn(
|
|
1179
|
+
"@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
return fallbackLoggerState;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
function setLogger(logger) {
|
|
1186
|
+
getLoggerState().logger = logger;
|
|
1187
|
+
}
|
|
1188
|
+
function getLogger() {
|
|
1189
|
+
return getLoggerState().logger;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
// src/react/useEncryption.ts
|
|
1193
|
+
var EncryptionKeyMissingError = class extends Error {
|
|
1194
|
+
constructor(address, version) {
|
|
1195
|
+
super(
|
|
1196
|
+
`Encryption key (${version}) not found for ${address}. Please sign a message to generate your encryption key.`
|
|
1197
|
+
);
|
|
1198
|
+
this.name = "EncryptionKeyMissingError";
|
|
1199
|
+
this.address = address;
|
|
1200
|
+
this.version = version;
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
var encryptionKeyStore = /* @__PURE__ */ new Map();
|
|
1204
|
+
var cryptoKeyCache = /* @__PURE__ */ new Map();
|
|
1205
|
+
var clearAllEncryptionStateCallbacks = /* @__PURE__ */ new Set();
|
|
1206
|
+
function onClearAllEncryptionState(callback) {
|
|
1207
|
+
clearAllEncryptionStateCallbacks.add(callback);
|
|
1208
|
+
return () => {
|
|
1209
|
+
clearAllEncryptionStateCallbacks.delete(callback);
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
function getStoredKeyByVersion(address, version) {
|
|
1213
|
+
const keys = encryptionKeyStore.get(address);
|
|
1214
|
+
if (!keys) return null;
|
|
1215
|
+
const value = version === "v2" ? keys.legacy : keys.current;
|
|
1216
|
+
return value ?? null;
|
|
1217
|
+
}
|
|
1218
|
+
function hexNibble(code) {
|
|
1219
|
+
if (code >= 48 && code <= 57) return code - 48;
|
|
1220
|
+
if (code >= 65 && code <= 70) return code - 55;
|
|
1221
|
+
if (code >= 97 && code <= 102) return code - 87;
|
|
1222
|
+
return -1;
|
|
1223
|
+
}
|
|
1224
|
+
function hexToBytes(hex) {
|
|
1225
|
+
if (typeof hex !== "string") {
|
|
1226
|
+
throw new TypeError(
|
|
1227
|
+
"hexToBytes: expected a hex string. Pass raw signature bytes to deriveKeyFromSignatureBytes instead of stringifying them."
|
|
1228
|
+
);
|
|
1229
|
+
}
|
|
1230
|
+
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1231
|
+
if (cleanHex.length === 0 || cleanHex.length % 2 !== 0) {
|
|
1232
|
+
throw new Error(
|
|
1233
|
+
`hexToBytes: invalid hex string (expected a non-empty even length, got ${cleanHex.length})`
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
const bytes = new Uint8Array(cleanHex.length / 2);
|
|
1237
|
+
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
1238
|
+
const hi = hexNibble(cleanHex.charCodeAt(i));
|
|
1239
|
+
const lo = hexNibble(cleanHex.charCodeAt(i + 1));
|
|
1240
|
+
if (hi < 0 || lo < 0) {
|
|
1241
|
+
throw new Error(`hexToBytes: invalid hex string (non-hex character at index ${i})`);
|
|
1242
|
+
}
|
|
1243
|
+
bytes[i / 2] = hi << 4 | lo;
|
|
1244
|
+
}
|
|
1245
|
+
return bytes;
|
|
1246
|
+
}
|
|
1247
|
+
var SHARED_TEXT_ENCODER = new TextEncoder();
|
|
1248
|
+
var SHARED_TEXT_DECODER = new TextDecoder();
|
|
1249
|
+
async function getEncryptionKey(address, version = "v3") {
|
|
1250
|
+
const cacheKey = `${address}:${version}`;
|
|
1251
|
+
const cachedKey = cryptoKeyCache.get(cacheKey);
|
|
1252
|
+
if (cachedKey) {
|
|
1253
|
+
return cachedKey;
|
|
1254
|
+
}
|
|
1255
|
+
const keyHex = getStoredKeyByVersion(address, version);
|
|
1256
|
+
if (!keyHex) {
|
|
1257
|
+
throw new EncryptionKeyMissingError(address, version);
|
|
1258
|
+
}
|
|
1259
|
+
const keyBytes = hexToBytes(keyHex);
|
|
1260
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
1261
|
+
"raw",
|
|
1262
|
+
keyBytes.buffer,
|
|
1263
|
+
{ name: "AES-GCM" },
|
|
1264
|
+
false,
|
|
1265
|
+
["encrypt", "decrypt"]
|
|
1266
|
+
);
|
|
1267
|
+
cryptoKeyCache.set(cacheKey, cryptoKey);
|
|
1268
|
+
return cryptoKey;
|
|
1269
|
+
}
|
|
1270
|
+
async function decryptData(encryptedHex, address, version = "v3") {
|
|
1271
|
+
const key = await getEncryptionKey(address, version);
|
|
1272
|
+
return decryptDataWithKey(encryptedHex, key);
|
|
1273
|
+
}
|
|
1274
|
+
function hasEncryptionKey(address, version) {
|
|
1275
|
+
return getStoredKeyByVersion(address, version ?? "v3") !== null;
|
|
1276
|
+
}
|
|
1277
|
+
async function decryptDataWithKey(encryptedHex, key) {
|
|
1278
|
+
const combined = hexToBytes(encryptedHex);
|
|
1279
|
+
const iv = combined.subarray(0, 12);
|
|
1280
|
+
const encryptedData = combined.subarray(12);
|
|
1281
|
+
const decryptedData = await crypto.subtle.decrypt(
|
|
1282
|
+
{
|
|
1283
|
+
name: "AES-GCM",
|
|
1284
|
+
iv
|
|
1285
|
+
},
|
|
1286
|
+
key,
|
|
1287
|
+
encryptedData
|
|
1288
|
+
);
|
|
1289
|
+
return SHARED_TEXT_DECODER.decode(decryptedData);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
// src/lib/db/encryption-utils.ts
|
|
1293
|
+
function isEncrypted(value) {
|
|
1294
|
+
const prefix = value.startsWith("enc:v3:") ? "enc:v3:" : value.startsWith("enc:v2:") ? "enc:v2:" : null;
|
|
1295
|
+
if (!prefix) return false;
|
|
1296
|
+
const payload = value.slice(prefix.length);
|
|
1297
|
+
return payload.length >= 56 && /^[0-9a-f]+$/i.test(payload);
|
|
1298
|
+
}
|
|
1299
|
+
function hasEncryptedToolPayload(event) {
|
|
1300
|
+
return [event.arguments, event.output].some(
|
|
1301
|
+
(value) => typeof value === "string" && isEncrypted(value)
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1304
|
+
function detectEncryptionVersion(value) {
|
|
1305
|
+
if (value.startsWith("enc:v3:")) {
|
|
1306
|
+
return { version: "v3", encryptedData: value.slice("enc:v3:".length) };
|
|
1307
|
+
}
|
|
1308
|
+
if (value.startsWith("enc:v2:")) {
|
|
1309
|
+
return { version: "v2", encryptedData: value.slice("enc:v2:".length) };
|
|
1310
|
+
}
|
|
1311
|
+
return null;
|
|
1312
|
+
}
|
|
1313
|
+
async function decryptFieldDetailed(value, address) {
|
|
1314
|
+
if (!value) return { status: "plaintext", value };
|
|
1315
|
+
const detected = detectEncryptionVersion(value);
|
|
1316
|
+
if (!detected) return { status: "plaintext", value };
|
|
1317
|
+
if (detected.encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(detected.encryptedData)) {
|
|
1318
|
+
return { status: "invalid_payload", value, version: detected.version };
|
|
1319
|
+
}
|
|
1320
|
+
try {
|
|
1321
|
+
const plaintext = await decryptData(detected.encryptedData, address, detected.version);
|
|
1322
|
+
return { status: "ok", value: plaintext, version: detected.version };
|
|
1323
|
+
} catch (error) {
|
|
1324
|
+
if (error instanceof EncryptionKeyMissingError) {
|
|
1325
|
+
getLogger().warn("Failed to decrypt field (key missing for version):", error.message);
|
|
1326
|
+
return { status: "key_missing", value, version: detected.version };
|
|
1327
|
+
}
|
|
1328
|
+
getLogger().warn("Failed to decrypt field (auth mismatch or crypto error):", error);
|
|
1329
|
+
return { status: "auth_mismatch", value, version: detected.version };
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
async function decryptField(value, address) {
|
|
1333
|
+
const result = await decryptFieldDetailed(value, address);
|
|
1334
|
+
return result.value;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1151
1337
|
// src/lib/chat/reservationReceipts.ts
|
|
1152
1338
|
var ACTIONS = [
|
|
1153
1339
|
{
|
|
@@ -1169,7 +1355,8 @@ function extractReservationReceipts(toolCallEvents) {
|
|
|
1169
1355
|
for (const event of toolCallEvents ?? []) {
|
|
1170
1356
|
const action = ACTIONS.find((a) => event.name?.endsWith(a.tool));
|
|
1171
1357
|
const output = event.output ?? "";
|
|
1172
|
-
if (!action || !output || NOT_AN_ATTEMPT.test(output))
|
|
1358
|
+
if (!action || !output || hasEncryptedToolPayload(event) || NOT_AN_ATTEMPT.test(output))
|
|
1359
|
+
continue;
|
|
1173
1360
|
const kept = latest.get(action.kind)?.status;
|
|
1174
1361
|
if (kept === "made") continue;
|
|
1175
1362
|
const receipt = toReceipt(action, event.arguments ?? "", output);
|
|
@@ -1418,187 +1605,6 @@ function getImageModel(r) {
|
|
|
1418
1605
|
return r.image_model;
|
|
1419
1606
|
}
|
|
1420
1607
|
|
|
1421
|
-
// src/lib/logger.ts
|
|
1422
|
-
var consoleLogger = {
|
|
1423
|
-
debug: console.log.bind(console),
|
|
1424
|
-
info: console.info.bind(console),
|
|
1425
|
-
warn: console.warn.bind(console),
|
|
1426
|
-
error: console.error.bind(console)
|
|
1427
|
-
};
|
|
1428
|
-
var noopLogger = {
|
|
1429
|
-
debug: () => {
|
|
1430
|
-
},
|
|
1431
|
-
info: () => {
|
|
1432
|
-
},
|
|
1433
|
-
warn: () => {
|
|
1434
|
-
},
|
|
1435
|
-
error: () => {
|
|
1436
|
-
}
|
|
1437
|
-
};
|
|
1438
|
-
var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
|
|
1439
|
-
var loggerGlobal = globalThis;
|
|
1440
|
-
var fallbackLoggerState = { logger: consoleLogger };
|
|
1441
|
-
var fallbackWarned = false;
|
|
1442
|
-
function getLoggerState() {
|
|
1443
|
-
try {
|
|
1444
|
-
return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
|
|
1445
|
-
} catch {
|
|
1446
|
-
if (!fallbackWarned) {
|
|
1447
|
-
fallbackWarned = true;
|
|
1448
|
-
fallbackLoggerState.logger.warn(
|
|
1449
|
-
"@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
|
|
1450
|
-
);
|
|
1451
|
-
}
|
|
1452
|
-
return fallbackLoggerState;
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
function setLogger(logger) {
|
|
1456
|
-
getLoggerState().logger = logger;
|
|
1457
|
-
}
|
|
1458
|
-
function getLogger() {
|
|
1459
|
-
return getLoggerState().logger;
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
// src/react/useEncryption.ts
|
|
1463
|
-
var EncryptionKeyMissingError = class extends Error {
|
|
1464
|
-
constructor(address, version) {
|
|
1465
|
-
super(
|
|
1466
|
-
`Encryption key (${version}) not found for ${address}. Please sign a message to generate your encryption key.`
|
|
1467
|
-
);
|
|
1468
|
-
this.name = "EncryptionKeyMissingError";
|
|
1469
|
-
this.address = address;
|
|
1470
|
-
this.version = version;
|
|
1471
|
-
}
|
|
1472
|
-
};
|
|
1473
|
-
var encryptionKeyStore = /* @__PURE__ */ new Map();
|
|
1474
|
-
var cryptoKeyCache = /* @__PURE__ */ new Map();
|
|
1475
|
-
var clearAllEncryptionStateCallbacks = /* @__PURE__ */ new Set();
|
|
1476
|
-
function onClearAllEncryptionState(callback) {
|
|
1477
|
-
clearAllEncryptionStateCallbacks.add(callback);
|
|
1478
|
-
return () => {
|
|
1479
|
-
clearAllEncryptionStateCallbacks.delete(callback);
|
|
1480
|
-
};
|
|
1481
|
-
}
|
|
1482
|
-
function getStoredKeyByVersion(address, version) {
|
|
1483
|
-
const keys = encryptionKeyStore.get(address);
|
|
1484
|
-
if (!keys) return null;
|
|
1485
|
-
const value = version === "v2" ? keys.legacy : keys.current;
|
|
1486
|
-
return value ?? null;
|
|
1487
|
-
}
|
|
1488
|
-
function hexNibble(code) {
|
|
1489
|
-
if (code >= 48 && code <= 57) return code - 48;
|
|
1490
|
-
if (code >= 65 && code <= 70) return code - 55;
|
|
1491
|
-
if (code >= 97 && code <= 102) return code - 87;
|
|
1492
|
-
return -1;
|
|
1493
|
-
}
|
|
1494
|
-
function hexToBytes(hex) {
|
|
1495
|
-
if (typeof hex !== "string") {
|
|
1496
|
-
throw new TypeError(
|
|
1497
|
-
"hexToBytes: expected a hex string. Pass raw signature bytes to deriveKeyFromSignatureBytes instead of stringifying them."
|
|
1498
|
-
);
|
|
1499
|
-
}
|
|
1500
|
-
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1501
|
-
if (cleanHex.length === 0 || cleanHex.length % 2 !== 0) {
|
|
1502
|
-
throw new Error(
|
|
1503
|
-
`hexToBytes: invalid hex string (expected a non-empty even length, got ${cleanHex.length})`
|
|
1504
|
-
);
|
|
1505
|
-
}
|
|
1506
|
-
const bytes = new Uint8Array(cleanHex.length / 2);
|
|
1507
|
-
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
1508
|
-
const hi = hexNibble(cleanHex.charCodeAt(i));
|
|
1509
|
-
const lo = hexNibble(cleanHex.charCodeAt(i + 1));
|
|
1510
|
-
if (hi < 0 || lo < 0) {
|
|
1511
|
-
throw new Error(`hexToBytes: invalid hex string (non-hex character at index ${i})`);
|
|
1512
|
-
}
|
|
1513
|
-
bytes[i / 2] = hi << 4 | lo;
|
|
1514
|
-
}
|
|
1515
|
-
return bytes;
|
|
1516
|
-
}
|
|
1517
|
-
var SHARED_TEXT_ENCODER = new TextEncoder();
|
|
1518
|
-
var SHARED_TEXT_DECODER = new TextDecoder();
|
|
1519
|
-
async function getEncryptionKey(address, version = "v3") {
|
|
1520
|
-
const cacheKey = `${address}:${version}`;
|
|
1521
|
-
const cachedKey = cryptoKeyCache.get(cacheKey);
|
|
1522
|
-
if (cachedKey) {
|
|
1523
|
-
return cachedKey;
|
|
1524
|
-
}
|
|
1525
|
-
const keyHex = getStoredKeyByVersion(address, version);
|
|
1526
|
-
if (!keyHex) {
|
|
1527
|
-
throw new EncryptionKeyMissingError(address, version);
|
|
1528
|
-
}
|
|
1529
|
-
const keyBytes = hexToBytes(keyHex);
|
|
1530
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
1531
|
-
"raw",
|
|
1532
|
-
keyBytes.buffer,
|
|
1533
|
-
{ name: "AES-GCM" },
|
|
1534
|
-
false,
|
|
1535
|
-
["encrypt", "decrypt"]
|
|
1536
|
-
);
|
|
1537
|
-
cryptoKeyCache.set(cacheKey, cryptoKey);
|
|
1538
|
-
return cryptoKey;
|
|
1539
|
-
}
|
|
1540
|
-
async function decryptData(encryptedHex, address, version = "v3") {
|
|
1541
|
-
const key = await getEncryptionKey(address, version);
|
|
1542
|
-
return decryptDataWithKey(encryptedHex, key);
|
|
1543
|
-
}
|
|
1544
|
-
function hasEncryptionKey(address, version) {
|
|
1545
|
-
return getStoredKeyByVersion(address, version ?? "v3") !== null;
|
|
1546
|
-
}
|
|
1547
|
-
async function decryptDataWithKey(encryptedHex, key) {
|
|
1548
|
-
const combined = hexToBytes(encryptedHex);
|
|
1549
|
-
const iv = combined.subarray(0, 12);
|
|
1550
|
-
const encryptedData = combined.subarray(12);
|
|
1551
|
-
const decryptedData = await crypto.subtle.decrypt(
|
|
1552
|
-
{
|
|
1553
|
-
name: "AES-GCM",
|
|
1554
|
-
iv
|
|
1555
|
-
},
|
|
1556
|
-
key,
|
|
1557
|
-
encryptedData
|
|
1558
|
-
);
|
|
1559
|
-
return SHARED_TEXT_DECODER.decode(decryptedData);
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
// src/lib/db/encryption-utils.ts
|
|
1563
|
-
function isEncrypted(value) {
|
|
1564
|
-
const prefix = value.startsWith("enc:v3:") ? "enc:v3:" : value.startsWith("enc:v2:") ? "enc:v2:" : null;
|
|
1565
|
-
if (!prefix) return false;
|
|
1566
|
-
const payload = value.slice(prefix.length);
|
|
1567
|
-
return payload.length >= 56 && /^[0-9a-f]+$/i.test(payload);
|
|
1568
|
-
}
|
|
1569
|
-
function detectEncryptionVersion(value) {
|
|
1570
|
-
if (value.startsWith("enc:v3:")) {
|
|
1571
|
-
return { version: "v3", encryptedData: value.slice("enc:v3:".length) };
|
|
1572
|
-
}
|
|
1573
|
-
if (value.startsWith("enc:v2:")) {
|
|
1574
|
-
return { version: "v2", encryptedData: value.slice("enc:v2:".length) };
|
|
1575
|
-
}
|
|
1576
|
-
return null;
|
|
1577
|
-
}
|
|
1578
|
-
async function decryptFieldDetailed(value, address) {
|
|
1579
|
-
if (!value) return { status: "plaintext", value };
|
|
1580
|
-
const detected = detectEncryptionVersion(value);
|
|
1581
|
-
if (!detected) return { status: "plaintext", value };
|
|
1582
|
-
if (detected.encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(detected.encryptedData)) {
|
|
1583
|
-
return { status: "invalid_payload", value, version: detected.version };
|
|
1584
|
-
}
|
|
1585
|
-
try {
|
|
1586
|
-
const plaintext = await decryptData(detected.encryptedData, address, detected.version);
|
|
1587
|
-
return { status: "ok", value: plaintext, version: detected.version };
|
|
1588
|
-
} catch (error) {
|
|
1589
|
-
if (error instanceof EncryptionKeyMissingError) {
|
|
1590
|
-
getLogger().warn("Failed to decrypt field (key missing for version):", error.message);
|
|
1591
|
-
return { status: "key_missing", value, version: detected.version };
|
|
1592
|
-
}
|
|
1593
|
-
getLogger().warn("Failed to decrypt field (auth mismatch or crypto error):", error);
|
|
1594
|
-
return { status: "auth_mismatch", value, version: detected.version };
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
async function decryptField(value, address) {
|
|
1598
|
-
const result = await decryptFieldDetailed(value, address);
|
|
1599
|
-
return result.value;
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
1608
|
// src/lib/db/chat/lazyDecrypt.ts
|
|
1603
1609
|
var LRU_CAPACITY = 256;
|
|
1604
1610
|
var titleCache = /* @__PURE__ */ new Map();
|
package/dist/react/index.cjs
CHANGED
|
@@ -1566,6 +1566,7 @@ __export(index_exports, {
|
|
|
1566
1566
|
encryptDataBatch: () => encryptDataBatch,
|
|
1567
1567
|
encryptDataBytes: () => encryptDataBytes,
|
|
1568
1568
|
encryptDataWithKey: () => encryptDataWithKey,
|
|
1569
|
+
encryptToolCallEventsOp: () => encryptToolCallEventsOp,
|
|
1569
1570
|
ensureDefaultFoldersOp: () => ensureDefaultFoldersOp,
|
|
1570
1571
|
expandToolSetsAdditive: () => expandToolSetsAdditive,
|
|
1571
1572
|
exportElementToPdf: () => exportElementToPdf,
|
|
@@ -3593,6 +3594,11 @@ function isEncrypted(value) {
|
|
|
3593
3594
|
const payload = value.slice(prefix.length);
|
|
3594
3595
|
return payload.length >= 56 && /^[0-9a-f]+$/i.test(payload);
|
|
3595
3596
|
}
|
|
3597
|
+
function hasEncryptedToolPayload(event) {
|
|
3598
|
+
return [event.arguments, event.output].some(
|
|
3599
|
+
(value) => typeof value === "string" && isEncrypted(value)
|
|
3600
|
+
);
|
|
3601
|
+
}
|
|
3596
3602
|
function detectEncryptionVersion(value) {
|
|
3597
3603
|
if (value.startsWith("enc:v3:")) {
|
|
3598
3604
|
return { version: "v3", encryptedData: value.slice("enc:v3:".length) };
|
|
@@ -3730,6 +3736,12 @@ async function encryptMessageFields(message, address, signMessage, embeddedWalle
|
|
|
3730
3736
|
const encryptedChunks = msg.chunks ? await encryptJsonField(msg.chunks, address, signMessage, embeddedWalletSigner, true) : void 0;
|
|
3731
3737
|
const encryptedSources = msg.sources ? await encryptJsonField(msg.sources, address, signMessage, embeddedWalletSigner, true) : void 0;
|
|
3732
3738
|
const encryptedThoughtProcess = msg.thoughtProcess ? await encryptJsonField(msg.thoughtProcess, address, signMessage, embeddedWalletSigner, true) : void 0;
|
|
3739
|
+
const encryptedToolCallEvents = Array.isArray(msg.toolCallEvents) ? await encryptToolCallEvents(
|
|
3740
|
+
msg.toolCallEvents,
|
|
3741
|
+
address,
|
|
3742
|
+
signMessage,
|
|
3743
|
+
embeddedWalletSigner
|
|
3744
|
+
) : void 0;
|
|
3733
3745
|
return {
|
|
3734
3746
|
...message,
|
|
3735
3747
|
...encryptedContent !== void 0 && { content: encryptedContent },
|
|
@@ -3737,13 +3749,31 @@ async function encryptMessageFields(message, address, signMessage, embeddedWalle
|
|
|
3737
3749
|
...encryptedVector !== void 0 && { vector: encryptedVector },
|
|
3738
3750
|
...encryptedChunks !== void 0 && { chunks: encryptedChunks },
|
|
3739
3751
|
...encryptedSources !== void 0 && { sources: encryptedSources },
|
|
3740
|
-
...encryptedThoughtProcess !== void 0 && { thoughtProcess: encryptedThoughtProcess }
|
|
3752
|
+
...encryptedThoughtProcess !== void 0 && { thoughtProcess: encryptedThoughtProcess },
|
|
3753
|
+
...encryptedToolCallEvents !== void 0 && { toolCallEvents: encryptedToolCallEvents }
|
|
3741
3754
|
};
|
|
3742
3755
|
} catch (error) {
|
|
3743
3756
|
getLogger().warn("Failed to encrypt message fields:", error);
|
|
3744
3757
|
throw error;
|
|
3745
3758
|
}
|
|
3746
3759
|
}
|
|
3760
|
+
function mapToolCallPayloads(events, transform) {
|
|
3761
|
+
return Promise.all(
|
|
3762
|
+
events.map(async (event) => {
|
|
3763
|
+
if (!event || typeof event !== "object") return event;
|
|
3764
|
+
const mapped = { ...event };
|
|
3765
|
+
if (typeof event.arguments === "string") mapped.arguments = await transform(event.arguments);
|
|
3766
|
+
if (typeof event.output === "string") mapped.output = await transform(event.output);
|
|
3767
|
+
return mapped;
|
|
3768
|
+
})
|
|
3769
|
+
);
|
|
3770
|
+
}
|
|
3771
|
+
function encryptToolCallEvents(events, address, signMessage, embeddedWalletSigner) {
|
|
3772
|
+
return mapToolCallPayloads(
|
|
3773
|
+
events,
|
|
3774
|
+
(value) => encryptField(value, address, signMessage, embeddedWalletSigner, true)
|
|
3775
|
+
);
|
|
3776
|
+
}
|
|
3747
3777
|
async function decryptMaybeJsonFieldDetailed(value, address) {
|
|
3748
3778
|
if (value === void 0) return { value: void 0, status: "plaintext" };
|
|
3749
3779
|
if (value === null) return { value, status: "plaintext" };
|
|
@@ -3829,6 +3859,10 @@ async function assembleDecryptedMessage(message, address) {
|
|
|
3829
3859
|
message.thoughtProcess,
|
|
3830
3860
|
address
|
|
3831
3861
|
);
|
|
3862
|
+
const toolCallEventsResult = await decryptMaybeJsonFieldDetailed(
|
|
3863
|
+
message.toolCallEvents,
|
|
3864
|
+
address
|
|
3865
|
+
);
|
|
3832
3866
|
let decryptionStatus;
|
|
3833
3867
|
let refreshProbe;
|
|
3834
3868
|
const consider = (status, probe) => {
|
|
@@ -3847,6 +3881,14 @@ async function assembleDecryptedMessage(message, address) {
|
|
|
3847
3881
|
if (thoughtProcessResult.probe) {
|
|
3848
3882
|
consider(thoughtProcessResult.status, thoughtProcessResult.probe);
|
|
3849
3883
|
}
|
|
3884
|
+
if (toolCallEventsResult.probe) {
|
|
3885
|
+
consider(toolCallEventsResult.status, toolCallEventsResult.probe);
|
|
3886
|
+
}
|
|
3887
|
+
const toolCallEvents = Array.isArray(toolCallEventsResult.value) ? await mapToolCallPayloads(toolCallEventsResult.value, async (value) => {
|
|
3888
|
+
const detailed = await decryptFieldDetailed(value, address);
|
|
3889
|
+
consider(detailed.status, isEncrypted(value) ? value : void 0);
|
|
3890
|
+
return detailed.value;
|
|
3891
|
+
}) : void 0;
|
|
3850
3892
|
const statusForConsumer = decryptionStatus === "ok" || decryptionStatus === "plaintext" || !decryptionStatus ? void 0 : decryptionStatus;
|
|
3851
3893
|
const result = {
|
|
3852
3894
|
...message,
|
|
@@ -3855,7 +3897,8 @@ async function assembleDecryptedMessage(message, address) {
|
|
|
3855
3897
|
vector: vectorResult.value,
|
|
3856
3898
|
chunks: chunksResult.value,
|
|
3857
3899
|
sources: sourcesResult.value,
|
|
3858
|
-
thoughtProcess: thoughtProcessResult.value
|
|
3900
|
+
thoughtProcess: thoughtProcessResult.value,
|
|
3901
|
+
toolCallEvents
|
|
3859
3902
|
};
|
|
3860
3903
|
if (statusForConsumer) {
|
|
3861
3904
|
result.decryptionStatus = statusForConsumer;
|
|
@@ -4649,7 +4692,7 @@ async function updateMessageChunksOp(ctx, uniqueId, chunks3, embeddingModel) {
|
|
|
4649
4692
|
});
|
|
4650
4693
|
return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
4651
4694
|
}
|
|
4652
|
-
var
|
|
4695
|
+
var RAW_REPAIR_PAGE_SIZE = 100;
|
|
4653
4696
|
function chunksWithoutText(raw) {
|
|
4654
4697
|
if (typeof raw !== "string") return null;
|
|
4655
4698
|
let parsed;
|
|
@@ -4672,8 +4715,8 @@ function chunksWithoutText(raw) {
|
|
|
4672
4715
|
async function stripLegacyChunkTextOp(ctx) {
|
|
4673
4716
|
const candidateIds = await ctx.messagesCollection.query(import_watermelondb2.Q.where("chunks", import_watermelondb2.Q.like(`%${import_watermelondb2.Q.sanitizeLikeString('"text":')}%`))).fetchIds();
|
|
4674
4717
|
let stripped = 0;
|
|
4675
|
-
for (let start = 0; start < candidateIds.length; start +=
|
|
4676
|
-
const pageIds = candidateIds.slice(start, start +
|
|
4718
|
+
for (let start = 0; start < candidateIds.length; start += RAW_REPAIR_PAGE_SIZE) {
|
|
4719
|
+
const pageIds = candidateIds.slice(start, start + RAW_REPAIR_PAGE_SIZE);
|
|
4677
4720
|
const rows = await ctx.messagesCollection.query(import_watermelondb2.Q.where("id", import_watermelondb2.Q.oneOf(pageIds))).unsafeFetchRaw();
|
|
4678
4721
|
const changedIds = rows.filter((row) => chunksWithoutText(row.chunks) !== null).map((row) => String(row.id));
|
|
4679
4722
|
if (changedIds.length === 0) continue;
|
|
@@ -4697,6 +4740,88 @@ async function stripLegacyChunkTextOp(ctx) {
|
|
|
4697
4740
|
}
|
|
4698
4741
|
return stripped;
|
|
4699
4742
|
}
|
|
4743
|
+
async function encryptedToolCallEventsColumn(raw, address, signMessage, embeddedWalletSigner) {
|
|
4744
|
+
if (typeof raw !== "string") return null;
|
|
4745
|
+
let parsed;
|
|
4746
|
+
try {
|
|
4747
|
+
parsed = JSON.parse(raw);
|
|
4748
|
+
} catch {
|
|
4749
|
+
return null;
|
|
4750
|
+
}
|
|
4751
|
+
if (!Array.isArray(parsed)) return null;
|
|
4752
|
+
const column = JSON.stringify(
|
|
4753
|
+
await encryptToolCallEvents(
|
|
4754
|
+
parsed,
|
|
4755
|
+
address,
|
|
4756
|
+
signMessage,
|
|
4757
|
+
embeddedWalletSigner
|
|
4758
|
+
)
|
|
4759
|
+
);
|
|
4760
|
+
return column === JSON.stringify(parsed) ? null : column;
|
|
4761
|
+
}
|
|
4762
|
+
async function encryptToolCallEventsOp(ctx) {
|
|
4763
|
+
const { walletAddress: address, signMessage, embeddedWalletSigner } = ctx;
|
|
4764
|
+
if (!address || !signMessage) return 0;
|
|
4765
|
+
if (!await requestEncryptionKey(address, signMessage, embeddedWalletSigner)) return 0;
|
|
4766
|
+
if (!hasEncryptionKey(address)) return 0;
|
|
4767
|
+
if (!await savedKeyOpensExistingData(ctx, address, signMessage, embeddedWalletSigner)) {
|
|
4768
|
+
return 0;
|
|
4769
|
+
}
|
|
4770
|
+
const candidateIds = await ctx.messagesCollection.query(
|
|
4771
|
+
import_watermelondb2.Q.where("tool_call_events", import_watermelondb2.Q.notEq(null)),
|
|
4772
|
+
import_watermelondb2.Q.where("tool_call_events", import_watermelondb2.Q.notIn(["", "[]"]))
|
|
4773
|
+
).fetchIds();
|
|
4774
|
+
let encrypted = 0;
|
|
4775
|
+
for (let start = 0; start < candidateIds.length; start += RAW_REPAIR_PAGE_SIZE) {
|
|
4776
|
+
const pageIds = candidateIds.slice(start, start + RAW_REPAIR_PAGE_SIZE);
|
|
4777
|
+
const rows = await ctx.messagesCollection.query(import_watermelondb2.Q.where("id", import_watermelondb2.Q.oneOf(pageIds))).unsafeFetchRaw();
|
|
4778
|
+
const repairs = /* @__PURE__ */ new Map();
|
|
4779
|
+
for (const row of rows) {
|
|
4780
|
+
const column = await encryptedToolCallEventsColumn(
|
|
4781
|
+
row.tool_call_events,
|
|
4782
|
+
address,
|
|
4783
|
+
signMessage,
|
|
4784
|
+
embeddedWalletSigner
|
|
4785
|
+
);
|
|
4786
|
+
if (column !== null) repairs.set(String(row.id), { raw: row.tool_call_events, column });
|
|
4787
|
+
}
|
|
4788
|
+
if (repairs.size === 0) continue;
|
|
4789
|
+
await ctx.database.write(async () => {
|
|
4790
|
+
const messages = (await ctx.messagesCollection.query(import_watermelondb2.Q.where("id", import_watermelondb2.Q.oneOf([...repairs.keys()]))).fetch()).filter(
|
|
4791
|
+
(message) => message._raw.tool_call_events === repairs.get(message.id)?.raw
|
|
4792
|
+
);
|
|
4793
|
+
if (messages.length === 0) return;
|
|
4794
|
+
const conversationIds = [...new Set(messages.map((message) => message.conversationId))];
|
|
4795
|
+
const conversations = await ctx.conversationsCollection.query(import_watermelondb2.Q.where("conversation_id", import_watermelondb2.Q.oneOf(conversationIds))).fetch();
|
|
4796
|
+
await ctx.database.batch(
|
|
4797
|
+
...messages.map(
|
|
4798
|
+
(message) => message.prepareUpdate((msg) => {
|
|
4799
|
+
msg._setRaw("tool_call_events", repairs.get(message.id).column);
|
|
4800
|
+
})
|
|
4801
|
+
),
|
|
4802
|
+
...conversations.map((conversation) => conversation.prepareUpdate(() => {
|
|
4803
|
+
}))
|
|
4804
|
+
);
|
|
4805
|
+
encrypted += messages.length;
|
|
4806
|
+
});
|
|
4807
|
+
}
|
|
4808
|
+
return encrypted;
|
|
4809
|
+
}
|
|
4810
|
+
async function savedKeyOpensExistingData(ctx, address, signMessage, embeddedWalletSigner) {
|
|
4811
|
+
const v3Probe = await findEncryptedContent(ctx, "enc:v3:%");
|
|
4812
|
+
if (v3Probe) {
|
|
4813
|
+
const { status } = await decryptFieldDetailed(v3Probe, address);
|
|
4814
|
+
if (status !== "auth_mismatch" && status !== "key_missing") return true;
|
|
4815
|
+
return refreshEncryptionKeyIfMatches(address, v3Probe, signMessage, embeddedWalletSigner);
|
|
4816
|
+
}
|
|
4817
|
+
const v2Probe = await findEncryptedContent(ctx, "enc:v2:%");
|
|
4818
|
+
if (!v2Probe) return true;
|
|
4819
|
+
return refreshEncryptionKeyIfMatches(address, v2Probe, signMessage, embeddedWalletSigner);
|
|
4820
|
+
}
|
|
4821
|
+
async function findEncryptedContent(ctx, pattern) {
|
|
4822
|
+
const [row] = await ctx.messagesCollection.query(import_watermelondb2.Q.where("content", import_watermelondb2.Q.like(pattern)), import_watermelondb2.Q.take(1)).unsafeFetchRaw();
|
|
4823
|
+
return row ? String(row.content) : null;
|
|
4824
|
+
}
|
|
4700
4825
|
async function updateMessageErrorOp(ctx, uniqueId, error) {
|
|
4701
4826
|
let message;
|
|
4702
4827
|
try {
|
|
@@ -6575,7 +6700,8 @@ function extractReservationReceipts(toolCallEvents) {
|
|
|
6575
6700
|
for (const event of toolCallEvents ?? []) {
|
|
6576
6701
|
const action = ACTIONS.find((a) => event.name?.endsWith(a.tool));
|
|
6577
6702
|
const output = event.output ?? "";
|
|
6578
|
-
if (!action || !output || NOT_AN_ATTEMPT.test(output))
|
|
6703
|
+
if (!action || !output || hasEncryptedToolPayload(event) || NOT_AN_ATTEMPT.test(output))
|
|
6704
|
+
continue;
|
|
6579
6705
|
const kept = latest.get(action.kind)?.status;
|
|
6580
6706
|
if (kept === "made") continue;
|
|
6581
6707
|
const receipt = toReceipt(action, event.arguments ?? "", output);
|
|
@@ -32041,11 +32167,12 @@ async function storedToLlmapiMessage(stored2, encryptionKey, resolveMediaByIds)
|
|
|
32041
32167
|
textContent = textContent.replace(/\n{3,}/g, "\n\n").trim();
|
|
32042
32168
|
const content = [{ type: "text", text: textContent }, ...imageParts];
|
|
32043
32169
|
const messages = [];
|
|
32044
|
-
|
|
32170
|
+
const toolCallEvents = Array.isArray(stored2.toolCallEvents) ? stored2.toolCallEvents.filter((event) => !hasEncryptedToolPayload(event)) : [];
|
|
32171
|
+
if (stored2.role === "assistant" && toolCallEvents.length) {
|
|
32045
32172
|
messages.push({
|
|
32046
32173
|
role: stored2.role,
|
|
32047
32174
|
content: void 0,
|
|
32048
|
-
tool_calls:
|
|
32175
|
+
tool_calls: toolCallEvents.map((event) => ({
|
|
32049
32176
|
id: event.id,
|
|
32050
32177
|
type: "function",
|
|
32051
32178
|
function: {
|
|
@@ -32054,7 +32181,7 @@ async function storedToLlmapiMessage(stored2, encryptionKey, resolveMediaByIds)
|
|
|
32054
32181
|
}
|
|
32055
32182
|
}))
|
|
32056
32183
|
});
|
|
32057
|
-
for (const event of
|
|
32184
|
+
for (const event of toolCallEvents) {
|
|
32058
32185
|
if (event.id && event.output !== void 0 && event.output !== null) {
|
|
32059
32186
|
messages.push({
|
|
32060
32187
|
role: "tool",
|
|
@@ -37042,6 +37169,7 @@ function useWalletBinding(options = {}) {
|
|
|
37042
37169
|
encryptDataBatch,
|
|
37043
37170
|
encryptDataBytes,
|
|
37044
37171
|
encryptDataWithKey,
|
|
37172
|
+
encryptToolCallEventsOp,
|
|
37045
37173
|
ensureDefaultFoldersOp,
|
|
37046
37174
|
expandToolSetsAdditive,
|
|
37047
37175
|
exportElementToPdf,
|