@anuma/sdk 9.1.3 → 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 +221 -121
- package/dist/expo/index.d.mts +13 -0
- package/dist/expo/index.d.ts +13 -0
- package/dist/expo/index.mjs +221 -121
- package/dist/memory/context.d.mts +123 -0
- package/dist/memory/context.d.ts +123 -0
- package/dist/react/index.cjs +221 -121
- package/dist/react/index.d.mts +13 -0
- package/dist/react/index.d.ts +13 -0
- package/dist/react/index.mjs +221 -121
- 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 },
|
|
@@ -22927,6 +23012,8 @@ async function backfillTopics(ctx) {
|
|
|
22927
23012
|
if (topicless.length > 0) await backfillMemoryTopicsOp(ctx, topicless);
|
|
22928
23013
|
}
|
|
22929
23014
|
async function migrateMemoriesToRemote(options) {
|
|
23015
|
+
if (typeof options.withWriteBarrier !== "function" || typeof options.onActivated !== "function")
|
|
23016
|
+
throw new Error("A write barrier and a remote store handoff are required");
|
|
22930
23017
|
const { canonical, signal } = options;
|
|
22931
23018
|
const rings = [canonical, ...options.fallbacks ?? []];
|
|
22932
23019
|
const model = options.embeddingOptions?.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
@@ -22954,93 +23041,98 @@ async function migrateMemoriesToRemote(options) {
|
|
|
22954
23041
|
const placeholders = /* @__PURE__ */ new Set();
|
|
22955
23042
|
const truncated = /* @__PURE__ */ new Set();
|
|
22956
23043
|
let imported = 0;
|
|
22957
|
-
|
|
22958
|
-
|
|
22959
|
-
|
|
22960
|
-
|
|
22961
|
-
|
|
22962
|
-
|
|
22963
|
-
|
|
22964
|
-
|
|
22965
|
-
|
|
22966
|
-
|
|
22967
|
-
|
|
22968
|
-
|
|
22969
|
-
|
|
22970
|
-
);
|
|
22971
|
-
const needsVector = (raw, server) => !!options.embeddingOptions && !embedding(raw, model) && server.embedding_model !== model;
|
|
22972
|
-
for (const raw of candidates) {
|
|
22973
|
-
const server = remote.get(raw.id);
|
|
22974
|
-
if (server && server.updated_at === raw.updated_at && (!sameMetadata2(raw, server, model) || needsVector(raw, server)))
|
|
22975
|
-
pending.set(raw.id, raw.updated_at + 1);
|
|
22976
|
-
}
|
|
22977
|
-
}
|
|
22978
|
-
if (pending.size === 0) {
|
|
22979
|
-
const result = (state) => ({
|
|
22980
|
-
state,
|
|
22981
|
-
total: rows.length,
|
|
22982
|
-
imported,
|
|
22983
|
-
skipped: [...skipped].map(([memoryId, reason]) => ({ memoryId, reason })),
|
|
22984
|
-
reembedded: reembedded.size,
|
|
22985
|
-
unembedded: unembedded.size,
|
|
22986
|
-
placeholderTombstones: placeholders.size,
|
|
22987
|
-
truncatedSourceChunkIds: truncated.size
|
|
22988
|
-
});
|
|
22989
|
-
if (skipped.size > 0 && !options.allowSkipped) return result("migrating");
|
|
22990
|
-
if (!claimed) await importBatch(request, canonical.keyId, [], signal);
|
|
22991
|
-
if (!active)
|
|
22992
|
-
await request(
|
|
22993
|
-
"/account",
|
|
22994
|
-
{ method: "PUT", body: JSON.stringify({ state: "active" }) },
|
|
23044
|
+
const uploadPasses = async (finalizing = false) => {
|
|
23045
|
+
for (let pass = 0; ; pass++) {
|
|
23046
|
+
const rows = await getAllVaultMemoryRowsOp(options.vaultCtx);
|
|
23047
|
+
for (const raw of rows) if (invalid2(raw)) skipped.set(String(raw.id), "invalid");
|
|
23048
|
+
const candidates = rows.filter((raw) => !skipped.has(String(raw.id)));
|
|
23049
|
+
const missing = await missingIds(request, candidates.map(revision), signal);
|
|
23050
|
+
const pending = /* @__PURE__ */ new Map();
|
|
23051
|
+
for (const raw of candidates)
|
|
23052
|
+
if (missing.has(raw.id)) pending.set(raw.id, raw.updated_at);
|
|
23053
|
+
if (pending.size === 0 && !active) {
|
|
23054
|
+
const remote = await remoteMetadata(
|
|
23055
|
+
request,
|
|
23056
|
+
candidates.map((raw) => raw.id),
|
|
22995
23057
|
signal
|
|
22996
23058
|
);
|
|
22997
|
-
|
|
22998
|
-
|
|
22999
|
-
|
|
23000
|
-
|
|
23001
|
-
|
|
23002
|
-
|
|
23003
|
-
|
|
23004
|
-
)
|
|
23005
|
-
|
|
23006
|
-
|
|
23007
|
-
|
|
23008
|
-
|
|
23009
|
-
|
|
23010
|
-
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23014
|
-
|
|
23015
|
-
|
|
23016
|
-
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
|
|
23059
|
+
const needsVector = (raw, server) => !!options.embeddingOptions && !embedding(raw, model) && server.embedding_model !== model;
|
|
23060
|
+
for (const raw of candidates) {
|
|
23061
|
+
const server = remote.get(raw.id);
|
|
23062
|
+
if (server && server.updated_at === raw.updated_at && (!sameMetadata2(raw, server, model) || needsVector(raw, server)))
|
|
23063
|
+
pending.set(raw.id, raw.updated_at + 1);
|
|
23064
|
+
}
|
|
23065
|
+
}
|
|
23066
|
+
if (pending.size === 0) {
|
|
23067
|
+
const result = (state) => ({
|
|
23068
|
+
state,
|
|
23069
|
+
total: rows.length,
|
|
23070
|
+
imported,
|
|
23071
|
+
skipped: [...skipped].map(([memoryId, reason]) => ({ memoryId, reason })),
|
|
23072
|
+
reembedded: reembedded.size,
|
|
23073
|
+
unembedded: unembedded.size,
|
|
23074
|
+
placeholderTombstones: placeholders.size,
|
|
23075
|
+
truncatedSourceChunkIds: truncated.size
|
|
23076
|
+
});
|
|
23077
|
+
if (skipped.size > 0 && !options.allowSkipped) return result("migrating");
|
|
23078
|
+
if (!finalizing) return options.withWriteBarrier(() => uploadPasses(true));
|
|
23079
|
+
if (!claimed) await importBatch(request, canonical.keyId, [], signal);
|
|
23080
|
+
if (!active)
|
|
23081
|
+
await request(
|
|
23082
|
+
"/account",
|
|
23083
|
+
{ method: "PUT", body: JSON.stringify({ state: "active" }) },
|
|
23084
|
+
signal
|
|
23085
|
+
);
|
|
23086
|
+
await options.onActivated();
|
|
23087
|
+
return result("active");
|
|
23088
|
+
}
|
|
23089
|
+
if (pass >= MAX_UPLOAD_PASSES)
|
|
23090
|
+
throw new RemoteMemoryError(
|
|
23091
|
+
"Nearby still reports memories missing after importing them",
|
|
23092
|
+
409,
|
|
23093
|
+
"migration_incomplete"
|
|
23094
|
+
);
|
|
23095
|
+
const prepared = [];
|
|
23096
|
+
for (const raw of candidates) {
|
|
23097
|
+
const updatedAt = pending.get(raw.id);
|
|
23098
|
+
if (updatedAt === void 0) continue;
|
|
23099
|
+
try {
|
|
23100
|
+
prepared.push(await prepareRow(raw, canonical, rings, model, updatedAt));
|
|
23101
|
+
} catch (error) {
|
|
23102
|
+
if (!(error instanceof MemoryKeyError)) throw error;
|
|
23103
|
+
skipped.set(raw.id, "unreadable");
|
|
23104
|
+
}
|
|
23105
|
+
}
|
|
23106
|
+
const usable = new Set(prepared.filter((p) => p.row.embedding).map((p) => p.row.memory_id));
|
|
23107
|
+
if (options.embeddingOptions)
|
|
23108
|
+
await embedMissing(prepared, options.embeddingOptions, model, signal);
|
|
23109
|
+
const local = new Map(candidates.map((raw) => [raw.id, raw]));
|
|
23110
|
+
const upload = [];
|
|
23111
|
+
for (const { row, plaintext } of prepared) {
|
|
23112
|
+
const id2 = row.memory_id;
|
|
23113
|
+
if (!fitsNearby(row)) {
|
|
23114
|
+
skipped.set(id2, "invalid");
|
|
23115
|
+
continue;
|
|
23116
|
+
}
|
|
23117
|
+
upload.push(row);
|
|
23118
|
+
const track = (set, on) => on ? set.add(id2) : set.delete(id2);
|
|
23119
|
+
track(reembedded, !!row.embedding && !usable.has(id2));
|
|
23120
|
+
track(unembedded, !row.embedding);
|
|
23121
|
+
track(placeholders, plaintext === void 0);
|
|
23122
|
+
track(truncated, row.source_chunk_ids !== text13(local.get(id2).source_chunk_ids));
|
|
23026
23123
|
}
|
|
23027
|
-
|
|
23028
|
-
const track = (set, on) => on ? set.add(id2) : set.delete(id2);
|
|
23029
|
-
track(reembedded, !!row.embedding && !usable.has(id2));
|
|
23030
|
-
track(unembedded, !row.embedding);
|
|
23031
|
-
track(placeholders, plaintext === void 0);
|
|
23032
|
-
track(truncated, row.source_chunk_ids !== text13(local.get(id2).source_chunk_ids));
|
|
23033
|
-
}
|
|
23034
|
-
let sent = 0;
|
|
23035
|
-
options.onProgress?.({ imported: sent, toImport: upload.length });
|
|
23036
|
-
for (const batch of chunks(upload, IMPORT_BATCH)) {
|
|
23037
|
-
await importBatch(request, canonical.keyId, batch, signal);
|
|
23038
|
-
claimed = true;
|
|
23039
|
-
sent += batch.length;
|
|
23124
|
+
let sent = 0;
|
|
23040
23125
|
options.onProgress?.({ imported: sent, toImport: upload.length });
|
|
23126
|
+
for (const batch of chunks(upload, IMPORT_BATCH)) {
|
|
23127
|
+
await importBatch(request, canonical.keyId, batch, signal);
|
|
23128
|
+
claimed = true;
|
|
23129
|
+
sent += batch.length;
|
|
23130
|
+
options.onProgress?.({ imported: sent, toImport: upload.length });
|
|
23131
|
+
}
|
|
23132
|
+
imported += sent;
|
|
23041
23133
|
}
|
|
23042
|
-
|
|
23043
|
-
|
|
23134
|
+
};
|
|
23135
|
+
return uploadPasses();
|
|
23044
23136
|
}
|
|
23045
23137
|
|
|
23046
23138
|
// src/lib/memory/store/remoteStore.ts
|
|
@@ -24496,13 +24588,20 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
24496
24588
|
}
|
|
24497
24589
|
}
|
|
24498
24590
|
}
|
|
24591
|
+
const vaultPreparation = createVaultPreparation();
|
|
24499
24592
|
const settled = await Promise.allSettled(
|
|
24500
24593
|
facets.map(async (facet) => {
|
|
24501
24594
|
const prior = previous?.sections.find((s) => s.key === facet.key);
|
|
24502
24595
|
if (prior && !staleKeys.has(facet.key)) {
|
|
24503
24596
|
return prior;
|
|
24504
24597
|
}
|
|
24505
|
-
return synthesizeFacet(
|
|
24598
|
+
return synthesizeFacet(
|
|
24599
|
+
facet,
|
|
24600
|
+
recallCtx,
|
|
24601
|
+
options,
|
|
24602
|
+
fallbackPriors.get(facet.key),
|
|
24603
|
+
vaultPreparation
|
|
24604
|
+
);
|
|
24506
24605
|
})
|
|
24507
24606
|
);
|
|
24508
24607
|
const sections = settled.map((r, i) => {
|
|
@@ -24656,7 +24755,7 @@ async function attributeFacts(ctx, candidates, facets) {
|
|
|
24656
24755
|
}
|
|
24657
24756
|
return keys;
|
|
24658
24757
|
}
|
|
24659
|
-
async function synthesizeFacet(facet, ctx, options, prior) {
|
|
24758
|
+
async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
24660
24759
|
const scopes = options.scopes ?? DEFAULT_SCOPES;
|
|
24661
24760
|
const limit = options.limit ?? DEFAULT_FACET_RECALL_LIMIT;
|
|
24662
24761
|
const factTypeWeights = { ...DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, ...options.factTypeWeights };
|
|
@@ -24673,6 +24772,7 @@ async function synthesizeFacet(facet, ctx, options, prior) {
|
|
|
24673
24772
|
};
|
|
24674
24773
|
}
|
|
24675
24774
|
const recalled = await recall(facet.query, ctx, {
|
|
24775
|
+
vaultPreparation,
|
|
24676
24776
|
scopes,
|
|
24677
24777
|
limit: hasReviewGate ? RECALL_MAX_LIMIT : limit,
|
|
24678
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']. */
|
|
@@ -9931,6 +9940,10 @@ interface MemoryMigrationOptions extends Pick<RemoteMemoryPersistenceOptions, "b
|
|
|
9931
9940
|
name: string;
|
|
9932
9941
|
kind?: string;
|
|
9933
9942
|
}[];
|
|
9943
|
+
/** Drain all local memory writes, block new writes until the task returns, and retain the block if the remote handoff fails. */
|
|
9944
|
+
withWriteBarrier: (task: () => Promise<MemoryMigrationResult>) => Promise<MemoryMigrationResult>;
|
|
9945
|
+
/** Route all subsequent memory writes to the remote store before this callback returns. */
|
|
9946
|
+
onActivated: () => void | Promise<void>;
|
|
9934
9947
|
signal?: AbortSignal;
|
|
9935
9948
|
onProgress?: (progress: MemoryMigrationProgress) => void;
|
|
9936
9949
|
}
|
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']. */
|
|
@@ -9931,6 +9940,10 @@ interface MemoryMigrationOptions extends Pick<RemoteMemoryPersistenceOptions, "b
|
|
|
9931
9940
|
name: string;
|
|
9932
9941
|
kind?: string;
|
|
9933
9942
|
}[];
|
|
9943
|
+
/** Drain all local memory writes, block new writes until the task returns, and retain the block if the remote handoff fails. */
|
|
9944
|
+
withWriteBarrier: (task: () => Promise<MemoryMigrationResult>) => Promise<MemoryMigrationResult>;
|
|
9945
|
+
/** Route all subsequent memory writes to the remote store before this callback returns. */
|
|
9946
|
+
onActivated: () => void | Promise<void>;
|
|
9934
9947
|
signal?: AbortSignal;
|
|
9935
9948
|
onProgress?: (progress: MemoryMigrationProgress) => void;
|
|
9936
9949
|
}
|