@anuma/sdk 7.0.0 → 7.0.2
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 +421 -111
- package/dist/expo/index.d.mts +25 -24
- package/dist/expo/index.d.ts +25 -24
- package/dist/expo/index.mjs +420 -111
- package/dist/index.cjs +216 -192
- package/dist/index.mjs +216 -192
- package/dist/memory/context.d.mts +8 -0
- package/dist/memory/context.d.ts +8 -0
- package/dist/react/index.cjs +442 -132
- package/dist/react/index.d.mts +30 -44
- package/dist/react/index.d.ts +30 -44
- package/dist/react/index.mjs +441 -132
- package/dist/server/index.cjs +431 -106
- package/dist/server/index.d.mts +30 -21
- package/dist/server/index.d.ts +30 -21
- package/dist/server/index.mjs +430 -106
- package/dist/telemetry/index.d.mts +6 -0
- package/dist/telemetry/index.d.ts +6 -0
- package/dist/tools/selection/index.cjs +28 -10
- package/dist/tools/selection/index.mjs +28 -10
- 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();
|
|
@@ -1967,13 +1973,35 @@ async function generateEmbedding(text2, options) {
|
|
|
1967
1973
|
if (total === void 0) return embedOne(text2, options, void 0);
|
|
1968
1974
|
return withDeadline((signal) => embedOne(text2, options, signal), total, "embedding");
|
|
1969
1975
|
}
|
|
1976
|
+
var inFlightByCache = /* @__PURE__ */ new WeakMap();
|
|
1970
1977
|
async function embedOne(text2, options, outer) {
|
|
1971
|
-
const {
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1978
|
+
const { cache } = options;
|
|
1979
|
+
if (!cache) return Array.from(await requestEmbedding(text2, options, outer));
|
|
1980
|
+
const cached = cache.get(text2);
|
|
1981
|
+
if (cached) return Array.from(cached);
|
|
1982
|
+
const inFlight = inFlightByCache.get(cache) ?? /* @__PURE__ */ new Map();
|
|
1983
|
+
inFlightByCache.set(cache, inFlight);
|
|
1984
|
+
const pending = inFlight.get(text2);
|
|
1985
|
+
if (pending) {
|
|
1986
|
+
try {
|
|
1987
|
+
return Array.from(await pending);
|
|
1988
|
+
} catch (err) {
|
|
1989
|
+
if (outer?.aborted) throw err;
|
|
1990
|
+
}
|
|
1976
1991
|
}
|
|
1992
|
+
const request = requestEmbedding(text2, options, outer);
|
|
1993
|
+
inFlight.set(text2, request);
|
|
1994
|
+
try {
|
|
1995
|
+
const embedding = await request;
|
|
1996
|
+
cache.set(text2, embedding);
|
|
1997
|
+
return Array.from(embedding);
|
|
1998
|
+
} finally {
|
|
1999
|
+
if (inFlight.get(text2) === request) inFlight.delete(text2);
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
async function requestEmbedding(text2, options, outer) {
|
|
2003
|
+
const { baseUrl = BASE_URL, model } = options;
|
|
2004
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
|
|
1977
2005
|
const headers = {
|
|
1978
2006
|
...await resolveAuthHeaders(options, outer),
|
|
1979
2007
|
...taskTypeHeader(options.taskType)
|
|
@@ -2008,11 +2036,7 @@ async function embedOne(text2, options, outer) {
|
|
|
2008
2036
|
totalTokens: response.data.usage.total_tokens ?? 0
|
|
2009
2037
|
});
|
|
2010
2038
|
}
|
|
2011
|
-
|
|
2012
|
-
if (cache) {
|
|
2013
|
-
cache.set(text2, f32Embedding);
|
|
2014
|
-
}
|
|
2015
|
-
return Array.from(f32Embedding);
|
|
2039
|
+
return Float32Array.from(embedding);
|
|
2016
2040
|
}
|
|
2017
2041
|
var DEFAULT_EMBEDDING_BATCH_SIZE = 100;
|
|
2018
2042
|
var DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
|
|
@@ -299,6 +299,8 @@ interface RankedMemory {
|
|
|
299
299
|
updatedAt: Date;
|
|
300
300
|
}
|
|
301
301
|
interface RecallOptions {
|
|
302
|
+
/** Embedding cache shared with the rest of the turn, so the query is embedded once across lanes and the send. */
|
|
303
|
+
embeddingCache?: Map<string, Float32Array>;
|
|
302
304
|
/** Which kinds to search. Default: ['fact']. */
|
|
303
305
|
types?: MemoryKind[];
|
|
304
306
|
/** Max items returned. Default: 8. */
|
|
@@ -554,6 +556,12 @@ interface RecallDiagnostics {
|
|
|
554
556
|
* LEGACY read path this batch is uncapped, so it can be the whole vault.
|
|
555
557
|
*/
|
|
556
558
|
vaultRowsEmbedded?: number;
|
|
559
|
+
/** Embedded messages the chunk lane considered; absent when the lane did not run. */
|
|
560
|
+
chunkRowsScanned?: number;
|
|
561
|
+
/** Messages whose vectors the chunk lane read from storage on a cache miss. */
|
|
562
|
+
chunkRowsFetched?: number;
|
|
563
|
+
/** Messages the chunk lane scored from the vector cache. */
|
|
564
|
+
chunkCacheHits?: number;
|
|
557
565
|
/** Facts the fact lane returned (post-dedupe, pre-fusion). */
|
|
558
566
|
factCount: number;
|
|
559
567
|
/** Chunks the chunk lane returned (post-dedupe, pre-fusion). */
|
package/dist/memory/context.d.ts
CHANGED
|
@@ -299,6 +299,8 @@ interface RankedMemory {
|
|
|
299
299
|
updatedAt: Date;
|
|
300
300
|
}
|
|
301
301
|
interface RecallOptions {
|
|
302
|
+
/** Embedding cache shared with the rest of the turn, so the query is embedded once across lanes and the send. */
|
|
303
|
+
embeddingCache?: Map<string, Float32Array>;
|
|
302
304
|
/** Which kinds to search. Default: ['fact']. */
|
|
303
305
|
types?: MemoryKind[];
|
|
304
306
|
/** Max items returned. Default: 8. */
|
|
@@ -554,6 +556,12 @@ interface RecallDiagnostics {
|
|
|
554
556
|
* LEGACY read path this batch is uncapped, so it can be the whole vault.
|
|
555
557
|
*/
|
|
556
558
|
vaultRowsEmbedded?: number;
|
|
559
|
+
/** Embedded messages the chunk lane considered; absent when the lane did not run. */
|
|
560
|
+
chunkRowsScanned?: number;
|
|
561
|
+
/** Messages whose vectors the chunk lane read from storage on a cache miss. */
|
|
562
|
+
chunkRowsFetched?: number;
|
|
563
|
+
/** Messages the chunk lane scored from the vector cache. */
|
|
564
|
+
chunkCacheHits?: number;
|
|
557
565
|
/** Facts the fact lane returned (post-dedupe, pre-fusion). */
|
|
558
566
|
factCount: number;
|
|
559
567
|
/** Chunks the chunk lane returned (post-dedupe, pre-fusion). */
|