@anuma/sdk 9.1.4 → 9.1.5
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 +132 -39
- package/dist/expo/index.d.mts +9 -0
- package/dist/expo/index.d.ts +9 -0
- package/dist/expo/index.mjs +132 -39
- package/dist/memory/context.d.mts +123 -0
- package/dist/memory/context.d.ts +123 -0
- package/dist/react/index.cjs +132 -39
- package/dist/react/index.d.mts +9 -0
- package/dist/react/index.d.ts +9 -0
- package/dist/react/index.mjs +132 -39
- package/dist/server/index.cjs +132 -39
- package/dist/server/index.d.mts +9 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.mjs +132 -39
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -2520,15 +2520,16 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
2520
2520
|
if (!parsed) {
|
|
2521
2521
|
return false;
|
|
2522
2522
|
}
|
|
2523
|
+
const startEpoch = sessionEpoch;
|
|
2523
2524
|
const cached = refreshCandidatesByAddress.get(walletAddress);
|
|
2524
2525
|
if (cached) {
|
|
2525
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached);
|
|
2526
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached, startEpoch);
|
|
2526
2527
|
}
|
|
2527
2528
|
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
2528
2529
|
if (!derivePromise) {
|
|
2529
2530
|
derivePromise = (async () => {
|
|
2530
2531
|
const candidates2 = await deriveRefreshCandidates(signMessage, embeddedWalletSigner);
|
|
2531
|
-
if (candidates2) {
|
|
2532
|
+
if (candidates2 && sessionEpoch === startEpoch) {
|
|
2532
2533
|
refreshCandidatesByAddress.set(walletAddress, candidates2);
|
|
2533
2534
|
}
|
|
2534
2535
|
return candidates2;
|
|
@@ -2540,10 +2541,10 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
2540
2541
|
pendingCandidateDerives.set(walletAddress, derivePromise);
|
|
2541
2542
|
}
|
|
2542
2543
|
const candidates = await derivePromise;
|
|
2543
|
-
if (!candidates) {
|
|
2544
|
+
if (!candidates || sessionEpoch !== startEpoch) {
|
|
2544
2545
|
return false;
|
|
2545
2546
|
}
|
|
2546
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates);
|
|
2547
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch);
|
|
2547
2548
|
}
|
|
2548
2549
|
function parsePrefixedCiphertext(probeCiphertext) {
|
|
2549
2550
|
const version = probeCiphertext.startsWith("enc:v3:") ? "v3" : probeCiphertext.startsWith("enc:v2:") ? "v2" : null;
|
|
@@ -2586,7 +2587,7 @@ async function deriveRefreshCandidates(signMessage, embeddedWalletSigner) {
|
|
|
2586
2587
|
}
|
|
2587
2588
|
return { legacy: legacyKey, current: currentKey };
|
|
2588
2589
|
}
|
|
2589
|
-
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates) {
|
|
2590
|
+
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch) {
|
|
2590
2591
|
const candidateHex = parsed.version === "v2" ? candidates.legacy : candidates.current;
|
|
2591
2592
|
const keyBytes = hexToBytes(candidateHex);
|
|
2592
2593
|
const candidateCryptoKey = await crypto.subtle.importKey(
|
|
@@ -2604,6 +2605,9 @@ async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidat
|
|
|
2604
2605
|
);
|
|
2605
2606
|
return false;
|
|
2606
2607
|
}
|
|
2608
|
+
if (sessionEpoch !== startEpoch) {
|
|
2609
|
+
return false;
|
|
2610
|
+
}
|
|
2607
2611
|
setStoredKey(walletAddress, { legacy: candidates.legacy, current: candidates.current });
|
|
2608
2612
|
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
2609
2613
|
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
@@ -17284,6 +17288,104 @@ function validate(parsed, originalQuery) {
|
|
|
17284
17288
|
return { mode, subQueries };
|
|
17285
17289
|
}
|
|
17286
17290
|
|
|
17291
|
+
// src/lib/memoryVault/vaultPreparation.ts
|
|
17292
|
+
function createVaultPreparation() {
|
|
17293
|
+
return { corpora: /* @__PURE__ */ new WeakMap(), rows: /* @__PURE__ */ new WeakMap() };
|
|
17294
|
+
}
|
|
17295
|
+
var pendingRows = /* @__PURE__ */ new WeakMap();
|
|
17296
|
+
function loadVaultCorpus(ctx, options, preparation) {
|
|
17297
|
+
if (!preparation) return getAllVaultMemoriesOp(ctx, options);
|
|
17298
|
+
const corpusCache = preparation.corpora;
|
|
17299
|
+
let pending = corpusCache.get(ctx);
|
|
17300
|
+
if (!pending) {
|
|
17301
|
+
pending = /* @__PURE__ */ new Map();
|
|
17302
|
+
corpusCache.set(ctx, pending);
|
|
17303
|
+
}
|
|
17304
|
+
const key = JSON.stringify(options ?? {});
|
|
17305
|
+
let request = pending.get(key);
|
|
17306
|
+
if (!request) {
|
|
17307
|
+
const entries = pending;
|
|
17308
|
+
request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
|
|
17309
|
+
entries.delete(key);
|
|
17310
|
+
throw error;
|
|
17311
|
+
});
|
|
17312
|
+
pending.set(key, request);
|
|
17313
|
+
}
|
|
17314
|
+
return request;
|
|
17315
|
+
}
|
|
17316
|
+
function rowRequestsFor(registry2, ctx, maskInput) {
|
|
17317
|
+
let byMask = registry2.get(ctx);
|
|
17318
|
+
if (!byMask) {
|
|
17319
|
+
byMask = /* @__PURE__ */ new Map();
|
|
17320
|
+
registry2.set(ctx, byMask);
|
|
17321
|
+
}
|
|
17322
|
+
let requests = byMask.get(maskInput);
|
|
17323
|
+
if (!requests) {
|
|
17324
|
+
requests = /* @__PURE__ */ new Map();
|
|
17325
|
+
byMask.set(maskInput, requests);
|
|
17326
|
+
}
|
|
17327
|
+
return requests;
|
|
17328
|
+
}
|
|
17329
|
+
function embedVaultRows(ctx, options, rows, preparation) {
|
|
17330
|
+
const pending = rowRequestsFor(pendingRows, ctx, options.maskInput);
|
|
17331
|
+
const prepared = preparation && rowRequestsFor(preparation.rows, ctx, options.maskInput);
|
|
17332
|
+
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
17333
|
+
const keys = rows.map(
|
|
17334
|
+
(row) => JSON.stringify([
|
|
17335
|
+
row.uniqueId,
|
|
17336
|
+
row.updatedAt?.getTime(),
|
|
17337
|
+
row.content,
|
|
17338
|
+
model,
|
|
17339
|
+
options.baseUrl,
|
|
17340
|
+
options.timeoutMs,
|
|
17341
|
+
options.tokenTimeoutMs,
|
|
17342
|
+
options.totalTimeoutMs
|
|
17343
|
+
])
|
|
17344
|
+
);
|
|
17345
|
+
const missing = /* @__PURE__ */ new Map();
|
|
17346
|
+
rows.forEach((row, index) => {
|
|
17347
|
+
if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing.set(keys[index], row);
|
|
17348
|
+
});
|
|
17349
|
+
if (missing.size > 0) {
|
|
17350
|
+
const entries = pending;
|
|
17351
|
+
const batch = Promise.resolve().then(
|
|
17352
|
+
() => generateEmbeddings(
|
|
17353
|
+
[...missing.values()].map((row) => row.content),
|
|
17354
|
+
options
|
|
17355
|
+
)
|
|
17356
|
+
);
|
|
17357
|
+
[...missing].forEach(([key, row], index) => {
|
|
17358
|
+
const request = batch.then((vectors) => {
|
|
17359
|
+
const vector = vectors[index];
|
|
17360
|
+
updateVaultMemoryEmbeddingOp(ctx, row.uniqueId, JSON.stringify(vector), model, {
|
|
17361
|
+
content: row.content,
|
|
17362
|
+
updatedAt: row.updatedAt?.getTime()
|
|
17363
|
+
}).catch(() => {
|
|
17364
|
+
});
|
|
17365
|
+
return vector;
|
|
17366
|
+
}).finally(() => {
|
|
17367
|
+
entries.delete(key);
|
|
17368
|
+
if (entries.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
|
|
17369
|
+
});
|
|
17370
|
+
pending.set(key, request);
|
|
17371
|
+
});
|
|
17372
|
+
}
|
|
17373
|
+
return Promise.all(
|
|
17374
|
+
keys.map((key) => {
|
|
17375
|
+
const cached = prepared?.get(key);
|
|
17376
|
+
if (cached) return cached;
|
|
17377
|
+
const request = pending.get(key);
|
|
17378
|
+
if (!prepared) return request;
|
|
17379
|
+
const retained = request.catch((error) => {
|
|
17380
|
+
prepared.delete(key);
|
|
17381
|
+
throw error;
|
|
17382
|
+
});
|
|
17383
|
+
prepared.set(key, retained);
|
|
17384
|
+
return retained;
|
|
17385
|
+
})
|
|
17386
|
+
);
|
|
17387
|
+
}
|
|
17388
|
+
|
|
17287
17389
|
// src/lib/memoryVault/vectorVersion.ts
|
|
17288
17390
|
var vectorRowVersion = /* @__PURE__ */ new WeakMap();
|
|
17289
17391
|
function contentFingerprint(content) {
|
|
@@ -17846,11 +17948,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
17846
17948
|
return combined.slice(0, limit);
|
|
17847
17949
|
}
|
|
17848
17950
|
async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options) {
|
|
17849
|
-
const memories = await
|
|
17951
|
+
const memories = await loadVaultCorpus(vaultCtx, options);
|
|
17850
17952
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
17851
17953
|
const uncachedTexts = [];
|
|
17852
17954
|
const uncachedKeys = [];
|
|
17853
|
-
const
|
|
17955
|
+
const uncachedRows = [];
|
|
17854
17956
|
const uncachedVersions = [];
|
|
17855
17957
|
for (const m of memories) {
|
|
17856
17958
|
const content = m.content;
|
|
@@ -17869,12 +17971,12 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
17869
17971
|
}
|
|
17870
17972
|
uncachedTexts.push(m.content);
|
|
17871
17973
|
uncachedKeys.push(m.uniqueId);
|
|
17872
|
-
|
|
17974
|
+
uncachedRows.push(m);
|
|
17873
17975
|
uncachedVersions.push(m.updatedAt);
|
|
17874
17976
|
}
|
|
17875
17977
|
}
|
|
17876
17978
|
if (uncachedTexts.length > 0) {
|
|
17877
|
-
const embeddings = await
|
|
17979
|
+
const embeddings = await embedVaultRows(vaultCtx, embeddingOptions, uncachedRows);
|
|
17878
17980
|
for (let i = 0; i < uncachedKeys.length; i++) {
|
|
17879
17981
|
cacheRowVector(
|
|
17880
17982
|
cache,
|
|
@@ -17883,13 +17985,6 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
17883
17985
|
uncachedVersions[i],
|
|
17884
17986
|
uncachedTexts[i]
|
|
17885
17987
|
);
|
|
17886
|
-
updateVaultMemoryEmbeddingOp(
|
|
17887
|
-
vaultCtx,
|
|
17888
|
-
uncachedIds[i],
|
|
17889
|
-
JSON.stringify(embeddings[i]),
|
|
17890
|
-
currentModel
|
|
17891
|
-
).catch(() => {
|
|
17892
|
-
});
|
|
17893
17988
|
}
|
|
17894
17989
|
}
|
|
17895
17990
|
}
|
|
@@ -18031,10 +18126,7 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
18031
18126
|
let laneVecs;
|
|
18032
18127
|
if (opts.embedStats) opts.embedStats.rowsEmbedded += laneRows.length;
|
|
18033
18128
|
try {
|
|
18034
|
-
laneVecs = await
|
|
18035
|
-
laneRows.map((m) => m.content),
|
|
18036
|
-
embeddingOptions
|
|
18037
|
-
);
|
|
18129
|
+
laneVecs = await embedVaultRows(vaultCtx, embeddingOptions, laneRows);
|
|
18038
18130
|
} catch (err) {
|
|
18039
18131
|
laneEmbedFailed = true;
|
|
18040
18132
|
getLogger().warn(
|
|
@@ -18048,13 +18140,6 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
18048
18140
|
cacheRowVector(cache, m.uniqueId, vec, m.updatedAt, m.content);
|
|
18049
18141
|
resolvedThisCall.add(m.uniqueId);
|
|
18050
18142
|
vectored.push({ uniqueId: m.uniqueId, embedding: vec, updatedAt: m.updatedAt });
|
|
18051
|
-
updateVaultMemoryEmbeddingOp(
|
|
18052
|
-
vaultCtx,
|
|
18053
|
-
m.uniqueId,
|
|
18054
|
-
JSON.stringify(vecs[i]),
|
|
18055
|
-
currentModel
|
|
18056
|
-
).catch(() => {
|
|
18057
|
-
});
|
|
18058
18143
|
});
|
|
18059
18144
|
}
|
|
18060
18145
|
}
|
|
@@ -18246,9 +18331,10 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
18246
18331
|
};
|
|
18247
18332
|
}
|
|
18248
18333
|
} else {
|
|
18249
|
-
const loaded = await
|
|
18334
|
+
const loaded = await loadVaultCorpus(
|
|
18250
18335
|
vaultCtx,
|
|
18251
|
-
Object.keys(queryOpts).length > 0 ? queryOpts : void 0
|
|
18336
|
+
Object.keys(queryOpts).length > 0 ? queryOpts : void 0,
|
|
18337
|
+
searchOptions?.vaultPreparation
|
|
18252
18338
|
);
|
|
18253
18339
|
vaultSize = loaded.length;
|
|
18254
18340
|
rowsDecrypted = loaded.length;
|
|
@@ -18321,7 +18407,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
18321
18407
|
let newEmbeddings;
|
|
18322
18408
|
embedStats.rowsEmbedded += uncachedTexts.length;
|
|
18323
18409
|
try {
|
|
18324
|
-
newEmbeddings = await
|
|
18410
|
+
newEmbeddings = await embedVaultRows(
|
|
18411
|
+
vaultCtx,
|
|
18412
|
+
embeddingOptions,
|
|
18413
|
+
uncachedIndices.map((index) => memories[index]),
|
|
18414
|
+
searchOptions?.vaultPreparation
|
|
18415
|
+
);
|
|
18325
18416
|
} catch (err) {
|
|
18326
18417
|
embeddingFailure = true;
|
|
18327
18418
|
getLogger().warn(
|
|
@@ -18337,13 +18428,6 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
18337
18428
|
memories[uncachedIndices[j]].updatedAt,
|
|
18338
18429
|
memories[uncachedIndices[j]].content
|
|
18339
18430
|
);
|
|
18340
|
-
updateVaultMemoryEmbeddingOp(
|
|
18341
|
-
vaultCtx,
|
|
18342
|
-
memories[uncachedIndices[j]].uniqueId,
|
|
18343
|
-
JSON.stringify(newEmbeddings[j]),
|
|
18344
|
-
currentModel
|
|
18345
|
-
).catch(() => {
|
|
18346
|
-
});
|
|
18347
18431
|
}
|
|
18348
18432
|
}
|
|
18349
18433
|
}
|
|
@@ -20898,6 +20982,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
20898
20982
|
},
|
|
20899
20983
|
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
20900
20984
|
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
20985
|
+
...options.vaultPreparation && { vaultPreparation: options.vaultPreparation },
|
|
20901
20986
|
...subQueries && { subQueries },
|
|
20902
20987
|
...options.scopes && { scopes: options.scopes },
|
|
20903
20988
|
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
@@ -24503,13 +24588,20 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
24503
24588
|
}
|
|
24504
24589
|
}
|
|
24505
24590
|
}
|
|
24591
|
+
const vaultPreparation = createVaultPreparation();
|
|
24506
24592
|
const settled = await Promise.allSettled(
|
|
24507
24593
|
facets.map(async (facet) => {
|
|
24508
24594
|
const prior = previous?.sections.find((s) => s.key === facet.key);
|
|
24509
24595
|
if (prior && !staleKeys.has(facet.key)) {
|
|
24510
24596
|
return prior;
|
|
24511
24597
|
}
|
|
24512
|
-
return synthesizeFacet(
|
|
24598
|
+
return synthesizeFacet(
|
|
24599
|
+
facet,
|
|
24600
|
+
recallCtx,
|
|
24601
|
+
options,
|
|
24602
|
+
fallbackPriors.get(facet.key),
|
|
24603
|
+
vaultPreparation
|
|
24604
|
+
);
|
|
24513
24605
|
})
|
|
24514
24606
|
);
|
|
24515
24607
|
const sections = settled.map((r, i) => {
|
|
@@ -24663,7 +24755,7 @@ async function attributeFacts(ctx, candidates, facets) {
|
|
|
24663
24755
|
}
|
|
24664
24756
|
return keys;
|
|
24665
24757
|
}
|
|
24666
|
-
async function synthesizeFacet(facet, ctx, options, prior) {
|
|
24758
|
+
async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
24667
24759
|
const scopes = options.scopes ?? DEFAULT_SCOPES;
|
|
24668
24760
|
const limit = options.limit ?? DEFAULT_FACET_RECALL_LIMIT;
|
|
24669
24761
|
const factTypeWeights = { ...DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, ...options.factTypeWeights };
|
|
@@ -24680,6 +24772,7 @@ async function synthesizeFacet(facet, ctx, options, prior) {
|
|
|
24680
24772
|
};
|
|
24681
24773
|
}
|
|
24682
24774
|
const recalled = await recall(facet.query, ctx, {
|
|
24775
|
+
vaultPreparation,
|
|
24683
24776
|
scopes,
|
|
24684
24777
|
limit: hasReviewGate ? RECALL_MAX_LIMIT : limit,
|
|
24685
24778
|
types: ["fact"],
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -3902,6 +3902,13 @@ interface RecencyOptions {
|
|
|
3902
3902
|
noDateMultiplier?: number;
|
|
3903
3903
|
}
|
|
3904
3904
|
|
|
3905
|
+
type VaultCorpusCache = WeakMap<VaultMemoryOperationsContext, Map<string, Promise<StoredVaultMemory[]>>>;
|
|
3906
|
+
type RowRequests = Map<EmbeddingOptions["maskInput"], Map<string, Promise<number[]>>>;
|
|
3907
|
+
interface VaultPreparation {
|
|
3908
|
+
corpora: VaultCorpusCache;
|
|
3909
|
+
rows: WeakMap<VaultMemoryOperationsContext, RowRequests>;
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3905
3912
|
declare const DEFAULT_VAULT_CACHE_SIZE = 5000;
|
|
3906
3913
|
/**
|
|
3907
3914
|
* Create a VaultEmbeddingCache backed by an LRU with a default cap of
|
|
@@ -3919,6 +3926,7 @@ type VaultEmbeddingCache = Map<string, Float32Array>;
|
|
|
3919
3926
|
* Options for the vault search tool.
|
|
3920
3927
|
*/
|
|
3921
3928
|
interface MemoryVaultSearchOptions {
|
|
3929
|
+
/** @internal */ vaultPreparation?: VaultPreparation;
|
|
3922
3930
|
onCandidateCount?: (count: number) => void;
|
|
3923
3931
|
/** Maximum number of results to return (default: 5) */
|
|
3924
3932
|
limit?: number;
|
|
@@ -4441,6 +4449,7 @@ interface RankedMemory {
|
|
|
4441
4449
|
updatedAt: Date;
|
|
4442
4450
|
}
|
|
4443
4451
|
interface RecallOptions {
|
|
4452
|
+
/** @internal */ vaultPreparation?: VaultPreparation;
|
|
4444
4453
|
/** Embedding cache shared with the rest of the turn, so the query is embedded once across lanes and the send. */
|
|
4445
4454
|
embeddingCache?: Map<string, Float32Array>;
|
|
4446
4455
|
/** Which kinds to search. Default: ['fact']. */
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -3902,6 +3902,13 @@ interface RecencyOptions {
|
|
|
3902
3902
|
noDateMultiplier?: number;
|
|
3903
3903
|
}
|
|
3904
3904
|
|
|
3905
|
+
type VaultCorpusCache = WeakMap<VaultMemoryOperationsContext, Map<string, Promise<StoredVaultMemory[]>>>;
|
|
3906
|
+
type RowRequests = Map<EmbeddingOptions["maskInput"], Map<string, Promise<number[]>>>;
|
|
3907
|
+
interface VaultPreparation {
|
|
3908
|
+
corpora: VaultCorpusCache;
|
|
3909
|
+
rows: WeakMap<VaultMemoryOperationsContext, RowRequests>;
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3905
3912
|
declare const DEFAULT_VAULT_CACHE_SIZE = 5000;
|
|
3906
3913
|
/**
|
|
3907
3914
|
* Create a VaultEmbeddingCache backed by an LRU with a default cap of
|
|
@@ -3919,6 +3926,7 @@ type VaultEmbeddingCache = Map<string, Float32Array>;
|
|
|
3919
3926
|
* Options for the vault search tool.
|
|
3920
3927
|
*/
|
|
3921
3928
|
interface MemoryVaultSearchOptions {
|
|
3929
|
+
/** @internal */ vaultPreparation?: VaultPreparation;
|
|
3922
3930
|
onCandidateCount?: (count: number) => void;
|
|
3923
3931
|
/** Maximum number of results to return (default: 5) */
|
|
3924
3932
|
limit?: number;
|
|
@@ -4441,6 +4449,7 @@ interface RankedMemory {
|
|
|
4441
4449
|
updatedAt: Date;
|
|
4442
4450
|
}
|
|
4443
4451
|
interface RecallOptions {
|
|
4452
|
+
/** @internal */ vaultPreparation?: VaultPreparation;
|
|
4444
4453
|
/** Embedding cache shared with the rest of the turn, so the query is embedded once across lanes and the send. */
|
|
4445
4454
|
embeddingCache?: Map<string, Float32Array>;
|
|
4446
4455
|
/** Which kinds to search. Default: ['fact']. */
|
package/dist/expo/index.mjs
CHANGED
|
@@ -923,15 +923,16 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
923
923
|
if (!parsed) {
|
|
924
924
|
return false;
|
|
925
925
|
}
|
|
926
|
+
const startEpoch = sessionEpoch;
|
|
926
927
|
const cached = refreshCandidatesByAddress.get(walletAddress);
|
|
927
928
|
if (cached) {
|
|
928
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached);
|
|
929
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached, startEpoch);
|
|
929
930
|
}
|
|
930
931
|
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
931
932
|
if (!derivePromise) {
|
|
932
933
|
derivePromise = (async () => {
|
|
933
934
|
const candidates2 = await deriveRefreshCandidates(signMessage, embeddedWalletSigner);
|
|
934
|
-
if (candidates2) {
|
|
935
|
+
if (candidates2 && sessionEpoch === startEpoch) {
|
|
935
936
|
refreshCandidatesByAddress.set(walletAddress, candidates2);
|
|
936
937
|
}
|
|
937
938
|
return candidates2;
|
|
@@ -943,10 +944,10 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
943
944
|
pendingCandidateDerives.set(walletAddress, derivePromise);
|
|
944
945
|
}
|
|
945
946
|
const candidates = await derivePromise;
|
|
946
|
-
if (!candidates) {
|
|
947
|
+
if (!candidates || sessionEpoch !== startEpoch) {
|
|
947
948
|
return false;
|
|
948
949
|
}
|
|
949
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates);
|
|
950
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch);
|
|
950
951
|
}
|
|
951
952
|
function parsePrefixedCiphertext(probeCiphertext) {
|
|
952
953
|
const version = probeCiphertext.startsWith("enc:v3:") ? "v3" : probeCiphertext.startsWith("enc:v2:") ? "v2" : null;
|
|
@@ -989,7 +990,7 @@ async function deriveRefreshCandidates(signMessage, embeddedWalletSigner) {
|
|
|
989
990
|
}
|
|
990
991
|
return { legacy: legacyKey, current: currentKey };
|
|
991
992
|
}
|
|
992
|
-
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates) {
|
|
993
|
+
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch) {
|
|
993
994
|
const candidateHex = parsed.version === "v2" ? candidates.legacy : candidates.current;
|
|
994
995
|
const keyBytes = hexToBytes(candidateHex);
|
|
995
996
|
const candidateCryptoKey = await crypto.subtle.importKey(
|
|
@@ -1007,6 +1008,9 @@ async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidat
|
|
|
1007
1008
|
);
|
|
1008
1009
|
return false;
|
|
1009
1010
|
}
|
|
1011
|
+
if (sessionEpoch !== startEpoch) {
|
|
1012
|
+
return false;
|
|
1013
|
+
}
|
|
1010
1014
|
setStoredKey(walletAddress, { legacy: candidates.legacy, current: candidates.current });
|
|
1011
1015
|
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
1012
1016
|
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
@@ -15635,6 +15639,104 @@ function validate(parsed, originalQuery) {
|
|
|
15635
15639
|
return { mode, subQueries };
|
|
15636
15640
|
}
|
|
15637
15641
|
|
|
15642
|
+
// src/lib/memoryVault/vaultPreparation.ts
|
|
15643
|
+
function createVaultPreparation() {
|
|
15644
|
+
return { corpora: /* @__PURE__ */ new WeakMap(), rows: /* @__PURE__ */ new WeakMap() };
|
|
15645
|
+
}
|
|
15646
|
+
var pendingRows = /* @__PURE__ */ new WeakMap();
|
|
15647
|
+
function loadVaultCorpus(ctx, options, preparation) {
|
|
15648
|
+
if (!preparation) return getAllVaultMemoriesOp(ctx, options);
|
|
15649
|
+
const corpusCache = preparation.corpora;
|
|
15650
|
+
let pending = corpusCache.get(ctx);
|
|
15651
|
+
if (!pending) {
|
|
15652
|
+
pending = /* @__PURE__ */ new Map();
|
|
15653
|
+
corpusCache.set(ctx, pending);
|
|
15654
|
+
}
|
|
15655
|
+
const key = JSON.stringify(options ?? {});
|
|
15656
|
+
let request = pending.get(key);
|
|
15657
|
+
if (!request) {
|
|
15658
|
+
const entries = pending;
|
|
15659
|
+
request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
|
|
15660
|
+
entries.delete(key);
|
|
15661
|
+
throw error;
|
|
15662
|
+
});
|
|
15663
|
+
pending.set(key, request);
|
|
15664
|
+
}
|
|
15665
|
+
return request;
|
|
15666
|
+
}
|
|
15667
|
+
function rowRequestsFor(registry2, ctx, maskInput) {
|
|
15668
|
+
let byMask = registry2.get(ctx);
|
|
15669
|
+
if (!byMask) {
|
|
15670
|
+
byMask = /* @__PURE__ */ new Map();
|
|
15671
|
+
registry2.set(ctx, byMask);
|
|
15672
|
+
}
|
|
15673
|
+
let requests = byMask.get(maskInput);
|
|
15674
|
+
if (!requests) {
|
|
15675
|
+
requests = /* @__PURE__ */ new Map();
|
|
15676
|
+
byMask.set(maskInput, requests);
|
|
15677
|
+
}
|
|
15678
|
+
return requests;
|
|
15679
|
+
}
|
|
15680
|
+
function embedVaultRows(ctx, options, rows, preparation) {
|
|
15681
|
+
const pending = rowRequestsFor(pendingRows, ctx, options.maskInput);
|
|
15682
|
+
const prepared = preparation && rowRequestsFor(preparation.rows, ctx, options.maskInput);
|
|
15683
|
+
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
15684
|
+
const keys = rows.map(
|
|
15685
|
+
(row) => JSON.stringify([
|
|
15686
|
+
row.uniqueId,
|
|
15687
|
+
row.updatedAt?.getTime(),
|
|
15688
|
+
row.content,
|
|
15689
|
+
model,
|
|
15690
|
+
options.baseUrl,
|
|
15691
|
+
options.timeoutMs,
|
|
15692
|
+
options.tokenTimeoutMs,
|
|
15693
|
+
options.totalTimeoutMs
|
|
15694
|
+
])
|
|
15695
|
+
);
|
|
15696
|
+
const missing = /* @__PURE__ */ new Map();
|
|
15697
|
+
rows.forEach((row, index) => {
|
|
15698
|
+
if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing.set(keys[index], row);
|
|
15699
|
+
});
|
|
15700
|
+
if (missing.size > 0) {
|
|
15701
|
+
const entries = pending;
|
|
15702
|
+
const batch = Promise.resolve().then(
|
|
15703
|
+
() => generateEmbeddings(
|
|
15704
|
+
[...missing.values()].map((row) => row.content),
|
|
15705
|
+
options
|
|
15706
|
+
)
|
|
15707
|
+
);
|
|
15708
|
+
[...missing].forEach(([key, row], index) => {
|
|
15709
|
+
const request = batch.then((vectors) => {
|
|
15710
|
+
const vector = vectors[index];
|
|
15711
|
+
updateVaultMemoryEmbeddingOp(ctx, row.uniqueId, JSON.stringify(vector), model, {
|
|
15712
|
+
content: row.content,
|
|
15713
|
+
updatedAt: row.updatedAt?.getTime()
|
|
15714
|
+
}).catch(() => {
|
|
15715
|
+
});
|
|
15716
|
+
return vector;
|
|
15717
|
+
}).finally(() => {
|
|
15718
|
+
entries.delete(key);
|
|
15719
|
+
if (entries.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
|
|
15720
|
+
});
|
|
15721
|
+
pending.set(key, request);
|
|
15722
|
+
});
|
|
15723
|
+
}
|
|
15724
|
+
return Promise.all(
|
|
15725
|
+
keys.map((key) => {
|
|
15726
|
+
const cached = prepared?.get(key);
|
|
15727
|
+
if (cached) return cached;
|
|
15728
|
+
const request = pending.get(key);
|
|
15729
|
+
if (!prepared) return request;
|
|
15730
|
+
const retained = request.catch((error) => {
|
|
15731
|
+
prepared.delete(key);
|
|
15732
|
+
throw error;
|
|
15733
|
+
});
|
|
15734
|
+
prepared.set(key, retained);
|
|
15735
|
+
return retained;
|
|
15736
|
+
})
|
|
15737
|
+
);
|
|
15738
|
+
}
|
|
15739
|
+
|
|
15638
15740
|
// src/lib/memoryVault/vectorVersion.ts
|
|
15639
15741
|
var vectorRowVersion = /* @__PURE__ */ new WeakMap();
|
|
15640
15742
|
function contentFingerprint(content) {
|
|
@@ -16197,11 +16299,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
16197
16299
|
return combined.slice(0, limit);
|
|
16198
16300
|
}
|
|
16199
16301
|
async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options) {
|
|
16200
|
-
const memories = await
|
|
16302
|
+
const memories = await loadVaultCorpus(vaultCtx, options);
|
|
16201
16303
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
16202
16304
|
const uncachedTexts = [];
|
|
16203
16305
|
const uncachedKeys = [];
|
|
16204
|
-
const
|
|
16306
|
+
const uncachedRows = [];
|
|
16205
16307
|
const uncachedVersions = [];
|
|
16206
16308
|
for (const m of memories) {
|
|
16207
16309
|
const content = m.content;
|
|
@@ -16220,12 +16322,12 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
16220
16322
|
}
|
|
16221
16323
|
uncachedTexts.push(m.content);
|
|
16222
16324
|
uncachedKeys.push(m.uniqueId);
|
|
16223
|
-
|
|
16325
|
+
uncachedRows.push(m);
|
|
16224
16326
|
uncachedVersions.push(m.updatedAt);
|
|
16225
16327
|
}
|
|
16226
16328
|
}
|
|
16227
16329
|
if (uncachedTexts.length > 0) {
|
|
16228
|
-
const embeddings = await
|
|
16330
|
+
const embeddings = await embedVaultRows(vaultCtx, embeddingOptions, uncachedRows);
|
|
16229
16331
|
for (let i = 0; i < uncachedKeys.length; i++) {
|
|
16230
16332
|
cacheRowVector(
|
|
16231
16333
|
cache,
|
|
@@ -16234,13 +16336,6 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
16234
16336
|
uncachedVersions[i],
|
|
16235
16337
|
uncachedTexts[i]
|
|
16236
16338
|
);
|
|
16237
|
-
updateVaultMemoryEmbeddingOp(
|
|
16238
|
-
vaultCtx,
|
|
16239
|
-
uncachedIds[i],
|
|
16240
|
-
JSON.stringify(embeddings[i]),
|
|
16241
|
-
currentModel
|
|
16242
|
-
).catch(() => {
|
|
16243
|
-
});
|
|
16244
16339
|
}
|
|
16245
16340
|
}
|
|
16246
16341
|
}
|
|
@@ -16382,10 +16477,7 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
16382
16477
|
let laneVecs;
|
|
16383
16478
|
if (opts.embedStats) opts.embedStats.rowsEmbedded += laneRows.length;
|
|
16384
16479
|
try {
|
|
16385
|
-
laneVecs = await
|
|
16386
|
-
laneRows.map((m) => m.content),
|
|
16387
|
-
embeddingOptions
|
|
16388
|
-
);
|
|
16480
|
+
laneVecs = await embedVaultRows(vaultCtx, embeddingOptions, laneRows);
|
|
16389
16481
|
} catch (err) {
|
|
16390
16482
|
laneEmbedFailed = true;
|
|
16391
16483
|
getLogger().warn(
|
|
@@ -16399,13 +16491,6 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
16399
16491
|
cacheRowVector(cache, m.uniqueId, vec, m.updatedAt, m.content);
|
|
16400
16492
|
resolvedThisCall.add(m.uniqueId);
|
|
16401
16493
|
vectored.push({ uniqueId: m.uniqueId, embedding: vec, updatedAt: m.updatedAt });
|
|
16402
|
-
updateVaultMemoryEmbeddingOp(
|
|
16403
|
-
vaultCtx,
|
|
16404
|
-
m.uniqueId,
|
|
16405
|
-
JSON.stringify(vecs[i]),
|
|
16406
|
-
currentModel
|
|
16407
|
-
).catch(() => {
|
|
16408
|
-
});
|
|
16409
16494
|
});
|
|
16410
16495
|
}
|
|
16411
16496
|
}
|
|
@@ -16597,9 +16682,10 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
16597
16682
|
};
|
|
16598
16683
|
}
|
|
16599
16684
|
} else {
|
|
16600
|
-
const loaded = await
|
|
16685
|
+
const loaded = await loadVaultCorpus(
|
|
16601
16686
|
vaultCtx,
|
|
16602
|
-
Object.keys(queryOpts).length > 0 ? queryOpts : void 0
|
|
16687
|
+
Object.keys(queryOpts).length > 0 ? queryOpts : void 0,
|
|
16688
|
+
searchOptions?.vaultPreparation
|
|
16603
16689
|
);
|
|
16604
16690
|
vaultSize = loaded.length;
|
|
16605
16691
|
rowsDecrypted = loaded.length;
|
|
@@ -16672,7 +16758,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
16672
16758
|
let newEmbeddings;
|
|
16673
16759
|
embedStats.rowsEmbedded += uncachedTexts.length;
|
|
16674
16760
|
try {
|
|
16675
|
-
newEmbeddings = await
|
|
16761
|
+
newEmbeddings = await embedVaultRows(
|
|
16762
|
+
vaultCtx,
|
|
16763
|
+
embeddingOptions,
|
|
16764
|
+
uncachedIndices.map((index) => memories[index]),
|
|
16765
|
+
searchOptions?.vaultPreparation
|
|
16766
|
+
);
|
|
16676
16767
|
} catch (err) {
|
|
16677
16768
|
embeddingFailure = true;
|
|
16678
16769
|
getLogger().warn(
|
|
@@ -16688,13 +16779,6 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
16688
16779
|
memories[uncachedIndices[j]].updatedAt,
|
|
16689
16780
|
memories[uncachedIndices[j]].content
|
|
16690
16781
|
);
|
|
16691
|
-
updateVaultMemoryEmbeddingOp(
|
|
16692
|
-
vaultCtx,
|
|
16693
|
-
memories[uncachedIndices[j]].uniqueId,
|
|
16694
|
-
JSON.stringify(newEmbeddings[j]),
|
|
16695
|
-
currentModel
|
|
16696
|
-
).catch(() => {
|
|
16697
|
-
});
|
|
16698
16782
|
}
|
|
16699
16783
|
}
|
|
16700
16784
|
}
|
|
@@ -19235,6 +19319,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
19235
19319
|
},
|
|
19236
19320
|
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
19237
19321
|
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
19322
|
+
...options.vaultPreparation && { vaultPreparation: options.vaultPreparation },
|
|
19238
19323
|
...subQueries && { subQueries },
|
|
19239
19324
|
...options.scopes && { scopes: options.scopes },
|
|
19240
19325
|
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
@@ -22825,13 +22910,20 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
22825
22910
|
}
|
|
22826
22911
|
}
|
|
22827
22912
|
}
|
|
22913
|
+
const vaultPreparation = createVaultPreparation();
|
|
22828
22914
|
const settled = await Promise.allSettled(
|
|
22829
22915
|
facets.map(async (facet) => {
|
|
22830
22916
|
const prior = previous?.sections.find((s) => s.key === facet.key);
|
|
22831
22917
|
if (prior && !staleKeys.has(facet.key)) {
|
|
22832
22918
|
return prior;
|
|
22833
22919
|
}
|
|
22834
|
-
return synthesizeFacet(
|
|
22920
|
+
return synthesizeFacet(
|
|
22921
|
+
facet,
|
|
22922
|
+
recallCtx,
|
|
22923
|
+
options,
|
|
22924
|
+
fallbackPriors.get(facet.key),
|
|
22925
|
+
vaultPreparation
|
|
22926
|
+
);
|
|
22835
22927
|
})
|
|
22836
22928
|
);
|
|
22837
22929
|
const sections = settled.map((r, i) => {
|
|
@@ -22985,7 +23077,7 @@ async function attributeFacts(ctx, candidates, facets) {
|
|
|
22985
23077
|
}
|
|
22986
23078
|
return keys;
|
|
22987
23079
|
}
|
|
22988
|
-
async function synthesizeFacet(facet, ctx, options, prior) {
|
|
23080
|
+
async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
22989
23081
|
const scopes = options.scopes ?? DEFAULT_SCOPES;
|
|
22990
23082
|
const limit = options.limit ?? DEFAULT_FACET_RECALL_LIMIT;
|
|
22991
23083
|
const factTypeWeights = { ...DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, ...options.factTypeWeights };
|
|
@@ -23002,6 +23094,7 @@ async function synthesizeFacet(facet, ctx, options, prior) {
|
|
|
23002
23094
|
};
|
|
23003
23095
|
}
|
|
23004
23096
|
const recalled = await recall(facet.query, ctx, {
|
|
23097
|
+
vaultPreparation,
|
|
23005
23098
|
scopes,
|
|
23006
23099
|
limit: hasReviewGate ? RECALL_MAX_LIMIT : limit,
|
|
23007
23100
|
types: ["fact"],
|