@anuma/sdk 4.2.0 → 5.0.0
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-VBO6KSNQ.mjs → chunk-SIMGZQ4P.mjs} +480 -196
- package/dist/expo/index.cjs +417 -120
- package/dist/expo/index.d.mts +161 -26
- package/dist/expo/index.d.ts +161 -26
- package/dist/expo/index.mjs +22 -6
- package/dist/expo/{recall-OCQOA7M3.mjs → recall-PIDYDFIQ.mjs} +1 -1
- package/dist/index.cjs +31 -17
- package/dist/index.mjs +31 -17
- package/dist/react/{chunk-BS7C4CUW.mjs → chunk-KTBOHRRE.mjs} +480 -196
- package/dist/react/index.cjs +417 -120
- package/dist/react/index.d.mts +155 -26
- package/dist/react/index.d.ts +155 -26
- package/dist/react/index.mjs +22 -6
- package/dist/react/{recall-WXCZHXHZ.mjs → recall-DVX4W2UD.mjs} +1 -1
- package/dist/server/{chunk-WADHFDMA.mjs → chunk-FKVYUOSD.mjs} +480 -196
- package/dist/server/index.cjs +417 -120
- package/dist/server/index.d.mts +154 -25
- package/dist/server/index.d.ts +154 -25
- package/dist/server/index.mjs +22 -6
- package/dist/server/{recall-QTVT7HCZ.mjs → recall-74L75BJ3.mjs} +1 -1
- package/package.json +1 -1
package/dist/server/index.cjs
CHANGED
|
@@ -15012,14 +15012,11 @@ function notifyKeyAvailable(address) {
|
|
|
15012
15012
|
}
|
|
15013
15013
|
}
|
|
15014
15014
|
}
|
|
15015
|
-
function getStoredKey(address) {
|
|
15016
|
-
const keys = encryptionKeyStore.get(address);
|
|
15017
|
-
return keys?.current ?? null;
|
|
15018
|
-
}
|
|
15019
15015
|
function getStoredKeyByVersion(address, version) {
|
|
15020
15016
|
const keys = encryptionKeyStore.get(address);
|
|
15021
15017
|
if (!keys) return null;
|
|
15022
|
-
|
|
15018
|
+
const value = version === "v2" ? keys.legacy : keys.current;
|
|
15019
|
+
return value ?? null;
|
|
15023
15020
|
}
|
|
15024
15021
|
function setStoredKey(address, keys) {
|
|
15025
15022
|
encryptionKeyStore.set(address, keys);
|
|
@@ -15028,6 +15025,8 @@ function clearEncryptionKey(address) {
|
|
|
15028
15025
|
encryptionKeyStore.delete(address);
|
|
15029
15026
|
cryptoKeyCache.delete(`${address}:v2`);
|
|
15030
15027
|
cryptoKeyCache.delete(`${address}:v3`);
|
|
15028
|
+
refreshCandidatesByAddress.delete(address);
|
|
15029
|
+
divergentDeriveAddresses.delete(address);
|
|
15031
15030
|
}
|
|
15032
15031
|
function clearAllEncryptionState() {
|
|
15033
15032
|
sessionEpoch += 1;
|
|
@@ -15035,6 +15034,9 @@ function clearAllEncryptionState() {
|
|
|
15035
15034
|
cryptoKeyCache.clear();
|
|
15036
15035
|
keyAvailableCallbacks.clear();
|
|
15037
15036
|
pendingKeyRequests.clear();
|
|
15037
|
+
pendingCandidateDerives.clear();
|
|
15038
|
+
refreshCandidatesByAddress.clear();
|
|
15039
|
+
divergentDeriveAddresses.clear();
|
|
15038
15040
|
clearAllKeyPairs();
|
|
15039
15041
|
for (const cb of clearAllEncryptionStateCallbacks) {
|
|
15040
15042
|
try {
|
|
@@ -15218,9 +15220,7 @@ async function getEncryptionKey(address, version = "v3") {
|
|
|
15218
15220
|
}
|
|
15219
15221
|
const keyHex = getStoredKeyByVersion(address, version);
|
|
15220
15222
|
if (!keyHex) {
|
|
15221
|
-
throw new
|
|
15222
|
-
"Encryption key not found. Please sign a message to generate your encryption key."
|
|
15223
|
-
);
|
|
15223
|
+
throw new EncryptionKeyMissingError(address, version);
|
|
15224
15224
|
}
|
|
15225
15225
|
const keyBytes = hexToBytes(keyHex);
|
|
15226
15226
|
const cryptoKey = await crypto.subtle.importKey(
|
|
@@ -15284,8 +15284,42 @@ async function decryptDataBytesFromBytes(encrypted, address, version = "v3") {
|
|
|
15284
15284
|
);
|
|
15285
15285
|
return new Uint8Array(decryptedData);
|
|
15286
15286
|
}
|
|
15287
|
-
function hasEncryptionKey(address) {
|
|
15288
|
-
return
|
|
15287
|
+
function hasEncryptionKey(address, version) {
|
|
15288
|
+
return getStoredKeyByVersion(address, version ?? "v3") !== null;
|
|
15289
|
+
}
|
|
15290
|
+
function seedEncryptionKeys(address, keys) {
|
|
15291
|
+
if (!isValidWalletAddress(address)) {
|
|
15292
|
+
throw new Error(
|
|
15293
|
+
`Invalid wallet address: ${address}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
15294
|
+
);
|
|
15295
|
+
}
|
|
15296
|
+
if (!keys.legacy && !keys.current) {
|
|
15297
|
+
throw new Error("seedEncryptionKeys: at least one of legacy or current is required");
|
|
15298
|
+
}
|
|
15299
|
+
if (keys.legacy !== void 0) {
|
|
15300
|
+
assertAes256KeyHex("legacy", keys.legacy);
|
|
15301
|
+
}
|
|
15302
|
+
if (keys.current !== void 0) {
|
|
15303
|
+
assertAes256KeyHex("current", keys.current);
|
|
15304
|
+
}
|
|
15305
|
+
const existing = encryptionKeyStore.get(address);
|
|
15306
|
+
const next = {
|
|
15307
|
+
legacy: keys.legacy ?? existing?.legacy,
|
|
15308
|
+
current: keys.current ?? existing?.current
|
|
15309
|
+
};
|
|
15310
|
+
setStoredKey(address, next);
|
|
15311
|
+
if (keys.legacy !== void 0) cryptoKeyCache.delete(`${address}:v2`);
|
|
15312
|
+
if (keys.current !== void 0) cryptoKeyCache.delete(`${address}:v3`);
|
|
15313
|
+
refreshCandidatesByAddress.delete(address);
|
|
15314
|
+
divergentDeriveAddresses.delete(address);
|
|
15315
|
+
notifyKeyAvailable(address);
|
|
15316
|
+
}
|
|
15317
|
+
function assertAes256KeyHex(field10, value) {
|
|
15318
|
+
if (!AES_256_KEY_HEX.test(value)) {
|
|
15319
|
+
throw new Error(
|
|
15320
|
+
`seedEncryptionKeys: ${field10} must be 64 hex characters (32-byte AES key), got length ${value.length}`
|
|
15321
|
+
);
|
|
15322
|
+
}
|
|
15289
15323
|
}
|
|
15290
15324
|
async function encryptBytesWithKey(plaintext, key) {
|
|
15291
15325
|
const plaintextBytes = typeof plaintext === "string" ? SHARED_TEXT_ENCODER.encode(plaintext) : plaintext;
|
|
@@ -15334,20 +15368,23 @@ async function decryptDataBatch(encryptedValues, address) {
|
|
|
15334
15368
|
const key = await getEncryptionKey(address);
|
|
15335
15369
|
return Promise.all(encryptedValues.map((value) => decryptDataWithKey(value, key)));
|
|
15336
15370
|
}
|
|
15337
|
-
async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSigner) {
|
|
15371
|
+
async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSigner, options) {
|
|
15338
15372
|
if (!isValidWalletAddress(walletAddress)) {
|
|
15339
15373
|
throw new Error(
|
|
15340
15374
|
`Invalid wallet address: ${walletAddress}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
15341
15375
|
);
|
|
15342
15376
|
}
|
|
15343
|
-
|
|
15344
|
-
|
|
15345
|
-
return;
|
|
15377
|
+
if (!options?.force && getStoredKeyByVersion(walletAddress, "v3") && getStoredKeyByVersion(walletAddress, "v2")) {
|
|
15378
|
+
return true;
|
|
15346
15379
|
}
|
|
15347
|
-
|
|
15348
|
-
|
|
15349
|
-
|
|
15350
|
-
|
|
15380
|
+
if (!options?.force && divergentDeriveAddresses.has(walletAddress)) {
|
|
15381
|
+
return false;
|
|
15382
|
+
}
|
|
15383
|
+
if (!options?.force) {
|
|
15384
|
+
const pending = pendingKeyRequests.get(walletAddress);
|
|
15385
|
+
if (pending) {
|
|
15386
|
+
return pending;
|
|
15387
|
+
}
|
|
15351
15388
|
}
|
|
15352
15389
|
const startEpoch = sessionEpoch;
|
|
15353
15390
|
const promise = (async () => {
|
|
@@ -15375,20 +15412,143 @@ async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSi
|
|
|
15375
15412
|
deriveKeyFromSignatureV3(signature)
|
|
15376
15413
|
]);
|
|
15377
15414
|
if (sessionEpoch !== startEpoch) {
|
|
15378
|
-
return;
|
|
15415
|
+
return false;
|
|
15379
15416
|
}
|
|
15380
|
-
|
|
15417
|
+
const existing = encryptionKeyStore.get(walletAddress);
|
|
15418
|
+
if (!options?.force && existing && (existing.legacy || existing.current)) {
|
|
15419
|
+
const matchesCurrent = Boolean(existing.current && existing.current === currentKey);
|
|
15420
|
+
const matchesLegacy = Boolean(existing.legacy && existing.legacy === legacyKey);
|
|
15421
|
+
if (!matchesCurrent && !matchesLegacy) {
|
|
15422
|
+
getLogger().warn(
|
|
15423
|
+
"requestEncryptionKey: derived keys do not match existing store; leaving unchanged"
|
|
15424
|
+
);
|
|
15425
|
+
divergentDeriveAddresses.add(walletAddress);
|
|
15426
|
+
return false;
|
|
15427
|
+
}
|
|
15428
|
+
setStoredKey(walletAddress, {
|
|
15429
|
+
legacy: existing.legacy ?? legacyKey,
|
|
15430
|
+
current: existing.current ?? currentKey
|
|
15431
|
+
});
|
|
15432
|
+
} else {
|
|
15433
|
+
setStoredKey(walletAddress, { legacy: legacyKey, current: currentKey });
|
|
15434
|
+
}
|
|
15435
|
+
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
15436
|
+
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
15437
|
+
refreshCandidatesByAddress.delete(walletAddress);
|
|
15438
|
+
divergentDeriveAddresses.delete(walletAddress);
|
|
15381
15439
|
notifyKeyAvailable(walletAddress);
|
|
15440
|
+
return true;
|
|
15382
15441
|
})();
|
|
15383
15442
|
pendingKeyRequests.set(walletAddress, promise);
|
|
15384
15443
|
try {
|
|
15385
|
-
await promise;
|
|
15444
|
+
return await promise;
|
|
15386
15445
|
} finally {
|
|
15387
15446
|
if (pendingKeyRequests.get(walletAddress) === promise) {
|
|
15388
15447
|
pendingKeyRequests.delete(walletAddress);
|
|
15389
15448
|
}
|
|
15390
15449
|
}
|
|
15391
15450
|
}
|
|
15451
|
+
async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, signMessage, embeddedWalletSigner) {
|
|
15452
|
+
if (!isValidWalletAddress(walletAddress)) {
|
|
15453
|
+
throw new Error(
|
|
15454
|
+
`Invalid wallet address: ${walletAddress}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
15455
|
+
);
|
|
15456
|
+
}
|
|
15457
|
+
const parsed = parsePrefixedCiphertext(probeCiphertext);
|
|
15458
|
+
if (!parsed) {
|
|
15459
|
+
return false;
|
|
15460
|
+
}
|
|
15461
|
+
const cached = refreshCandidatesByAddress.get(walletAddress);
|
|
15462
|
+
if (cached) {
|
|
15463
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached);
|
|
15464
|
+
}
|
|
15465
|
+
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
15466
|
+
if (!derivePromise) {
|
|
15467
|
+
derivePromise = (async () => {
|
|
15468
|
+
const candidates2 = await deriveRefreshCandidates(signMessage, embeddedWalletSigner);
|
|
15469
|
+
if (candidates2) {
|
|
15470
|
+
refreshCandidatesByAddress.set(walletAddress, candidates2);
|
|
15471
|
+
}
|
|
15472
|
+
return candidates2;
|
|
15473
|
+
})().finally(() => {
|
|
15474
|
+
if (pendingCandidateDerives.get(walletAddress) === derivePromise) {
|
|
15475
|
+
pendingCandidateDerives.delete(walletAddress);
|
|
15476
|
+
}
|
|
15477
|
+
});
|
|
15478
|
+
pendingCandidateDerives.set(walletAddress, derivePromise);
|
|
15479
|
+
}
|
|
15480
|
+
const candidates = await derivePromise;
|
|
15481
|
+
if (!candidates) {
|
|
15482
|
+
return false;
|
|
15483
|
+
}
|
|
15484
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates);
|
|
15485
|
+
}
|
|
15486
|
+
function parsePrefixedCiphertext(probeCiphertext) {
|
|
15487
|
+
const version = probeCiphertext.startsWith("enc:v3:") ? "v3" : probeCiphertext.startsWith("enc:v2:") ? "v2" : null;
|
|
15488
|
+
if (!version) return null;
|
|
15489
|
+
const encryptedData = probeCiphertext.slice(
|
|
15490
|
+
version === "v3" ? "enc:v3:".length : "enc:v2:".length
|
|
15491
|
+
);
|
|
15492
|
+
if (encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(encryptedData)) {
|
|
15493
|
+
return null;
|
|
15494
|
+
}
|
|
15495
|
+
return { version, encryptedData };
|
|
15496
|
+
}
|
|
15497
|
+
async function deriveRefreshCandidates(signMessage, embeddedWalletSigner) {
|
|
15498
|
+
const startEpoch = sessionEpoch;
|
|
15499
|
+
const signOptions = { showWalletUIs: false };
|
|
15500
|
+
let signature;
|
|
15501
|
+
try {
|
|
15502
|
+
if (embeddedWalletSigner) {
|
|
15503
|
+
signature = await embeddedWalletSigner(SIGN_MESSAGE, signOptions);
|
|
15504
|
+
} else {
|
|
15505
|
+
signature = await signMessage(SIGN_MESSAGE, signOptions);
|
|
15506
|
+
}
|
|
15507
|
+
} catch (error) {
|
|
15508
|
+
if (embeddedWalletSigner && error instanceof Error) {
|
|
15509
|
+
getLogger().warn(
|
|
15510
|
+
"Embedded wallet signing failed during key refresh, falling back to standard signMessage:",
|
|
15511
|
+
error.message
|
|
15512
|
+
);
|
|
15513
|
+
signature = await signMessage(SIGN_MESSAGE, signOptions);
|
|
15514
|
+
} else {
|
|
15515
|
+
throw error;
|
|
15516
|
+
}
|
|
15517
|
+
}
|
|
15518
|
+
const [legacyKey, currentKey] = await Promise.all([
|
|
15519
|
+
deriveKeyFromSignature(signature),
|
|
15520
|
+
deriveKeyFromSignatureV3(signature)
|
|
15521
|
+
]);
|
|
15522
|
+
if (sessionEpoch !== startEpoch) {
|
|
15523
|
+
return null;
|
|
15524
|
+
}
|
|
15525
|
+
return { legacy: legacyKey, current: currentKey };
|
|
15526
|
+
}
|
|
15527
|
+
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates) {
|
|
15528
|
+
const candidateHex = parsed.version === "v2" ? candidates.legacy : candidates.current;
|
|
15529
|
+
const keyBytes = hexToBytes(candidateHex);
|
|
15530
|
+
const candidateCryptoKey = await crypto.subtle.importKey(
|
|
15531
|
+
"raw",
|
|
15532
|
+
keyBytes.buffer,
|
|
15533
|
+
{ name: "AES-GCM" },
|
|
15534
|
+
false,
|
|
15535
|
+
["encrypt", "decrypt"]
|
|
15536
|
+
);
|
|
15537
|
+
try {
|
|
15538
|
+
await decryptDataWithKey(parsed.encryptedData, candidateCryptoKey);
|
|
15539
|
+
} catch {
|
|
15540
|
+
getLogger().warn(
|
|
15541
|
+
"refreshEncryptionKeyIfMatches: candidate keys failed to decrypt probe; leaving store unchanged"
|
|
15542
|
+
);
|
|
15543
|
+
return false;
|
|
15544
|
+
}
|
|
15545
|
+
setStoredKey(walletAddress, { legacy: candidates.legacy, current: candidates.current });
|
|
15546
|
+
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
15547
|
+
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
15548
|
+
divergentDeriveAddresses.delete(walletAddress);
|
|
15549
|
+
notifyKeyAvailable(walletAddress);
|
|
15550
|
+
return true;
|
|
15551
|
+
}
|
|
15392
15552
|
async function persistKeyPair(address, startEpoch) {
|
|
15393
15553
|
if (typeof window === "undefined") {
|
|
15394
15554
|
return;
|
|
@@ -15613,15 +15773,28 @@ function clearAllKeyPairs() {
|
|
|
15613
15773
|
}
|
|
15614
15774
|
}
|
|
15615
15775
|
}
|
|
15616
|
-
var SIGN_MESSAGE, encryptionKeyStore, pendingKeyRequests, sessionEpoch, cryptoKeyCache, keyAvailableCallbacks, clearAllEncryptionStateCallbacks, keyPairStore, SHARED_TEXT_ENCODER, SHARED_TEXT_DECODER, KEYPAIR_STORAGE_PREFIX;
|
|
15776
|
+
var SIGN_MESSAGE, EncryptionKeyMissingError, encryptionKeyStore, pendingKeyRequests, pendingCandidateDerives, refreshCandidatesByAddress, divergentDeriveAddresses, sessionEpoch, cryptoKeyCache, keyAvailableCallbacks, clearAllEncryptionStateCallbacks, keyPairStore, SHARED_TEXT_ENCODER, SHARED_TEXT_DECODER, AES_256_KEY_HEX, KEYPAIR_STORAGE_PREFIX;
|
|
15617
15777
|
var init_useEncryption = __esm({
|
|
15618
15778
|
"src/react/useEncryption.ts"() {
|
|
15619
15779
|
"use strict";
|
|
15620
15780
|
"use client";
|
|
15621
15781
|
init_logger();
|
|
15622
15782
|
SIGN_MESSAGE = "The app is asking you to sign this message to generate a key, which will be used to encrypt data.";
|
|
15783
|
+
EncryptionKeyMissingError = class extends Error {
|
|
15784
|
+
constructor(address, version) {
|
|
15785
|
+
super(
|
|
15786
|
+
`Encryption key (${version}) not found for ${address}. Please sign a message to generate your encryption key.`
|
|
15787
|
+
);
|
|
15788
|
+
this.name = "EncryptionKeyMissingError";
|
|
15789
|
+
this.address = address;
|
|
15790
|
+
this.version = version;
|
|
15791
|
+
}
|
|
15792
|
+
};
|
|
15623
15793
|
encryptionKeyStore = /* @__PURE__ */ new Map();
|
|
15624
15794
|
pendingKeyRequests = /* @__PURE__ */ new Map();
|
|
15795
|
+
pendingCandidateDerives = /* @__PURE__ */ new Map();
|
|
15796
|
+
refreshCandidatesByAddress = /* @__PURE__ */ new Map();
|
|
15797
|
+
divergentDeriveAddresses = /* @__PURE__ */ new Set();
|
|
15625
15798
|
sessionEpoch = 0;
|
|
15626
15799
|
cryptoKeyCache = /* @__PURE__ */ new Map();
|
|
15627
15800
|
keyAvailableCallbacks = /* @__PURE__ */ new Map();
|
|
@@ -15629,6 +15802,7 @@ var init_useEncryption = __esm({
|
|
|
15629
15802
|
keyPairStore = /* @__PURE__ */ new Map();
|
|
15630
15803
|
SHARED_TEXT_ENCODER = new TextEncoder();
|
|
15631
15804
|
SHARED_TEXT_DECODER = new TextDecoder();
|
|
15805
|
+
AES_256_KEY_HEX = /^[0-9a-fA-F]{64}$/;
|
|
15632
15806
|
KEYPAIR_STORAGE_PREFIX = "ecdh_keypair_";
|
|
15633
15807
|
}
|
|
15634
15808
|
});
|
|
@@ -15661,20 +15835,29 @@ async function encryptField(value, address, signMessage, embeddedWalletSigner, s
|
|
|
15661
15835
|
const encrypted = await encryptData(value, address);
|
|
15662
15836
|
return `${ENCRYPTION_PREFIX}${encrypted}`;
|
|
15663
15837
|
}
|
|
15664
|
-
async function
|
|
15665
|
-
if (!value) return value;
|
|
15838
|
+
async function decryptFieldDetailed(value, address) {
|
|
15839
|
+
if (!value) return { status: "plaintext", value };
|
|
15666
15840
|
const detected = detectEncryptionVersion(value);
|
|
15667
|
-
if (!detected) return value;
|
|
15841
|
+
if (!detected) return { status: "plaintext", value };
|
|
15668
15842
|
if (detected.encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(detected.encryptedData)) {
|
|
15669
|
-
return value;
|
|
15843
|
+
return { status: "invalid_payload", value, version: detected.version };
|
|
15670
15844
|
}
|
|
15671
15845
|
try {
|
|
15672
|
-
|
|
15846
|
+
const plaintext = await decryptData(detected.encryptedData, address, detected.version);
|
|
15847
|
+
return { status: "ok", value: plaintext, version: detected.version };
|
|
15673
15848
|
} catch (error) {
|
|
15674
|
-
|
|
15675
|
-
|
|
15849
|
+
if (error instanceof EncryptionKeyMissingError) {
|
|
15850
|
+
getLogger().warn("Failed to decrypt field (key missing for version):", error.message);
|
|
15851
|
+
return { status: "key_missing", value, version: detected.version };
|
|
15852
|
+
}
|
|
15853
|
+
getLogger().warn("Failed to decrypt field (auth mismatch or crypto error):", error);
|
|
15854
|
+
return { status: "auth_mismatch", value, version: detected.version };
|
|
15676
15855
|
}
|
|
15677
15856
|
}
|
|
15857
|
+
async function decryptField(value, address) {
|
|
15858
|
+
const result = await decryptFieldDetailed(value, address);
|
|
15859
|
+
return result.value;
|
|
15860
|
+
}
|
|
15678
15861
|
async function encryptJsonField(value, address, signMessage, embeddedWalletSigner, skipKeyRequest) {
|
|
15679
15862
|
if (!value) return void 0;
|
|
15680
15863
|
const jsonString = JSON.stringify(value);
|
|
@@ -15811,20 +15994,40 @@ async function encryptMessageFields(message, address, signMessage, embeddedWalle
|
|
|
15811
15994
|
throw error;
|
|
15812
15995
|
}
|
|
15813
15996
|
}
|
|
15814
|
-
async function
|
|
15815
|
-
if (value === void 0) return void 0;
|
|
15816
|
-
if (value === null) return value;
|
|
15997
|
+
async function decryptMaybeJsonFieldDetailed(value, address) {
|
|
15998
|
+
if (value === void 0) return { value: void 0, status: "plaintext" };
|
|
15999
|
+
if (value === null) return { value, status: "plaintext" };
|
|
15817
16000
|
if (typeof value === "string") {
|
|
15818
16001
|
if (isEncrypted(value)) {
|
|
15819
|
-
|
|
16002
|
+
const detailed = await decryptFieldDetailed(value, address);
|
|
16003
|
+
if (detailed.status !== "ok") {
|
|
16004
|
+
return { value: void 0, status: detailed.status, probe: value };
|
|
16005
|
+
}
|
|
16006
|
+
try {
|
|
16007
|
+
return { value: JSON.parse(detailed.value), status: "ok" };
|
|
16008
|
+
} catch (error) {
|
|
16009
|
+
getLogger().warn("Failed to parse decrypted JSON field:", error);
|
|
16010
|
+
return { value: void 0, status: "invalid_payload", probe: value };
|
|
16011
|
+
}
|
|
15820
16012
|
}
|
|
15821
16013
|
try {
|
|
15822
|
-
return JSON.parse(value);
|
|
16014
|
+
return { value: JSON.parse(value), status: "plaintext" };
|
|
15823
16015
|
} catch {
|
|
15824
|
-
return void 0;
|
|
16016
|
+
return { value: void 0, status: "plaintext" };
|
|
15825
16017
|
}
|
|
15826
16018
|
}
|
|
15827
|
-
return value;
|
|
16019
|
+
return { value, status: "plaintext" };
|
|
16020
|
+
}
|
|
16021
|
+
function worseDecryptStatus(a, b) {
|
|
16022
|
+
if (b === "ok" || b === "plaintext") return a;
|
|
16023
|
+
if (!a || a === "ok" || a === "plaintext") return b;
|
|
16024
|
+
const rank = (s) => {
|
|
16025
|
+
if (s === "auth_mismatch") return 3;
|
|
16026
|
+
if (s === "key_missing") return 2;
|
|
16027
|
+
if (s === "invalid_payload") return 1;
|
|
16028
|
+
return 0;
|
|
16029
|
+
};
|
|
16030
|
+
return rank(b) >= rank(a) ? b : a;
|
|
15828
16031
|
}
|
|
15829
16032
|
async function decryptMessageFields(message, address, signMessage, embeddedWalletSigner) {
|
|
15830
16033
|
if (!address) {
|
|
@@ -15837,33 +16040,82 @@ async function decryptMessageFields(message, address, signMessage, embeddedWalle
|
|
|
15837
16040
|
getLogger().warn("Failed to request encryption key for decryption:", error);
|
|
15838
16041
|
}
|
|
15839
16042
|
}
|
|
15840
|
-
|
|
15841
|
-
const
|
|
15842
|
-
|
|
16043
|
+
let assembled = await assembleDecryptedMessage(message, address);
|
|
16044
|
+
const needsRefresh = assembled.decryptionStatus === "auth_mismatch" || assembled.decryptionStatus === "key_missing";
|
|
16045
|
+
if (needsRefresh && signMessage && assembled.refreshProbe) {
|
|
16046
|
+
try {
|
|
16047
|
+
const refreshed = await refreshEncryptionKeyIfMatches(
|
|
16048
|
+
address,
|
|
16049
|
+
assembled.refreshProbe,
|
|
16050
|
+
signMessage,
|
|
16051
|
+
embeddedWalletSigner
|
|
16052
|
+
);
|
|
16053
|
+
if (refreshed) {
|
|
16054
|
+
assembled = await assembleDecryptedMessage(message, address);
|
|
16055
|
+
}
|
|
16056
|
+
} catch (error) {
|
|
16057
|
+
getLogger().warn("Failed to refresh encryption key after decrypt failure:", error);
|
|
16058
|
+
}
|
|
16059
|
+
}
|
|
16060
|
+
const { refreshProbe: _probe, ...result } = assembled;
|
|
16061
|
+
return result;
|
|
16062
|
+
}
|
|
16063
|
+
async function assembleDecryptedMessage(message, address) {
|
|
16064
|
+
const contentResult = await decryptFieldDetailed(message.content, address);
|
|
16065
|
+
const thinkingResult = message.thinking ? await decryptFieldDetailed(message.thinking, address) : null;
|
|
16066
|
+
const vectorResult = await decryptMaybeJsonFieldDetailed(
|
|
15843
16067
|
message.vector,
|
|
15844
16068
|
address
|
|
15845
16069
|
);
|
|
15846
|
-
const
|
|
16070
|
+
const chunksResult = await decryptMaybeJsonFieldDetailed(
|
|
15847
16071
|
message.chunks,
|
|
15848
16072
|
address
|
|
15849
16073
|
);
|
|
15850
|
-
const
|
|
16074
|
+
const sourcesResult = await decryptMaybeJsonFieldDetailed(
|
|
15851
16075
|
message.sources,
|
|
15852
16076
|
address
|
|
15853
16077
|
);
|
|
15854
|
-
const
|
|
16078
|
+
const thoughtProcessResult = await decryptMaybeJsonFieldDetailed(
|
|
15855
16079
|
message.thoughtProcess,
|
|
15856
16080
|
address
|
|
15857
16081
|
);
|
|
15858
|
-
|
|
16082
|
+
let decryptionStatus;
|
|
16083
|
+
let refreshProbe;
|
|
16084
|
+
const consider = (status, probe) => {
|
|
16085
|
+
decryptionStatus = worseDecryptStatus(decryptionStatus, status);
|
|
16086
|
+
if (!refreshProbe && probe && (status === "auth_mismatch" || status === "key_missing")) {
|
|
16087
|
+
refreshProbe = probe;
|
|
16088
|
+
}
|
|
16089
|
+
};
|
|
16090
|
+
consider(contentResult.status, isEncrypted(message.content) ? message.content : void 0);
|
|
16091
|
+
if (thinkingResult && message.thinking && typeof message.thinking === "string") {
|
|
16092
|
+
consider(thinkingResult.status, isEncrypted(message.thinking) ? message.thinking : void 0);
|
|
16093
|
+
}
|
|
16094
|
+
if (vectorResult.probe) consider(vectorResult.status, vectorResult.probe);
|
|
16095
|
+
if (chunksResult.probe) consider(chunksResult.status, chunksResult.probe);
|
|
16096
|
+
if (sourcesResult.probe) consider(sourcesResult.status, sourcesResult.probe);
|
|
16097
|
+
if (thoughtProcessResult.probe) {
|
|
16098
|
+
consider(thoughtProcessResult.status, thoughtProcessResult.probe);
|
|
16099
|
+
}
|
|
16100
|
+
const statusForConsumer = decryptionStatus === "ok" || decryptionStatus === "plaintext" || !decryptionStatus ? void 0 : decryptionStatus;
|
|
16101
|
+
const result = {
|
|
15859
16102
|
...message,
|
|
15860
|
-
content:
|
|
15861
|
-
thinking:
|
|
15862
|
-
vector:
|
|
15863
|
-
chunks:
|
|
15864
|
-
sources:
|
|
15865
|
-
thoughtProcess:
|
|
16103
|
+
content: contentResult.value,
|
|
16104
|
+
thinking: thinkingResult ? thinkingResult.value : message.thinking,
|
|
16105
|
+
vector: vectorResult.value,
|
|
16106
|
+
chunks: chunksResult.value,
|
|
16107
|
+
sources: sourcesResult.value,
|
|
16108
|
+
thoughtProcess: thoughtProcessResult.value
|
|
15866
16109
|
};
|
|
16110
|
+
if (statusForConsumer) {
|
|
16111
|
+
result.decryptionStatus = statusForConsumer;
|
|
16112
|
+
} else {
|
|
16113
|
+
delete result.decryptionStatus;
|
|
16114
|
+
}
|
|
16115
|
+
if (refreshProbe) {
|
|
16116
|
+
result.refreshProbe = refreshProbe;
|
|
16117
|
+
}
|
|
16118
|
+
return result;
|
|
15867
16119
|
}
|
|
15868
16120
|
var init_encryption = __esm({
|
|
15869
16121
|
"src/lib/db/chat/encryption.ts"() {
|
|
@@ -20360,11 +20612,11 @@ async function decomposeQuery(query, options) {
|
|
|
20360
20612
|
userMessage: `Classify the following memory query and decompose if composite. Respond with JSON only \u2014 do not answer the question, do not ask for clarification.
|
|
20361
20613
|
|
|
20362
20614
|
Query: ${trimmed}`,
|
|
20363
|
-
// Decompose runs
|
|
20615
|
+
// Decompose runs ahead of recall in the tool layer — tighter than the
|
|
20364
20616
|
// portalLlm default (consolidate/extract can wait longer).
|
|
20365
20617
|
timeoutMs: 2e4,
|
|
20366
20618
|
// No internal retry: a failure degrades to the safe `{specific,[query]}`
|
|
20367
|
-
// fallback below
|
|
20619
|
+
// fallback below. The agent/tool loop is the retry surface (719/B4).
|
|
20368
20620
|
maxAttempts: 1,
|
|
20369
20621
|
tag: "memory/decompose",
|
|
20370
20622
|
...options.fetchFn && { fetchFn: options.fetchFn }
|
|
@@ -20376,12 +20628,28 @@ Query: ${trimmed}`,
|
|
|
20376
20628
|
if (parsed === null) return fallback;
|
|
20377
20629
|
return validate(parsed, trimmed) ?? fallback;
|
|
20378
20630
|
}
|
|
20631
|
+
function normalizeSubQueries(raw) {
|
|
20632
|
+
if (!raw || raw.length === 0) return [];
|
|
20633
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20634
|
+
const out = [];
|
|
20635
|
+
for (const s of raw) {
|
|
20636
|
+
if (typeof s !== "string") continue;
|
|
20637
|
+
const t = s.trim();
|
|
20638
|
+
if (t.length === 0) continue;
|
|
20639
|
+
const key = t.toLowerCase();
|
|
20640
|
+
if (seen.has(key)) continue;
|
|
20641
|
+
seen.add(key);
|
|
20642
|
+
out.push(t);
|
|
20643
|
+
if (out.length >= MAX_SUB_QUERIES) break;
|
|
20644
|
+
}
|
|
20645
|
+
return out;
|
|
20646
|
+
}
|
|
20379
20647
|
function validate(parsed, originalQuery) {
|
|
20380
20648
|
if (typeof parsed !== "object" || parsed === null) return null;
|
|
20381
20649
|
const obj = parsed;
|
|
20382
20650
|
const mode = obj.mode === "composite" ? "composite" : "specific";
|
|
20383
20651
|
if (!Array.isArray(obj.subQueries)) return null;
|
|
20384
|
-
const subQueries = obj.subQueries
|
|
20652
|
+
const subQueries = normalizeSubQueries(obj.subQueries);
|
|
20385
20653
|
if (subQueries.length === 0) return null;
|
|
20386
20654
|
if (mode === "specific") {
|
|
20387
20655
|
return { mode: "specific", subQueries: [originalQuery] };
|
|
@@ -20960,12 +21228,12 @@ __export(recall_exports, {
|
|
|
20960
21228
|
function flagsForBudget(budget) {
|
|
20961
21229
|
switch (budget) {
|
|
20962
21230
|
case "high":
|
|
20963
|
-
return { rerank: true,
|
|
21231
|
+
return { rerank: true, traverse: true };
|
|
20964
21232
|
case "mid":
|
|
20965
|
-
return { rerank: true,
|
|
21233
|
+
return { rerank: true, traverse: false };
|
|
20966
21234
|
case "low":
|
|
20967
21235
|
default:
|
|
20968
|
-
return { rerank: false,
|
|
21236
|
+
return { rerank: false, traverse: false };
|
|
20969
21237
|
}
|
|
20970
21238
|
}
|
|
20971
21239
|
function dedupeBy(items, ...keys) {
|
|
@@ -20984,10 +21252,10 @@ function dedupeBy(items, ...keys) {
|
|
|
20984
21252
|
async function recall(query, ctx, options = {}) {
|
|
20985
21253
|
const types = options.types ?? ["fact"];
|
|
20986
21254
|
const limit = options.limit ?? DEFAULT_LIMIT;
|
|
20987
|
-
const
|
|
20988
|
-
const flags = flagsForBudget(
|
|
20989
|
-
const
|
|
20990
|
-
const
|
|
21255
|
+
const usedBudget = options.budget ?? DEFAULT_BUDGET;
|
|
21256
|
+
const flags = flagsForBudget(usedBudget);
|
|
21257
|
+
const normalizedFacets = normalizeSubQueries(options.subQueries);
|
|
21258
|
+
const subQueries = normalizedFacets.length >= 2 ? normalizedFacets : void 0;
|
|
20991
21259
|
const t0 = nowMs();
|
|
20992
21260
|
let prepMs = 0;
|
|
20993
21261
|
let factLaneMs = 0;
|
|
@@ -21008,7 +21276,9 @@ async function recall(query, ctx, options = {}) {
|
|
|
21008
21276
|
if (flags.rerank && factResults.length > 0 && hadV2Head && !didRerank) {
|
|
21009
21277
|
degraded.push("rerank-unavailable");
|
|
21010
21278
|
}
|
|
21011
|
-
if (
|
|
21279
|
+
if (usedBudget === "high" && options.decomposeOptions && !subQueries && !options.graphRefine) {
|
|
21280
|
+
degraded.push("decompose-moved");
|
|
21281
|
+
}
|
|
21012
21282
|
if (embeddingsUnavailable) degraded.push("embeddings-unavailable");
|
|
21013
21283
|
const diagnostics = {
|
|
21014
21284
|
usedBudget,
|
|
@@ -21121,10 +21391,8 @@ async function recall(query, ctx, options = {}) {
|
|
|
21121
21391
|
},
|
|
21122
21392
|
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
21123
21393
|
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
21124
|
-
|
|
21125
|
-
|
|
21126
|
-
decomposeOptions: options.decomposeOptions
|
|
21127
|
-
},
|
|
21394
|
+
// 719/B4 — composite facets arrive pre-built; no LLM call here.
|
|
21395
|
+
...subQueries && { subQueries },
|
|
21128
21396
|
...options.scopes && { scopes: options.scopes },
|
|
21129
21397
|
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
21130
21398
|
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
@@ -21361,6 +21629,7 @@ var init_recall = __esm({
|
|
|
21361
21629
|
init_logger();
|
|
21362
21630
|
init_constants();
|
|
21363
21631
|
init_embeddings();
|
|
21632
|
+
init_decomposeQuery();
|
|
21364
21633
|
init_searchTool();
|
|
21365
21634
|
init_graphTraversal();
|
|
21366
21635
|
init_observationTrend();
|
|
@@ -22306,52 +22575,51 @@ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, se
|
|
|
22306
22575
|
...searchOptions?.rrfK !== void 0 && { rrfK: searchOptions.rrfK },
|
|
22307
22576
|
...searchOptions?.factTypeWeights && { factTypeWeights: searchOptions.factTypeWeights }
|
|
22308
22577
|
};
|
|
22309
|
-
|
|
22310
|
-
|
|
22311
|
-
|
|
22312
|
-
|
|
22313
|
-
|
|
22314
|
-
|
|
22315
|
-
|
|
22316
|
-
|
|
22317
|
-
|
|
22318
|
-
|
|
22319
|
-
|
|
22320
|
-
|
|
22321
|
-
|
|
22322
|
-
|
|
22323
|
-
|
|
22324
|
-
|
|
22325
|
-
|
|
22326
|
-
|
|
22327
|
-
|
|
22328
|
-
|
|
22329
|
-
|
|
22330
|
-
|
|
22331
|
-
|
|
22332
|
-
|
|
22333
|
-
|
|
22334
|
-
|
|
22335
|
-
|
|
22336
|
-
|
|
22337
|
-
|
|
22338
|
-
|
|
22339
|
-
|
|
22340
|
-
|
|
22341
|
-
|
|
22342
|
-
|
|
22343
|
-
|
|
22344
|
-
|
|
22345
|
-
|
|
22346
|
-
|
|
22347
|
-
|
|
22348
|
-
|
|
22349
|
-
|
|
22350
|
-
|
|
22351
|
-
|
|
22352
|
-
|
|
22353
|
-
|
|
22354
|
-
}
|
|
22578
|
+
const normalizedFacets = normalizeSubQueries(searchOptions?.subQueries);
|
|
22579
|
+
const facetQueries = normalizedFacets.length >= 2 ? normalizedFacets : void 0;
|
|
22580
|
+
if (useFusion && !embeddingsUnavailable && facetQueries) {
|
|
22581
|
+
let subEmbeddings;
|
|
22582
|
+
try {
|
|
22583
|
+
subEmbeddings = await generateEmbeddings(facetQueries, embeddingOptions);
|
|
22584
|
+
} catch (err) {
|
|
22585
|
+
getLogger().warn(
|
|
22586
|
+
"memoryVault: sub-query embedding failed \u2014 falling back to single-query ranking: " + (err instanceof Error ? err.message : String(err))
|
|
22587
|
+
);
|
|
22588
|
+
subEmbeddings = [];
|
|
22589
|
+
}
|
|
22590
|
+
const subEmbeddingsUsable = facetQueries.length > 0 && subEmbeddings.length === facetQueries.length && subEmbeddings.every((v) => v.length > 0 && v.length === queryEmbedding.length);
|
|
22591
|
+
if (subEmbeddings.length > 0 && !subEmbeddingsUsable) {
|
|
22592
|
+
getLogger().warn(
|
|
22593
|
+
`memoryVault: sub-query embedding returned ${subEmbeddings.length} vectors (dims ${subEmbeddings.map((v) => v.length).join(",")}) for ${facetQueries.length} sub-queries against a ${queryEmbedding.length}-dim query \u2014 falling back to single-query ranking`
|
|
22594
|
+
);
|
|
22595
|
+
}
|
|
22596
|
+
if (subEmbeddingsUsable) {
|
|
22597
|
+
const subQueries = facetQueries.map((sq, i) => ({
|
|
22598
|
+
query: sq,
|
|
22599
|
+
embedding: subEmbeddings[i]
|
|
22600
|
+
}));
|
|
22601
|
+
const v2HeadStats = { hadResults: false };
|
|
22602
|
+
const composite = await rankComposite(query, queryEmbedding, subQueries, embeddedItems, {
|
|
22603
|
+
limit,
|
|
22604
|
+
minSimilarity,
|
|
22605
|
+
rerank: !!searchOptions?.rerank,
|
|
22606
|
+
...searchOptions?.rerankTopN !== void 0 && {
|
|
22607
|
+
rerankTopN: searchOptions.rerankTopN
|
|
22608
|
+
},
|
|
22609
|
+
...searchOptions?.ceWeight !== void 0 && { ceWeight: searchOptions.ceWeight },
|
|
22610
|
+
...searchOptions?.mmr !== void 0 && { mmr: searchOptions.mmr },
|
|
22611
|
+
...tuning,
|
|
22612
|
+
...searchOptions?.entityRanking && { entityRanking: searchOptions.entityRanking },
|
|
22613
|
+
...searchOptions?.temporalRanking && { temporalRanking: searchOptions.temporalRanking },
|
|
22614
|
+
rerankStats,
|
|
22615
|
+
v2HeadStats
|
|
22616
|
+
});
|
|
22617
|
+
return stampTimestamps({
|
|
22618
|
+
results: composite,
|
|
22619
|
+
vaultSize,
|
|
22620
|
+
reranked: rerankStats.applied,
|
|
22621
|
+
hadV2Head: v2HeadStats.hadResults
|
|
22622
|
+
});
|
|
22355
22623
|
}
|
|
22356
22624
|
}
|
|
22357
22625
|
if (useFusion && searchOptions?.rerank) {
|
|
@@ -22411,6 +22679,12 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
22411
22679
|
rankedOnCosine: false
|
|
22412
22680
|
};
|
|
22413
22681
|
}
|
|
22682
|
+
if (searchOptions?.decompose === "llm" && normalizeSubQueries(searchOptions.subQueries).length < 2 && !warnedProgrammaticDecomposeIgnored) {
|
|
22683
|
+
warnedProgrammaticDecomposeIgnored = true;
|
|
22684
|
+
getLogger().warn(
|
|
22685
|
+
'memoryVault: decompose:"llm" is ignored by searchVaultMemories \u2014 pass subQueries or use createMemoryVaultSearchTool / createRecallTool (719/B4)'
|
|
22686
|
+
);
|
|
22687
|
+
}
|
|
22414
22688
|
const prepared = await prepareVaultCandidates(
|
|
22415
22689
|
query,
|
|
22416
22690
|
vaultCtx,
|
|
@@ -22515,7 +22789,8 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
22515
22789
|
return "Error: A search query is required.";
|
|
22516
22790
|
}
|
|
22517
22791
|
try {
|
|
22518
|
-
const
|
|
22792
|
+
const wantsDecompose = searchOptions?.decompose === "llm" && !!searchOptions.decomposeOptions;
|
|
22793
|
+
const budget = wantsDecompose ? "high" : searchOptions?.rerank ? "mid" : "low";
|
|
22519
22794
|
const folderId = searchOptions?.folderId ?? argFolderId;
|
|
22520
22795
|
if (searchOptions?.useFusion === false) {
|
|
22521
22796
|
const { results: legacy, embeddingsUnavailable } = await searchVaultMemoriesWithSize(
|
|
@@ -22539,6 +22814,13 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
22539
22814
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
22540
22815
|
);
|
|
22541
22816
|
}
|
|
22817
|
+
let subQueries;
|
|
22818
|
+
if (wantsDecompose && searchOptions?.decomposeOptions) {
|
|
22819
|
+
const decomp = await decomposeQuery(query, searchOptions.decomposeOptions);
|
|
22820
|
+
if (decomp.mode === "composite" && decomp.subQueries.length >= 2) {
|
|
22821
|
+
subQueries = decomp.subQueries;
|
|
22822
|
+
}
|
|
22823
|
+
}
|
|
22542
22824
|
const { recall: recall2 } = await Promise.resolve().then(() => (init_recall(), recall_exports));
|
|
22543
22825
|
let recallDegraded = [];
|
|
22544
22826
|
const result = await recall2(
|
|
@@ -22555,9 +22837,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
22555
22837
|
...tuningForward,
|
|
22556
22838
|
...folderId !== void 0 && { folderId },
|
|
22557
22839
|
...searchOptions?.scopes && { scopes: searchOptions.scopes },
|
|
22558
|
-
...
|
|
22559
|
-
decomposeOptions: searchOptions.decomposeOptions
|
|
22560
|
-
}
|
|
22840
|
+
...subQueries && { subQueries }
|
|
22561
22841
|
}
|
|
22562
22842
|
);
|
|
22563
22843
|
if (result.vaultSize === 0) {
|
|
@@ -22587,7 +22867,7 @@ ${formatted}`;
|
|
|
22587
22867
|
}
|
|
22588
22868
|
};
|
|
22589
22869
|
}
|
|
22590
|
-
var SUPERSESSION_SIMILARITY_THRESHOLD, SUPERSESSION_MIN_AGE_GAP_MS, SUPERSESSION_BOOST_FACTOR, SUPERSESSION_MAX_WINDOW, EMBEDDINGS_DEGRADED_EMPTY_NO_LEXICAL;
|
|
22870
|
+
var warnedProgrammaticDecomposeIgnored, SUPERSESSION_SIMILARITY_THRESHOLD, SUPERSESSION_MIN_AGE_GAP_MS, SUPERSESSION_BOOST_FACTOR, SUPERSESSION_MAX_WINDOW, EMBEDDINGS_DEGRADED_EMPTY_NO_LEXICAL;
|
|
22591
22871
|
var init_searchTool = __esm({
|
|
22592
22872
|
"src/lib/memoryVault/searchTool.ts"() {
|
|
22593
22873
|
"use strict";
|
|
@@ -22605,6 +22885,7 @@ var init_searchTool = __esm({
|
|
|
22605
22885
|
init_bm25();
|
|
22606
22886
|
init_decomposeQuery();
|
|
22607
22887
|
init_lruCache();
|
|
22888
|
+
warnedProgrammaticDecomposeIgnored = false;
|
|
22608
22889
|
SUPERSESSION_SIMILARITY_THRESHOLD = 0.7;
|
|
22609
22890
|
SUPERSESSION_MIN_AGE_GAP_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
22610
22891
|
SUPERSESSION_BOOST_FACTOR = 0.8;
|
|
@@ -23465,6 +23746,7 @@ __export(index_exports, {
|
|
|
23465
23746
|
DEFAULT_VAULT_CACHE_SIZE: () => DEFAULT_VAULT_CACHE_SIZE,
|
|
23466
23747
|
DatabaseManager: () => DatabaseManager,
|
|
23467
23748
|
ENTITY_FANOUT: () => ENTITY_FANOUT,
|
|
23749
|
+
EncryptionKeyMissingError: () => EncryptionKeyMissingError,
|
|
23468
23750
|
ExcelProcessor: () => ExcelProcessor,
|
|
23469
23751
|
HARD_DELETE_WINDOW_MS: () => HARD_DELETE_WINDOW_MS,
|
|
23470
23752
|
INFERENCE_ID_HEADER: () => INFERENCE_ID_HEADER,
|
|
@@ -23665,6 +23947,7 @@ __export(index_exports, {
|
|
|
23665
23947
|
rankProfileCandidates: () => rankProfileCandidates,
|
|
23666
23948
|
recall: () => recall,
|
|
23667
23949
|
reflect: () => reflect,
|
|
23950
|
+
refreshEncryptionKeyIfMatches: () => refreshEncryptionKeyIfMatches,
|
|
23668
23951
|
relinkMemoryTopicsOp: () => relinkMemoryTopicsOp,
|
|
23669
23952
|
relinkMisclassifiedVideosOp: () => relinkMisclassifiedVideosOp,
|
|
23670
23953
|
renderTemplate: () => renderTemplate,
|
|
@@ -23685,6 +23968,7 @@ __export(index_exports, {
|
|
|
23685
23968
|
searchMediaOp: () => searchMediaOp,
|
|
23686
23969
|
searchMessagesOp: () => searchMessagesOp,
|
|
23687
23970
|
searchVaultMemories: () => searchVaultMemories,
|
|
23971
|
+
seedEncryptionKeys: () => seedEncryptionKeys,
|
|
23688
23972
|
selectServerToolsForPrompt: () => selectServerToolsForPrompt,
|
|
23689
23973
|
serverPlatformStorage: () => serverPlatformStorage,
|
|
23690
23974
|
setMemoryVisibilityOp: () => setMemoryVisibilityOp,
|
|
@@ -29478,6 +29762,7 @@ function rankProfileCandidates(inputs, now = Date.now(), options = {}) {
|
|
|
29478
29762
|
init_recall();
|
|
29479
29763
|
|
|
29480
29764
|
// src/lib/memory/recallTool.ts
|
|
29765
|
+
init_decomposeQuery();
|
|
29481
29766
|
init_recall();
|
|
29482
29767
|
init_recallConstants();
|
|
29483
29768
|
var DEFAULT_LIMIT2 = 8;
|
|
@@ -29575,7 +29860,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
29575
29860
|
type: "function",
|
|
29576
29861
|
function: {
|
|
29577
29862
|
name: RECALL_TOOL_NAME,
|
|
29578
|
-
description:
|
|
29863
|
+
description: `Search the user's memory across stored facts/preferences and past conversation excerpts. Returns a unified ranked list \u2014 facts carry an \`id\` you can reference; conversation excerpts carry a date and role. Use this whenever the user's question may relate to anything previously discussed or saved (preferences, prior decisions, past topics). Phrase the query naturally. For multi-faceted / overview questions ("tell me about the user", "what's my tech stack"), prefer several targeted searches \u2014 one facet each (e.g. name, work, hobbies) \u2014 over a single broad query; fuse the results yourself.`,
|
|
29579
29864
|
arguments: {
|
|
29580
29865
|
type: "object",
|
|
29581
29866
|
properties: {
|
|
@@ -29630,6 +29915,13 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
29630
29915
|
let surfaced = 0;
|
|
29631
29916
|
try {
|
|
29632
29917
|
let recallDegraded = [];
|
|
29918
|
+
let subQueries;
|
|
29919
|
+
if (defaultBudget === "high" && toolOptions?.decomposeOptions) {
|
|
29920
|
+
const decomp = await decomposeQuery(query, toolOptions.decomposeOptions);
|
|
29921
|
+
if (decomp.mode === "composite" && decomp.subQueries.length >= 2) {
|
|
29922
|
+
subQueries = decomp.subQueries;
|
|
29923
|
+
}
|
|
29924
|
+
}
|
|
29633
29925
|
const recallOpts = {
|
|
29634
29926
|
onDiagnostics: (d) => {
|
|
29635
29927
|
recallDegraded = d.degraded;
|
|
@@ -29643,10 +29935,12 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
29643
29935
|
...toolOptions?.excludeConversationId && {
|
|
29644
29936
|
excludeConversationId: toolOptions.excludeConversationId
|
|
29645
29937
|
},
|
|
29646
|
-
|
|
29647
|
-
|
|
29648
|
-
|
|
29649
|
-
|
|
29938
|
+
// Do NOT forward decomposeOptions into recall() — rewrite already
|
|
29939
|
+
// ran above, and forwarding would falsely trip `decompose-moved`
|
|
29940
|
+
// on every specific-mode high-budget call. graphRefine auth can
|
|
29941
|
+
// be threaded later when the tool opts into that path.
|
|
29942
|
+
...toolOptions?.now !== void 0 && { now: toolOptions.now },
|
|
29943
|
+
...subQueries && { subQueries }
|
|
29650
29944
|
};
|
|
29651
29945
|
const result = await recall(query, ctx, recallOpts);
|
|
29652
29946
|
if (callbacks?.onChunksRetrieved) {
|
|
@@ -36169,6 +36463,7 @@ function buildSystemPrompt(ctx, options) {
|
|
|
36169
36463
|
DEFAULT_VAULT_CACHE_SIZE,
|
|
36170
36464
|
DatabaseManager,
|
|
36171
36465
|
ENTITY_FANOUT,
|
|
36466
|
+
EncryptionKeyMissingError,
|
|
36172
36467
|
ExcelProcessor,
|
|
36173
36468
|
HARD_DELETE_WINDOW_MS,
|
|
36174
36469
|
INFERENCE_ID_HEADER,
|
|
@@ -36369,6 +36664,7 @@ function buildSystemPrompt(ctx, options) {
|
|
|
36369
36664
|
rankProfileCandidates,
|
|
36370
36665
|
recall,
|
|
36371
36666
|
reflect,
|
|
36667
|
+
refreshEncryptionKeyIfMatches,
|
|
36372
36668
|
relinkMemoryTopicsOp,
|
|
36373
36669
|
relinkMisclassifiedVideosOp,
|
|
36374
36670
|
renderTemplate,
|
|
@@ -36389,6 +36685,7 @@ function buildSystemPrompt(ctx, options) {
|
|
|
36389
36685
|
searchMediaOp,
|
|
36390
36686
|
searchMessagesOp,
|
|
36391
36687
|
searchVaultMemories,
|
|
36688
|
+
seedEncryptionKeys,
|
|
36392
36689
|
selectServerToolsForPrompt,
|
|
36393
36690
|
serverPlatformStorage,
|
|
36394
36691
|
setMemoryVisibilityOp,
|