@anuma/sdk 9.1.4 → 9.1.6
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-XW3LYSDA.mjs → chunk-WRZTH4OS.mjs} +38 -13
- package/dist/expo/{consolidate-4CQJYKRK.mjs → consolidate-HKL5EGZT.mjs} +1 -1
- package/dist/expo/index.cjs +201 -67
- package/dist/expo/index.d.mts +18 -5
- package/dist/expo/index.d.ts +18 -5
- package/dist/expo/index.mjs +164 -55
- package/dist/memory/context.d.mts +123 -0
- package/dist/memory/context.d.ts +123 -0
- package/dist/react/{chunk-7QX4J7KV.mjs → chunk-RSA3S6OA.mjs} +38 -13
- package/dist/react/{consolidate-WLDYJF6J.mjs → consolidate-WFTPBHDV.mjs} +1 -1
- package/dist/react/index.cjs +212 -77
- package/dist/react/index.d.mts +18 -5
- package/dist/react/index.d.ts +18 -5
- package/dist/react/index.mjs +180 -70
- package/dist/server/{chunk-AU3Z7NBC.mjs → chunk-QEROZ4VH.mjs} +38 -13
- package/dist/server/{consolidate-B6OSCZU4.mjs → consolidate-PYED62LW.mjs} +1 -1
- package/dist/server/index.cjs +198 -64
- package/dist/server/index.d.mts +18 -5
- package/dist/server/index.d.ts +18 -5
- package/dist/server/index.mjs +161 -52
- package/package.json +1 -1
package/dist/server/index.d.mts
CHANGED
|
@@ -3365,6 +3365,13 @@ interface RecencyOptions {
|
|
|
3365
3365
|
noDateMultiplier?: number;
|
|
3366
3366
|
}
|
|
3367
3367
|
|
|
3368
|
+
type VaultCorpusCache = WeakMap<VaultMemoryOperationsContext, Map<string, Promise<StoredVaultMemory[]>>>;
|
|
3369
|
+
type RowRequests = Map<EmbeddingOptions["maskInput"], Map<string, Promise<number[]>>>;
|
|
3370
|
+
interface VaultPreparation {
|
|
3371
|
+
corpora: VaultCorpusCache;
|
|
3372
|
+
rows: WeakMap<VaultMemoryOperationsContext, RowRequests>;
|
|
3373
|
+
}
|
|
3374
|
+
|
|
3368
3375
|
declare const DEFAULT_VAULT_CACHE_SIZE = 5000;
|
|
3369
3376
|
/**
|
|
3370
3377
|
* Create a VaultEmbeddingCache backed by an LRU with a default cap of
|
|
@@ -3382,6 +3389,7 @@ type VaultEmbeddingCache = Map<string, Float32Array>;
|
|
|
3382
3389
|
* Options for the vault search tool.
|
|
3383
3390
|
*/
|
|
3384
3391
|
interface MemoryVaultSearchOptions {
|
|
3392
|
+
/** @internal */ vaultPreparation?: VaultPreparation;
|
|
3385
3393
|
onCandidateCount?: (count: number) => void;
|
|
3386
3394
|
/** Maximum number of results to return (default: 5) */
|
|
3387
3395
|
limit?: number;
|
|
@@ -4059,6 +4067,7 @@ interface RankedMemory {
|
|
|
4059
4067
|
updatedAt: Date;
|
|
4060
4068
|
}
|
|
4061
4069
|
interface RecallOptions {
|
|
4070
|
+
/** @internal */ vaultPreparation?: VaultPreparation;
|
|
4062
4071
|
/** Embedding cache shared with the rest of the turn, so the query is embedded once across lanes and the send. */
|
|
4063
4072
|
embeddingCache?: Map<string, Float32Array>;
|
|
4064
4073
|
/** Which kinds to search. Default: ['fact']. */
|
|
@@ -5278,7 +5287,8 @@ interface CreateVaultMemoryOptions {
|
|
|
5278
5287
|
geohash?: string;
|
|
5279
5288
|
}
|
|
5280
5289
|
interface UpdateVaultMemoryOptions {
|
|
5281
|
-
content
|
|
5290
|
+
content?: string;
|
|
5291
|
+
expectedContent?: string;
|
|
5282
5292
|
/** When true, the write is skipped (returns null) if the row carries a profile kind. */
|
|
5283
5293
|
freeFormOnly?: boolean;
|
|
5284
5294
|
/**
|
|
@@ -5840,9 +5850,10 @@ declare function ttlForType(factType: string | null, policy?: Partial<DecayPolic
|
|
|
5840
5850
|
* null `eventTimeEnd` is still ongoing, so this rule does not fire for it.
|
|
5841
5851
|
* 4. Age fallback — `now - updatedAt > TTL(factType)` → archive. Durable types
|
|
5842
5852
|
* have Infinity TTL, so this never fires for them; null/unknown use medium.
|
|
5843
|
-
* EXCEPTION: a `plan
|
|
5844
|
-
* (`eventTimeEnd >= now
|
|
5845
|
-
*
|
|
5853
|
+
* EXCEPTION: a `plan` / `ongoing_context` with an upcoming event or an event
|
|
5854
|
+
* within the grace period (`eventTimeEnd >= now - pastEventGraceMs`) stays
|
|
5855
|
+
* active, even after its activity TTL expires. Rule 3 archives it after the
|
|
5856
|
+
* grace period ends.
|
|
5846
5857
|
* 5. Otherwise → keep.
|
|
5847
5858
|
*
|
|
5848
5859
|
* @param m Plaintext decay inputs for one row.
|
|
@@ -6173,7 +6184,9 @@ type MemoryCreate = Pick<CreateVaultMemoryOptions, "content" | "scope" | "factTy
|
|
|
6173
6184
|
* `embedding` (with `embeddingModel`) only when you already have the new one.
|
|
6174
6185
|
* @public
|
|
6175
6186
|
*/
|
|
6176
|
-
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "
|
|
6187
|
+
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "scope" | "factType" | "eventTime" | "embedding" | "embeddingModel" | "kind" | "kindValue" | "level"> & {
|
|
6188
|
+
content: string;
|
|
6189
|
+
};
|
|
6177
6190
|
/**
|
|
6178
6191
|
* Fact-only recall. Conversation chunks are message storage, not memory, so
|
|
6179
6192
|
* the chunk-lane knobs are not part of this surface; nor is `folderId` (see
|
package/dist/server/index.d.ts
CHANGED
|
@@ -3365,6 +3365,13 @@ interface RecencyOptions {
|
|
|
3365
3365
|
noDateMultiplier?: number;
|
|
3366
3366
|
}
|
|
3367
3367
|
|
|
3368
|
+
type VaultCorpusCache = WeakMap<VaultMemoryOperationsContext, Map<string, Promise<StoredVaultMemory[]>>>;
|
|
3369
|
+
type RowRequests = Map<EmbeddingOptions["maskInput"], Map<string, Promise<number[]>>>;
|
|
3370
|
+
interface VaultPreparation {
|
|
3371
|
+
corpora: VaultCorpusCache;
|
|
3372
|
+
rows: WeakMap<VaultMemoryOperationsContext, RowRequests>;
|
|
3373
|
+
}
|
|
3374
|
+
|
|
3368
3375
|
declare const DEFAULT_VAULT_CACHE_SIZE = 5000;
|
|
3369
3376
|
/**
|
|
3370
3377
|
* Create a VaultEmbeddingCache backed by an LRU with a default cap of
|
|
@@ -3382,6 +3389,7 @@ type VaultEmbeddingCache = Map<string, Float32Array>;
|
|
|
3382
3389
|
* Options for the vault search tool.
|
|
3383
3390
|
*/
|
|
3384
3391
|
interface MemoryVaultSearchOptions {
|
|
3392
|
+
/** @internal */ vaultPreparation?: VaultPreparation;
|
|
3385
3393
|
onCandidateCount?: (count: number) => void;
|
|
3386
3394
|
/** Maximum number of results to return (default: 5) */
|
|
3387
3395
|
limit?: number;
|
|
@@ -4059,6 +4067,7 @@ interface RankedMemory {
|
|
|
4059
4067
|
updatedAt: Date;
|
|
4060
4068
|
}
|
|
4061
4069
|
interface RecallOptions {
|
|
4070
|
+
/** @internal */ vaultPreparation?: VaultPreparation;
|
|
4062
4071
|
/** Embedding cache shared with the rest of the turn, so the query is embedded once across lanes and the send. */
|
|
4063
4072
|
embeddingCache?: Map<string, Float32Array>;
|
|
4064
4073
|
/** Which kinds to search. Default: ['fact']. */
|
|
@@ -5278,7 +5287,8 @@ interface CreateVaultMemoryOptions {
|
|
|
5278
5287
|
geohash?: string;
|
|
5279
5288
|
}
|
|
5280
5289
|
interface UpdateVaultMemoryOptions {
|
|
5281
|
-
content
|
|
5290
|
+
content?: string;
|
|
5291
|
+
expectedContent?: string;
|
|
5282
5292
|
/** When true, the write is skipped (returns null) if the row carries a profile kind. */
|
|
5283
5293
|
freeFormOnly?: boolean;
|
|
5284
5294
|
/**
|
|
@@ -5840,9 +5850,10 @@ declare function ttlForType(factType: string | null, policy?: Partial<DecayPolic
|
|
|
5840
5850
|
* null `eventTimeEnd` is still ongoing, so this rule does not fire for it.
|
|
5841
5851
|
* 4. Age fallback — `now - updatedAt > TTL(factType)` → archive. Durable types
|
|
5842
5852
|
* have Infinity TTL, so this never fires for them; null/unknown use medium.
|
|
5843
|
-
* EXCEPTION: a `plan
|
|
5844
|
-
* (`eventTimeEnd >= now
|
|
5845
|
-
*
|
|
5853
|
+
* EXCEPTION: a `plan` / `ongoing_context` with an upcoming event or an event
|
|
5854
|
+
* within the grace period (`eventTimeEnd >= now - pastEventGraceMs`) stays
|
|
5855
|
+
* active, even after its activity TTL expires. Rule 3 archives it after the
|
|
5856
|
+
* grace period ends.
|
|
5846
5857
|
* 5. Otherwise → keep.
|
|
5847
5858
|
*
|
|
5848
5859
|
* @param m Plaintext decay inputs for one row.
|
|
@@ -6173,7 +6184,9 @@ type MemoryCreate = Pick<CreateVaultMemoryOptions, "content" | "scope" | "factTy
|
|
|
6173
6184
|
* `embedding` (with `embeddingModel`) only when you already have the new one.
|
|
6174
6185
|
* @public
|
|
6175
6186
|
*/
|
|
6176
|
-
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "
|
|
6187
|
+
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "scope" | "factType" | "eventTime" | "embedding" | "embeddingModel" | "kind" | "kindValue" | "level"> & {
|
|
6188
|
+
content: string;
|
|
6189
|
+
};
|
|
6177
6190
|
/**
|
|
6178
6191
|
* Fact-only recall. Conversation chunks are message storage, not memory, so
|
|
6179
6192
|
* the chunk-lane knobs are not part of this surface; nor is `folderId` (see
|
package/dist/server/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
taskTypeHeader,
|
|
14
14
|
validateEndpointOverride,
|
|
15
15
|
withInternalFlowMarker
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-QEROZ4VH.mjs";
|
|
17
17
|
import {
|
|
18
18
|
BASE_URL,
|
|
19
19
|
__commonJS,
|
|
@@ -15652,15 +15652,16 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
15652
15652
|
if (!parsed) {
|
|
15653
15653
|
return false;
|
|
15654
15654
|
}
|
|
15655
|
+
const startEpoch = sessionEpoch;
|
|
15655
15656
|
const cached = refreshCandidatesByAddress.get(walletAddress);
|
|
15656
15657
|
if (cached) {
|
|
15657
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached);
|
|
15658
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached, startEpoch);
|
|
15658
15659
|
}
|
|
15659
15660
|
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
15660
15661
|
if (!derivePromise) {
|
|
15661
15662
|
derivePromise = (async () => {
|
|
15662
15663
|
const candidates2 = await deriveRefreshCandidates(signMessage, embeddedWalletSigner);
|
|
15663
|
-
if (candidates2) {
|
|
15664
|
+
if (candidates2 && sessionEpoch === startEpoch) {
|
|
15664
15665
|
refreshCandidatesByAddress.set(walletAddress, candidates2);
|
|
15665
15666
|
}
|
|
15666
15667
|
return candidates2;
|
|
@@ -15672,10 +15673,10 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
15672
15673
|
pendingCandidateDerives.set(walletAddress, derivePromise);
|
|
15673
15674
|
}
|
|
15674
15675
|
const candidates = await derivePromise;
|
|
15675
|
-
if (!candidates) {
|
|
15676
|
+
if (!candidates || sessionEpoch !== startEpoch) {
|
|
15676
15677
|
return false;
|
|
15677
15678
|
}
|
|
15678
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates);
|
|
15679
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch);
|
|
15679
15680
|
}
|
|
15680
15681
|
function parsePrefixedCiphertext(probeCiphertext) {
|
|
15681
15682
|
const version = probeCiphertext.startsWith("enc:v3:") ? "v3" : probeCiphertext.startsWith("enc:v2:") ? "v2" : null;
|
|
@@ -15718,7 +15719,7 @@ async function deriveRefreshCandidates(signMessage, embeddedWalletSigner) {
|
|
|
15718
15719
|
}
|
|
15719
15720
|
return { legacy: legacyKey, current: currentKey };
|
|
15720
15721
|
}
|
|
15721
|
-
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates) {
|
|
15722
|
+
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch) {
|
|
15722
15723
|
const candidateHex = parsed.version === "v2" ? candidates.legacy : candidates.current;
|
|
15723
15724
|
const keyBytes = hexToBytes(candidateHex);
|
|
15724
15725
|
const candidateCryptoKey = await crypto.subtle.importKey(
|
|
@@ -15736,6 +15737,9 @@ async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidat
|
|
|
15736
15737
|
);
|
|
15737
15738
|
return false;
|
|
15738
15739
|
}
|
|
15740
|
+
if (sessionEpoch !== startEpoch) {
|
|
15741
|
+
return false;
|
|
15742
|
+
}
|
|
15739
15743
|
setStoredKey(walletAddress, { legacy: candidates.legacy, current: candidates.current });
|
|
15740
15744
|
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
15741
15745
|
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
@@ -27359,6 +27363,16 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
27359
27363
|
const probe = await ctx.vaultMemoryCollection.find(id);
|
|
27360
27364
|
if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
|
|
27361
27365
|
if (opts.freeFormOnly && isKinded(probe)) return null;
|
|
27366
|
+
const readStoredContent = probe._getRaw("content");
|
|
27367
|
+
if (opts.expectedContent !== void 0) {
|
|
27368
|
+
const current = await vaultMemoryToStored(
|
|
27369
|
+
probe,
|
|
27370
|
+
ctx.walletAddress,
|
|
27371
|
+
ctx.signMessage,
|
|
27372
|
+
ctx.embeddedWalletSigner
|
|
27373
|
+
);
|
|
27374
|
+
if (current.content !== opts.expectedContent) return null;
|
|
27375
|
+
}
|
|
27362
27376
|
const levelAfter = (current) => {
|
|
27363
27377
|
if (opts.level !== void 0) return opts.level;
|
|
27364
27378
|
if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
|
|
@@ -27366,7 +27380,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
27366
27380
|
};
|
|
27367
27381
|
assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
|
|
27368
27382
|
const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
|
|
27369
|
-
const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
27383
|
+
const encryptedContent = opts.content !== void 0 && ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
27370
27384
|
opts.content,
|
|
27371
27385
|
ctx.walletAddress,
|
|
27372
27386
|
ctx.signMessage,
|
|
@@ -27374,13 +27388,13 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
27374
27388
|
) : opts.content;
|
|
27375
27389
|
let stale = false;
|
|
27376
27390
|
const record = probe;
|
|
27377
|
-
const originalUpdatedAt = record.updatedAt.getTime();
|
|
27378
27391
|
await ctx.database.write(async () => {
|
|
27379
27392
|
await assertCanWrite2(ctx);
|
|
27380
|
-
if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record) || opts.freeFormOnly && isKinded(record)) {
|
|
27393
|
+
if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record) || opts.freeFormOnly && isKinded(record) || opts.expectedContent !== void 0 && record._getRaw("content") !== readStoredContent) {
|
|
27381
27394
|
stale = true;
|
|
27382
27395
|
return;
|
|
27383
27396
|
}
|
|
27397
|
+
const originalUpdatedAt = record.updatedAt.getTime();
|
|
27384
27398
|
const nextKind = opts.kind !== void 0 ? opts.kind : record.kind;
|
|
27385
27399
|
const nextLevel = levelAfter(record);
|
|
27386
27400
|
assertValidKindLevel(nextKind, nextLevel);
|
|
@@ -27396,7 +27410,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
27396
27410
|
replayedObservation = opts.observationSourceIds.every((id2) => observedSources.includes(id2));
|
|
27397
27411
|
}
|
|
27398
27412
|
await record.update((r) => {
|
|
27399
|
-
r._setRaw("content", encryptedContent);
|
|
27413
|
+
if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
|
|
27400
27414
|
if (opts.level !== void 0) {
|
|
27401
27415
|
r._setRaw("level", nextLevel);
|
|
27402
27416
|
r._setRaw("scope", scopeForLevel(nextLevel));
|
|
@@ -28163,7 +28177,7 @@ function classifyDecay(m, now, policy) {
|
|
|
28163
28177
|
if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
|
|
28164
28178
|
if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
|
|
28165
28179
|
if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
|
|
28166
|
-
|
|
28180
|
+
return "keep";
|
|
28167
28181
|
}
|
|
28168
28182
|
if (now - lastActivityAt(m) > ttlForType(m.factType, resolved)) return "archive";
|
|
28169
28183
|
return "keep";
|
|
@@ -29821,6 +29835,104 @@ function validate(parsed, originalQuery) {
|
|
|
29821
29835
|
return { mode, subQueries };
|
|
29822
29836
|
}
|
|
29823
29837
|
|
|
29838
|
+
// src/lib/memoryVault/vaultPreparation.ts
|
|
29839
|
+
function createVaultPreparation() {
|
|
29840
|
+
return { corpora: /* @__PURE__ */ new WeakMap(), rows: /* @__PURE__ */ new WeakMap() };
|
|
29841
|
+
}
|
|
29842
|
+
var pendingRows = /* @__PURE__ */ new WeakMap();
|
|
29843
|
+
function loadVaultCorpus(ctx, options, preparation) {
|
|
29844
|
+
if (!preparation) return getAllVaultMemoriesOp(ctx, options);
|
|
29845
|
+
const corpusCache = preparation.corpora;
|
|
29846
|
+
let pending = corpusCache.get(ctx);
|
|
29847
|
+
if (!pending) {
|
|
29848
|
+
pending = /* @__PURE__ */ new Map();
|
|
29849
|
+
corpusCache.set(ctx, pending);
|
|
29850
|
+
}
|
|
29851
|
+
const key = JSON.stringify(options ?? {});
|
|
29852
|
+
let request = pending.get(key);
|
|
29853
|
+
if (!request) {
|
|
29854
|
+
const entries = pending;
|
|
29855
|
+
request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
|
|
29856
|
+
entries.delete(key);
|
|
29857
|
+
throw error;
|
|
29858
|
+
});
|
|
29859
|
+
pending.set(key, request);
|
|
29860
|
+
}
|
|
29861
|
+
return request;
|
|
29862
|
+
}
|
|
29863
|
+
function rowRequestsFor(registry, ctx, maskInput) {
|
|
29864
|
+
let byMask = registry.get(ctx);
|
|
29865
|
+
if (!byMask) {
|
|
29866
|
+
byMask = /* @__PURE__ */ new Map();
|
|
29867
|
+
registry.set(ctx, byMask);
|
|
29868
|
+
}
|
|
29869
|
+
let requests = byMask.get(maskInput);
|
|
29870
|
+
if (!requests) {
|
|
29871
|
+
requests = /* @__PURE__ */ new Map();
|
|
29872
|
+
byMask.set(maskInput, requests);
|
|
29873
|
+
}
|
|
29874
|
+
return requests;
|
|
29875
|
+
}
|
|
29876
|
+
function embedVaultRows(ctx, options, rows, preparation) {
|
|
29877
|
+
const pending = rowRequestsFor(pendingRows, ctx, options.maskInput);
|
|
29878
|
+
const prepared = preparation && rowRequestsFor(preparation.rows, ctx, options.maskInput);
|
|
29879
|
+
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
29880
|
+
const keys = rows.map(
|
|
29881
|
+
(row) => JSON.stringify([
|
|
29882
|
+
row.uniqueId,
|
|
29883
|
+
row.updatedAt?.getTime(),
|
|
29884
|
+
row.content,
|
|
29885
|
+
model,
|
|
29886
|
+
options.baseUrl,
|
|
29887
|
+
options.timeoutMs,
|
|
29888
|
+
options.tokenTimeoutMs,
|
|
29889
|
+
options.totalTimeoutMs
|
|
29890
|
+
])
|
|
29891
|
+
);
|
|
29892
|
+
const missing = /* @__PURE__ */ new Map();
|
|
29893
|
+
rows.forEach((row, index) => {
|
|
29894
|
+
if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing.set(keys[index], row);
|
|
29895
|
+
});
|
|
29896
|
+
if (missing.size > 0) {
|
|
29897
|
+
const entries = pending;
|
|
29898
|
+
const batch = Promise.resolve().then(
|
|
29899
|
+
() => generateEmbeddings(
|
|
29900
|
+
[...missing.values()].map((row) => row.content),
|
|
29901
|
+
options
|
|
29902
|
+
)
|
|
29903
|
+
);
|
|
29904
|
+
[...missing].forEach(([key, row], index) => {
|
|
29905
|
+
const request = batch.then((vectors) => {
|
|
29906
|
+
const vector = vectors[index];
|
|
29907
|
+
updateVaultMemoryEmbeddingOp(ctx, row.uniqueId, JSON.stringify(vector), model, {
|
|
29908
|
+
content: row.content,
|
|
29909
|
+
updatedAt: row.updatedAt?.getTime()
|
|
29910
|
+
}).catch(() => {
|
|
29911
|
+
});
|
|
29912
|
+
return vector;
|
|
29913
|
+
}).finally(() => {
|
|
29914
|
+
entries.delete(key);
|
|
29915
|
+
if (entries.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
|
|
29916
|
+
});
|
|
29917
|
+
pending.set(key, request);
|
|
29918
|
+
});
|
|
29919
|
+
}
|
|
29920
|
+
return Promise.all(
|
|
29921
|
+
keys.map((key) => {
|
|
29922
|
+
const cached = prepared?.get(key);
|
|
29923
|
+
if (cached) return cached;
|
|
29924
|
+
const request = pending.get(key);
|
|
29925
|
+
if (!prepared) return request;
|
|
29926
|
+
const retained = request.catch((error) => {
|
|
29927
|
+
prepared.delete(key);
|
|
29928
|
+
throw error;
|
|
29929
|
+
});
|
|
29930
|
+
prepared.set(key, retained);
|
|
29931
|
+
return retained;
|
|
29932
|
+
})
|
|
29933
|
+
);
|
|
29934
|
+
}
|
|
29935
|
+
|
|
29824
29936
|
// src/lib/memoryVault/vectorVersion.ts
|
|
29825
29937
|
var vectorRowVersion = /* @__PURE__ */ new WeakMap();
|
|
29826
29938
|
function contentFingerprint(content) {
|
|
@@ -30383,11 +30495,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
30383
30495
|
return combined.slice(0, limit);
|
|
30384
30496
|
}
|
|
30385
30497
|
async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options) {
|
|
30386
|
-
const memories = await
|
|
30498
|
+
const memories = await loadVaultCorpus(vaultCtx, options);
|
|
30387
30499
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
30388
30500
|
const uncachedTexts = [];
|
|
30389
30501
|
const uncachedKeys = [];
|
|
30390
|
-
const
|
|
30502
|
+
const uncachedRows = [];
|
|
30391
30503
|
const uncachedVersions = [];
|
|
30392
30504
|
for (const m of memories) {
|
|
30393
30505
|
const content = m.content;
|
|
@@ -30406,12 +30518,12 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
30406
30518
|
}
|
|
30407
30519
|
uncachedTexts.push(m.content);
|
|
30408
30520
|
uncachedKeys.push(m.uniqueId);
|
|
30409
|
-
|
|
30521
|
+
uncachedRows.push(m);
|
|
30410
30522
|
uncachedVersions.push(m.updatedAt);
|
|
30411
30523
|
}
|
|
30412
30524
|
}
|
|
30413
30525
|
if (uncachedTexts.length > 0) {
|
|
30414
|
-
const embeddings = await
|
|
30526
|
+
const embeddings = await embedVaultRows(vaultCtx, embeddingOptions, uncachedRows);
|
|
30415
30527
|
for (let i = 0; i < uncachedKeys.length; i++) {
|
|
30416
30528
|
cacheRowVector(
|
|
30417
30529
|
cache,
|
|
@@ -30420,13 +30532,6 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
30420
30532
|
uncachedVersions[i],
|
|
30421
30533
|
uncachedTexts[i]
|
|
30422
30534
|
);
|
|
30423
|
-
updateVaultMemoryEmbeddingOp(
|
|
30424
|
-
vaultCtx,
|
|
30425
|
-
uncachedIds[i],
|
|
30426
|
-
JSON.stringify(embeddings[i]),
|
|
30427
|
-
currentModel
|
|
30428
|
-
).catch(() => {
|
|
30429
|
-
});
|
|
30430
30535
|
}
|
|
30431
30536
|
}
|
|
30432
30537
|
}
|
|
@@ -30568,10 +30673,7 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
30568
30673
|
let laneVecs;
|
|
30569
30674
|
if (opts.embedStats) opts.embedStats.rowsEmbedded += laneRows.length;
|
|
30570
30675
|
try {
|
|
30571
|
-
laneVecs = await
|
|
30572
|
-
laneRows.map((m) => m.content),
|
|
30573
|
-
embeddingOptions
|
|
30574
|
-
);
|
|
30676
|
+
laneVecs = await embedVaultRows(vaultCtx, embeddingOptions, laneRows);
|
|
30575
30677
|
} catch (err) {
|
|
30576
30678
|
laneEmbedFailed = true;
|
|
30577
30679
|
getLogger().warn(
|
|
@@ -30585,13 +30687,6 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
30585
30687
|
cacheRowVector(cache, m.uniqueId, vec, m.updatedAt, m.content);
|
|
30586
30688
|
resolvedThisCall.add(m.uniqueId);
|
|
30587
30689
|
vectored.push({ uniqueId: m.uniqueId, embedding: vec, updatedAt: m.updatedAt });
|
|
30588
|
-
updateVaultMemoryEmbeddingOp(
|
|
30589
|
-
vaultCtx,
|
|
30590
|
-
m.uniqueId,
|
|
30591
|
-
JSON.stringify(vecs[i]),
|
|
30592
|
-
currentModel
|
|
30593
|
-
).catch(() => {
|
|
30594
|
-
});
|
|
30595
30690
|
});
|
|
30596
30691
|
}
|
|
30597
30692
|
}
|
|
@@ -30783,9 +30878,10 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
30783
30878
|
};
|
|
30784
30879
|
}
|
|
30785
30880
|
} else {
|
|
30786
|
-
const loaded = await
|
|
30881
|
+
const loaded = await loadVaultCorpus(
|
|
30787
30882
|
vaultCtx,
|
|
30788
|
-
Object.keys(queryOpts).length > 0 ? queryOpts : void 0
|
|
30883
|
+
Object.keys(queryOpts).length > 0 ? queryOpts : void 0,
|
|
30884
|
+
searchOptions?.vaultPreparation
|
|
30789
30885
|
);
|
|
30790
30886
|
vaultSize = loaded.length;
|
|
30791
30887
|
rowsDecrypted = loaded.length;
|
|
@@ -30858,7 +30954,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
30858
30954
|
let newEmbeddings;
|
|
30859
30955
|
embedStats.rowsEmbedded += uncachedTexts.length;
|
|
30860
30956
|
try {
|
|
30861
|
-
newEmbeddings = await
|
|
30957
|
+
newEmbeddings = await embedVaultRows(
|
|
30958
|
+
vaultCtx,
|
|
30959
|
+
embeddingOptions,
|
|
30960
|
+
uncachedIndices.map((index) => memories[index]),
|
|
30961
|
+
searchOptions?.vaultPreparation
|
|
30962
|
+
);
|
|
30862
30963
|
} catch (err) {
|
|
30863
30964
|
embeddingFailure = true;
|
|
30864
30965
|
getLogger().warn(
|
|
@@ -30874,13 +30975,6 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
30874
30975
|
memories[uncachedIndices[j]].updatedAt,
|
|
30875
30976
|
memories[uncachedIndices[j]].content
|
|
30876
30977
|
);
|
|
30877
|
-
updateVaultMemoryEmbeddingOp(
|
|
30878
|
-
vaultCtx,
|
|
30879
|
-
memories[uncachedIndices[j]].uniqueId,
|
|
30880
|
-
JSON.stringify(newEmbeddings[j]),
|
|
30881
|
-
currentModel
|
|
30882
|
-
).catch(() => {
|
|
30883
|
-
});
|
|
30884
30978
|
}
|
|
30885
30979
|
}
|
|
30886
30980
|
}
|
|
@@ -31284,7 +31378,6 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
31284
31378
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
31285
31379
|
const resurrect = resurrectFields(existing);
|
|
31286
31380
|
const updated = await ctx.persistence.update(targetId, {
|
|
31287
|
-
content: existing.content,
|
|
31288
31381
|
freeFormOnly: true,
|
|
31289
31382
|
proofCountIncrement: 1,
|
|
31290
31383
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -31488,7 +31581,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
31488
31581
|
content: m.content,
|
|
31489
31582
|
similarity: m.similarity
|
|
31490
31583
|
}));
|
|
31491
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
31584
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-PYED62LW.mjs");
|
|
31492
31585
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
31493
31586
|
if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
|
|
31494
31587
|
if (decision.action === "supersede" && decision.content) {
|
|
@@ -31523,7 +31616,6 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
31523
31616
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
31524
31617
|
const resurrect = resurrectFields(existing);
|
|
31525
31618
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
31526
|
-
content: existing.content,
|
|
31527
31619
|
freeFormOnly: true,
|
|
31528
31620
|
proofCountIncrement: 1,
|
|
31529
31621
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -31551,6 +31643,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
31551
31643
|
};
|
|
31552
31644
|
}
|
|
31553
31645
|
if (decision.action === "update" && decision.targetId && decision.content) {
|
|
31646
|
+
const expectedContent = candidates.find(
|
|
31647
|
+
(candidate) => candidate.id === decision.targetId
|
|
31648
|
+
)?.content;
|
|
31649
|
+
if (expectedContent === void 0) return null;
|
|
31554
31650
|
const existing = await ctx.persistence.get(decision.targetId);
|
|
31555
31651
|
if (!existing || existing.supersededBy) {
|
|
31556
31652
|
return abandonToRace(
|
|
@@ -31558,6 +31654,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
31558
31654
|
`update: target ${decision.targetId} ${existing ? "superseded" : "deleted"} before the write`
|
|
31559
31655
|
);
|
|
31560
31656
|
}
|
|
31657
|
+
if (existing.content !== expectedContent) {
|
|
31658
|
+
return abandonToRace(options, `update: target ${decision.targetId} edited before the write`);
|
|
31659
|
+
}
|
|
31561
31660
|
const mergedSourceIds = unionStrings(
|
|
31562
31661
|
existing.sourceChunkIds ?? [],
|
|
31563
31662
|
options.sourceChunkIds ?? []
|
|
@@ -31570,6 +31669,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
31570
31669
|
const resurrect = resurrectFields(existing);
|
|
31571
31670
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
31572
31671
|
content: decision.content,
|
|
31672
|
+
expectedContent,
|
|
31573
31673
|
freeFormOnly: true,
|
|
31574
31674
|
proofCountIncrement: 1,
|
|
31575
31675
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -31582,10 +31682,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
31582
31682
|
...factTypeUpdate !== void 0 && { factType: factTypeUpdate }
|
|
31583
31683
|
});
|
|
31584
31684
|
if (!updated) {
|
|
31585
|
-
await assertMergeTargetGoneOrThrow(ctx, decision.targetId);
|
|
31685
|
+
await assertMergeTargetGoneOrThrow(ctx, decision.targetId, expectedContent);
|
|
31586
31686
|
return abandonToRace(
|
|
31587
31687
|
options,
|
|
31588
|
-
`update: target ${decision.targetId}
|
|
31688
|
+
`update: target ${decision.targetId} changed mid-write (consolidated rewrite lost)`
|
|
31589
31689
|
);
|
|
31590
31690
|
}
|
|
31591
31691
|
cacheRowVector(
|
|
@@ -31612,9 +31712,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
31612
31712
|
);
|
|
31613
31713
|
return null;
|
|
31614
31714
|
}
|
|
31615
|
-
async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
31715
|
+
async function assertMergeTargetGoneOrThrow(ctx, targetId, expectedContent) {
|
|
31616
31716
|
const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
|
|
31617
|
-
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
|
|
31717
|
+
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0) && (expectedContent === void 0 || stillExists.content === expectedContent)) {
|
|
31618
31718
|
throw new RetainError(
|
|
31619
31719
|
"merge-not-persisted",
|
|
31620
31720
|
`retain: merge into memory ${targetId} failed to persist`
|
|
@@ -33447,6 +33547,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
33447
33547
|
},
|
|
33448
33548
|
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
33449
33549
|
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
33550
|
+
...options.vaultPreparation && { vaultPreparation: options.vaultPreparation },
|
|
33450
33551
|
...subQueries && { subQueries },
|
|
33451
33552
|
...options.scopes && { scopes: options.scopes },
|
|
33452
33553
|
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
@@ -34869,13 +34970,20 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
34869
34970
|
}
|
|
34870
34971
|
}
|
|
34871
34972
|
}
|
|
34973
|
+
const vaultPreparation = createVaultPreparation();
|
|
34872
34974
|
const settled = await Promise.allSettled(
|
|
34873
34975
|
facets.map(async (facet) => {
|
|
34874
34976
|
const prior = previous?.sections.find((s) => s.key === facet.key);
|
|
34875
34977
|
if (prior && !staleKeys.has(facet.key)) {
|
|
34876
34978
|
return prior;
|
|
34877
34979
|
}
|
|
34878
|
-
return synthesizeFacet(
|
|
34980
|
+
return synthesizeFacet(
|
|
34981
|
+
facet,
|
|
34982
|
+
recallCtx,
|
|
34983
|
+
options,
|
|
34984
|
+
fallbackPriors.get(facet.key),
|
|
34985
|
+
vaultPreparation
|
|
34986
|
+
);
|
|
34879
34987
|
})
|
|
34880
34988
|
);
|
|
34881
34989
|
const sections = settled.map((r, i) => {
|
|
@@ -35029,7 +35137,7 @@ async function attributeFacts(ctx, candidates, facets) {
|
|
|
35029
35137
|
}
|
|
35030
35138
|
return keys;
|
|
35031
35139
|
}
|
|
35032
|
-
async function synthesizeFacet(facet, ctx, options, prior) {
|
|
35140
|
+
async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
35033
35141
|
const scopes = options.scopes ?? DEFAULT_SCOPES;
|
|
35034
35142
|
const limit = options.limit ?? DEFAULT_FACET_RECALL_LIMIT;
|
|
35035
35143
|
const factTypeWeights = { ...DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, ...options.factTypeWeights };
|
|
@@ -35046,6 +35154,7 @@ async function synthesizeFacet(facet, ctx, options, prior) {
|
|
|
35046
35154
|
};
|
|
35047
35155
|
}
|
|
35048
35156
|
const recalled = await recall(facet.query, ctx, {
|
|
35157
|
+
vaultPreparation,
|
|
35049
35158
|
scopes,
|
|
35050
35159
|
limit: hasReviewGate ? RECALL_MAX_LIMIT : limit,
|
|
35051
35160
|
types: ["fact"],
|