@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/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']. */
|
|
@@ -5660,7 +5669,8 @@ interface CreateVaultMemoryOptions {
|
|
|
5660
5669
|
geohash?: string;
|
|
5661
5670
|
}
|
|
5662
5671
|
interface UpdateVaultMemoryOptions {
|
|
5663
|
-
content
|
|
5672
|
+
content?: string;
|
|
5673
|
+
expectedContent?: string;
|
|
5664
5674
|
/** When true, the write is skipped (returns null) if the row carries a profile kind. */
|
|
5665
5675
|
freeFormOnly?: boolean;
|
|
5666
5676
|
/**
|
|
@@ -6264,9 +6274,10 @@ declare function ttlForType(factType: string | null, policy?: Partial<DecayPolic
|
|
|
6264
6274
|
* null `eventTimeEnd` is still ongoing, so this rule does not fire for it.
|
|
6265
6275
|
* 4. Age fallback — `now - updatedAt > TTL(factType)` → archive. Durable types
|
|
6266
6276
|
* have Infinity TTL, so this never fires for them; null/unknown use medium.
|
|
6267
|
-
* EXCEPTION: a `plan
|
|
6268
|
-
* (`eventTimeEnd >= now
|
|
6269
|
-
*
|
|
6277
|
+
* EXCEPTION: a `plan` / `ongoing_context` with an upcoming event or an event
|
|
6278
|
+
* within the grace period (`eventTimeEnd >= now - pastEventGraceMs`) stays
|
|
6279
|
+
* active, even after its activity TTL expires. Rule 3 archives it after the
|
|
6280
|
+
* grace period ends.
|
|
6270
6281
|
* 5. Otherwise → keep.
|
|
6271
6282
|
*
|
|
6272
6283
|
* @param m Plaintext decay inputs for one row.
|
|
@@ -6597,7 +6608,9 @@ type MemoryCreate = Pick<CreateVaultMemoryOptions, "content" | "scope" | "factTy
|
|
|
6597
6608
|
* `embedding` (with `embeddingModel`) only when you already have the new one.
|
|
6598
6609
|
* @public
|
|
6599
6610
|
*/
|
|
6600
|
-
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "
|
|
6611
|
+
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "scope" | "factType" | "eventTime" | "embedding" | "embeddingModel" | "kind" | "kindValue" | "level"> & {
|
|
6612
|
+
content: string;
|
|
6613
|
+
};
|
|
6601
6614
|
/**
|
|
6602
6615
|
* Fact-only recall. Conversation chunks are message storage, not memory, so
|
|
6603
6616
|
* the chunk-lane knobs are not part of this surface; nor is `folderId` (see
|
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']. */
|
|
@@ -5660,7 +5669,8 @@ interface CreateVaultMemoryOptions {
|
|
|
5660
5669
|
geohash?: string;
|
|
5661
5670
|
}
|
|
5662
5671
|
interface UpdateVaultMemoryOptions {
|
|
5663
|
-
content
|
|
5672
|
+
content?: string;
|
|
5673
|
+
expectedContent?: string;
|
|
5664
5674
|
/** When true, the write is skipped (returns null) if the row carries a profile kind. */
|
|
5665
5675
|
freeFormOnly?: boolean;
|
|
5666
5676
|
/**
|
|
@@ -6264,9 +6274,10 @@ declare function ttlForType(factType: string | null, policy?: Partial<DecayPolic
|
|
|
6264
6274
|
* null `eventTimeEnd` is still ongoing, so this rule does not fire for it.
|
|
6265
6275
|
* 4. Age fallback — `now - updatedAt > TTL(factType)` → archive. Durable types
|
|
6266
6276
|
* have Infinity TTL, so this never fires for them; null/unknown use medium.
|
|
6267
|
-
* EXCEPTION: a `plan
|
|
6268
|
-
* (`eventTimeEnd >= now
|
|
6269
|
-
*
|
|
6277
|
+
* EXCEPTION: a `plan` / `ongoing_context` with an upcoming event or an event
|
|
6278
|
+
* within the grace period (`eventTimeEnd >= now - pastEventGraceMs`) stays
|
|
6279
|
+
* active, even after its activity TTL expires. Rule 3 archives it after the
|
|
6280
|
+
* grace period ends.
|
|
6270
6281
|
* 5. Otherwise → keep.
|
|
6271
6282
|
*
|
|
6272
6283
|
* @param m Plaintext decay inputs for one row.
|
|
@@ -6597,7 +6608,9 @@ type MemoryCreate = Pick<CreateVaultMemoryOptions, "content" | "scope" | "factTy
|
|
|
6597
6608
|
* `embedding` (with `embeddingModel`) only when you already have the new one.
|
|
6598
6609
|
* @public
|
|
6599
6610
|
*/
|
|
6600
|
-
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "
|
|
6611
|
+
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "scope" | "factType" | "eventTime" | "embedding" | "embeddingModel" | "kind" | "kindValue" | "level"> & {
|
|
6612
|
+
content: string;
|
|
6613
|
+
};
|
|
6601
6614
|
/**
|
|
6602
6615
|
* Fact-only recall. Conversation chunks are message storage, not memory, so
|
|
6603
6616
|
* the chunk-lane knobs are not part of this surface; nor is `folderId` (see
|
package/dist/expo/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
taskTypeHeader,
|
|
21
21
|
validateEndpointOverride,
|
|
22
22
|
withInternalFlowMarker
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-WRZTH4OS.mjs";
|
|
24
24
|
import {
|
|
25
25
|
BASE_URL,
|
|
26
26
|
MCP_R2_DOMAIN,
|
|
@@ -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`);
|
|
@@ -13341,6 +13345,16 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
13341
13345
|
const probe = await ctx.vaultMemoryCollection.find(id2);
|
|
13342
13346
|
if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
|
|
13343
13347
|
if (opts.freeFormOnly && isKinded(probe)) return null;
|
|
13348
|
+
const readStoredContent = probe._getRaw("content");
|
|
13349
|
+
if (opts.expectedContent !== void 0) {
|
|
13350
|
+
const current = await vaultMemoryToStored(
|
|
13351
|
+
probe,
|
|
13352
|
+
ctx.walletAddress,
|
|
13353
|
+
ctx.signMessage,
|
|
13354
|
+
ctx.embeddedWalletSigner
|
|
13355
|
+
);
|
|
13356
|
+
if (current.content !== opts.expectedContent) return null;
|
|
13357
|
+
}
|
|
13344
13358
|
const levelAfter = (current) => {
|
|
13345
13359
|
if (opts.level !== void 0) return opts.level;
|
|
13346
13360
|
if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
|
|
@@ -13348,7 +13362,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
13348
13362
|
};
|
|
13349
13363
|
assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
|
|
13350
13364
|
const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
|
|
13351
|
-
const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
13365
|
+
const encryptedContent = opts.content !== void 0 && ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
13352
13366
|
opts.content,
|
|
13353
13367
|
ctx.walletAddress,
|
|
13354
13368
|
ctx.signMessage,
|
|
@@ -13356,13 +13370,13 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
13356
13370
|
) : opts.content;
|
|
13357
13371
|
let stale = false;
|
|
13358
13372
|
const record2 = probe;
|
|
13359
|
-
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
13360
13373
|
await ctx.database.write(async () => {
|
|
13361
13374
|
await assertCanWrite2(ctx);
|
|
13362
|
-
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
|
|
13375
|
+
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2) || opts.expectedContent !== void 0 && record2._getRaw("content") !== readStoredContent) {
|
|
13363
13376
|
stale = true;
|
|
13364
13377
|
return;
|
|
13365
13378
|
}
|
|
13379
|
+
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
13366
13380
|
const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
|
|
13367
13381
|
const nextLevel = levelAfter(record2);
|
|
13368
13382
|
assertValidKindLevel(nextKind, nextLevel);
|
|
@@ -13378,7 +13392,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
13378
13392
|
replayedObservation = opts.observationSourceIds.every((id3) => observedSources.includes(id3));
|
|
13379
13393
|
}
|
|
13380
13394
|
await record2.update((r) => {
|
|
13381
|
-
r._setRaw("content", encryptedContent);
|
|
13395
|
+
if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
|
|
13382
13396
|
if (opts.level !== void 0) {
|
|
13383
13397
|
r._setRaw("level", nextLevel);
|
|
13384
13398
|
r._setRaw("scope", scopeForLevel(nextLevel));
|
|
@@ -14145,7 +14159,7 @@ function classifyDecay(m, now, policy) {
|
|
|
14145
14159
|
if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
|
|
14146
14160
|
if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
|
|
14147
14161
|
if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
|
|
14148
|
-
|
|
14162
|
+
return "keep";
|
|
14149
14163
|
}
|
|
14150
14164
|
if (now - lastActivityAt(m) > ttlForType(m.factType, resolved)) return "archive";
|
|
14151
14165
|
return "keep";
|
|
@@ -15635,6 +15649,104 @@ function validate(parsed, originalQuery) {
|
|
|
15635
15649
|
return { mode, subQueries };
|
|
15636
15650
|
}
|
|
15637
15651
|
|
|
15652
|
+
// src/lib/memoryVault/vaultPreparation.ts
|
|
15653
|
+
function createVaultPreparation() {
|
|
15654
|
+
return { corpora: /* @__PURE__ */ new WeakMap(), rows: /* @__PURE__ */ new WeakMap() };
|
|
15655
|
+
}
|
|
15656
|
+
var pendingRows = /* @__PURE__ */ new WeakMap();
|
|
15657
|
+
function loadVaultCorpus(ctx, options, preparation) {
|
|
15658
|
+
if (!preparation) return getAllVaultMemoriesOp(ctx, options);
|
|
15659
|
+
const corpusCache = preparation.corpora;
|
|
15660
|
+
let pending = corpusCache.get(ctx);
|
|
15661
|
+
if (!pending) {
|
|
15662
|
+
pending = /* @__PURE__ */ new Map();
|
|
15663
|
+
corpusCache.set(ctx, pending);
|
|
15664
|
+
}
|
|
15665
|
+
const key = JSON.stringify(options ?? {});
|
|
15666
|
+
let request = pending.get(key);
|
|
15667
|
+
if (!request) {
|
|
15668
|
+
const entries = pending;
|
|
15669
|
+
request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
|
|
15670
|
+
entries.delete(key);
|
|
15671
|
+
throw error;
|
|
15672
|
+
});
|
|
15673
|
+
pending.set(key, request);
|
|
15674
|
+
}
|
|
15675
|
+
return request;
|
|
15676
|
+
}
|
|
15677
|
+
function rowRequestsFor(registry2, ctx, maskInput) {
|
|
15678
|
+
let byMask = registry2.get(ctx);
|
|
15679
|
+
if (!byMask) {
|
|
15680
|
+
byMask = /* @__PURE__ */ new Map();
|
|
15681
|
+
registry2.set(ctx, byMask);
|
|
15682
|
+
}
|
|
15683
|
+
let requests = byMask.get(maskInput);
|
|
15684
|
+
if (!requests) {
|
|
15685
|
+
requests = /* @__PURE__ */ new Map();
|
|
15686
|
+
byMask.set(maskInput, requests);
|
|
15687
|
+
}
|
|
15688
|
+
return requests;
|
|
15689
|
+
}
|
|
15690
|
+
function embedVaultRows(ctx, options, rows, preparation) {
|
|
15691
|
+
const pending = rowRequestsFor(pendingRows, ctx, options.maskInput);
|
|
15692
|
+
const prepared = preparation && rowRequestsFor(preparation.rows, ctx, options.maskInput);
|
|
15693
|
+
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
15694
|
+
const keys = rows.map(
|
|
15695
|
+
(row) => JSON.stringify([
|
|
15696
|
+
row.uniqueId,
|
|
15697
|
+
row.updatedAt?.getTime(),
|
|
15698
|
+
row.content,
|
|
15699
|
+
model,
|
|
15700
|
+
options.baseUrl,
|
|
15701
|
+
options.timeoutMs,
|
|
15702
|
+
options.tokenTimeoutMs,
|
|
15703
|
+
options.totalTimeoutMs
|
|
15704
|
+
])
|
|
15705
|
+
);
|
|
15706
|
+
const missing = /* @__PURE__ */ new Map();
|
|
15707
|
+
rows.forEach((row, index) => {
|
|
15708
|
+
if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing.set(keys[index], row);
|
|
15709
|
+
});
|
|
15710
|
+
if (missing.size > 0) {
|
|
15711
|
+
const entries = pending;
|
|
15712
|
+
const batch = Promise.resolve().then(
|
|
15713
|
+
() => generateEmbeddings(
|
|
15714
|
+
[...missing.values()].map((row) => row.content),
|
|
15715
|
+
options
|
|
15716
|
+
)
|
|
15717
|
+
);
|
|
15718
|
+
[...missing].forEach(([key, row], index) => {
|
|
15719
|
+
const request = batch.then((vectors) => {
|
|
15720
|
+
const vector = vectors[index];
|
|
15721
|
+
updateVaultMemoryEmbeddingOp(ctx, row.uniqueId, JSON.stringify(vector), model, {
|
|
15722
|
+
content: row.content,
|
|
15723
|
+
updatedAt: row.updatedAt?.getTime()
|
|
15724
|
+
}).catch(() => {
|
|
15725
|
+
});
|
|
15726
|
+
return vector;
|
|
15727
|
+
}).finally(() => {
|
|
15728
|
+
entries.delete(key);
|
|
15729
|
+
if (entries.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
|
|
15730
|
+
});
|
|
15731
|
+
pending.set(key, request);
|
|
15732
|
+
});
|
|
15733
|
+
}
|
|
15734
|
+
return Promise.all(
|
|
15735
|
+
keys.map((key) => {
|
|
15736
|
+
const cached = prepared?.get(key);
|
|
15737
|
+
if (cached) return cached;
|
|
15738
|
+
const request = pending.get(key);
|
|
15739
|
+
if (!prepared) return request;
|
|
15740
|
+
const retained = request.catch((error) => {
|
|
15741
|
+
prepared.delete(key);
|
|
15742
|
+
throw error;
|
|
15743
|
+
});
|
|
15744
|
+
prepared.set(key, retained);
|
|
15745
|
+
return retained;
|
|
15746
|
+
})
|
|
15747
|
+
);
|
|
15748
|
+
}
|
|
15749
|
+
|
|
15638
15750
|
// src/lib/memoryVault/vectorVersion.ts
|
|
15639
15751
|
var vectorRowVersion = /* @__PURE__ */ new WeakMap();
|
|
15640
15752
|
function contentFingerprint(content) {
|
|
@@ -16197,11 +16309,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
16197
16309
|
return combined.slice(0, limit);
|
|
16198
16310
|
}
|
|
16199
16311
|
async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options) {
|
|
16200
|
-
const memories = await
|
|
16312
|
+
const memories = await loadVaultCorpus(vaultCtx, options);
|
|
16201
16313
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
16202
16314
|
const uncachedTexts = [];
|
|
16203
16315
|
const uncachedKeys = [];
|
|
16204
|
-
const
|
|
16316
|
+
const uncachedRows = [];
|
|
16205
16317
|
const uncachedVersions = [];
|
|
16206
16318
|
for (const m of memories) {
|
|
16207
16319
|
const content = m.content;
|
|
@@ -16220,12 +16332,12 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
16220
16332
|
}
|
|
16221
16333
|
uncachedTexts.push(m.content);
|
|
16222
16334
|
uncachedKeys.push(m.uniqueId);
|
|
16223
|
-
|
|
16335
|
+
uncachedRows.push(m);
|
|
16224
16336
|
uncachedVersions.push(m.updatedAt);
|
|
16225
16337
|
}
|
|
16226
16338
|
}
|
|
16227
16339
|
if (uncachedTexts.length > 0) {
|
|
16228
|
-
const embeddings = await
|
|
16340
|
+
const embeddings = await embedVaultRows(vaultCtx, embeddingOptions, uncachedRows);
|
|
16229
16341
|
for (let i = 0; i < uncachedKeys.length; i++) {
|
|
16230
16342
|
cacheRowVector(
|
|
16231
16343
|
cache,
|
|
@@ -16234,13 +16346,6 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
16234
16346
|
uncachedVersions[i],
|
|
16235
16347
|
uncachedTexts[i]
|
|
16236
16348
|
);
|
|
16237
|
-
updateVaultMemoryEmbeddingOp(
|
|
16238
|
-
vaultCtx,
|
|
16239
|
-
uncachedIds[i],
|
|
16240
|
-
JSON.stringify(embeddings[i]),
|
|
16241
|
-
currentModel
|
|
16242
|
-
).catch(() => {
|
|
16243
|
-
});
|
|
16244
16349
|
}
|
|
16245
16350
|
}
|
|
16246
16351
|
}
|
|
@@ -16382,10 +16487,7 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
16382
16487
|
let laneVecs;
|
|
16383
16488
|
if (opts.embedStats) opts.embedStats.rowsEmbedded += laneRows.length;
|
|
16384
16489
|
try {
|
|
16385
|
-
laneVecs = await
|
|
16386
|
-
laneRows.map((m) => m.content),
|
|
16387
|
-
embeddingOptions
|
|
16388
|
-
);
|
|
16490
|
+
laneVecs = await embedVaultRows(vaultCtx, embeddingOptions, laneRows);
|
|
16389
16491
|
} catch (err) {
|
|
16390
16492
|
laneEmbedFailed = true;
|
|
16391
16493
|
getLogger().warn(
|
|
@@ -16399,13 +16501,6 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
16399
16501
|
cacheRowVector(cache, m.uniqueId, vec, m.updatedAt, m.content);
|
|
16400
16502
|
resolvedThisCall.add(m.uniqueId);
|
|
16401
16503
|
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
16504
|
});
|
|
16410
16505
|
}
|
|
16411
16506
|
}
|
|
@@ -16597,9 +16692,10 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
16597
16692
|
};
|
|
16598
16693
|
}
|
|
16599
16694
|
} else {
|
|
16600
|
-
const loaded = await
|
|
16695
|
+
const loaded = await loadVaultCorpus(
|
|
16601
16696
|
vaultCtx,
|
|
16602
|
-
Object.keys(queryOpts).length > 0 ? queryOpts : void 0
|
|
16697
|
+
Object.keys(queryOpts).length > 0 ? queryOpts : void 0,
|
|
16698
|
+
searchOptions?.vaultPreparation
|
|
16603
16699
|
);
|
|
16604
16700
|
vaultSize = loaded.length;
|
|
16605
16701
|
rowsDecrypted = loaded.length;
|
|
@@ -16672,7 +16768,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
16672
16768
|
let newEmbeddings;
|
|
16673
16769
|
embedStats.rowsEmbedded += uncachedTexts.length;
|
|
16674
16770
|
try {
|
|
16675
|
-
newEmbeddings = await
|
|
16771
|
+
newEmbeddings = await embedVaultRows(
|
|
16772
|
+
vaultCtx,
|
|
16773
|
+
embeddingOptions,
|
|
16774
|
+
uncachedIndices.map((index) => memories[index]),
|
|
16775
|
+
searchOptions?.vaultPreparation
|
|
16776
|
+
);
|
|
16676
16777
|
} catch (err) {
|
|
16677
16778
|
embeddingFailure = true;
|
|
16678
16779
|
getLogger().warn(
|
|
@@ -16688,13 +16789,6 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
16688
16789
|
memories[uncachedIndices[j]].updatedAt,
|
|
16689
16790
|
memories[uncachedIndices[j]].content
|
|
16690
16791
|
);
|
|
16691
|
-
updateVaultMemoryEmbeddingOp(
|
|
16692
|
-
vaultCtx,
|
|
16693
|
-
memories[uncachedIndices[j]].uniqueId,
|
|
16694
|
-
JSON.stringify(newEmbeddings[j]),
|
|
16695
|
-
currentModel
|
|
16696
|
-
).catch(() => {
|
|
16697
|
-
});
|
|
16698
16792
|
}
|
|
16699
16793
|
}
|
|
16700
16794
|
}
|
|
@@ -17098,7 +17192,6 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
17098
17192
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
17099
17193
|
const resurrect = resurrectFields(existing);
|
|
17100
17194
|
const updated = await ctx.persistence.update(targetId, {
|
|
17101
|
-
content: existing.content,
|
|
17102
17195
|
freeFormOnly: true,
|
|
17103
17196
|
proofCountIncrement: 1,
|
|
17104
17197
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -17302,7 +17395,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17302
17395
|
content: m.content,
|
|
17303
17396
|
similarity: m.similarity
|
|
17304
17397
|
}));
|
|
17305
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
17398
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-HKL5EGZT.mjs");
|
|
17306
17399
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
17307
17400
|
if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
|
|
17308
17401
|
if (decision.action === "supersede" && decision.content) {
|
|
@@ -17337,7 +17430,6 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17337
17430
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
17338
17431
|
const resurrect = resurrectFields(existing);
|
|
17339
17432
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
17340
|
-
content: existing.content,
|
|
17341
17433
|
freeFormOnly: true,
|
|
17342
17434
|
proofCountIncrement: 1,
|
|
17343
17435
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -17365,6 +17457,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17365
17457
|
};
|
|
17366
17458
|
}
|
|
17367
17459
|
if (decision.action === "update" && decision.targetId && decision.content) {
|
|
17460
|
+
const expectedContent = candidates.find(
|
|
17461
|
+
(candidate) => candidate.id === decision.targetId
|
|
17462
|
+
)?.content;
|
|
17463
|
+
if (expectedContent === void 0) return null;
|
|
17368
17464
|
const existing = await ctx.persistence.get(decision.targetId);
|
|
17369
17465
|
if (!existing || existing.supersededBy) {
|
|
17370
17466
|
return abandonToRace(
|
|
@@ -17372,6 +17468,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17372
17468
|
`update: target ${decision.targetId} ${existing ? "superseded" : "deleted"} before the write`
|
|
17373
17469
|
);
|
|
17374
17470
|
}
|
|
17471
|
+
if (existing.content !== expectedContent) {
|
|
17472
|
+
return abandonToRace(options, `update: target ${decision.targetId} edited before the write`);
|
|
17473
|
+
}
|
|
17375
17474
|
const mergedSourceIds = unionStrings(
|
|
17376
17475
|
existing.sourceChunkIds ?? [],
|
|
17377
17476
|
options.sourceChunkIds ?? []
|
|
@@ -17384,6 +17483,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17384
17483
|
const resurrect = resurrectFields(existing);
|
|
17385
17484
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
17386
17485
|
content: decision.content,
|
|
17486
|
+
expectedContent,
|
|
17387
17487
|
freeFormOnly: true,
|
|
17388
17488
|
proofCountIncrement: 1,
|
|
17389
17489
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -17396,10 +17496,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17396
17496
|
...factTypeUpdate !== void 0 && { factType: factTypeUpdate }
|
|
17397
17497
|
});
|
|
17398
17498
|
if (!updated) {
|
|
17399
|
-
await assertMergeTargetGoneOrThrow(ctx, decision.targetId);
|
|
17499
|
+
await assertMergeTargetGoneOrThrow(ctx, decision.targetId, expectedContent);
|
|
17400
17500
|
return abandonToRace(
|
|
17401
17501
|
options,
|
|
17402
|
-
`update: target ${decision.targetId}
|
|
17502
|
+
`update: target ${decision.targetId} changed mid-write (consolidated rewrite lost)`
|
|
17403
17503
|
);
|
|
17404
17504
|
}
|
|
17405
17505
|
cacheRowVector(
|
|
@@ -17426,9 +17526,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17426
17526
|
);
|
|
17427
17527
|
return null;
|
|
17428
17528
|
}
|
|
17429
|
-
async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
17529
|
+
async function assertMergeTargetGoneOrThrow(ctx, targetId, expectedContent) {
|
|
17430
17530
|
const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
|
|
17431
|
-
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
|
|
17531
|
+
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0) && (expectedContent === void 0 || stillExists.content === expectedContent)) {
|
|
17432
17532
|
throw new RetainError(
|
|
17433
17533
|
"merge-not-persisted",
|
|
17434
17534
|
`retain: merge into memory ${targetId} failed to persist`
|
|
@@ -19235,6 +19335,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
19235
19335
|
},
|
|
19236
19336
|
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
19237
19337
|
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
19338
|
+
...options.vaultPreparation && { vaultPreparation: options.vaultPreparation },
|
|
19238
19339
|
...subQueries && { subQueries },
|
|
19239
19340
|
...options.scopes && { scopes: options.scopes },
|
|
19240
19341
|
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
@@ -20814,16 +20915,16 @@ function createRemoteMemoryPipeline(options) {
|
|
|
20814
20915
|
create: (input) => write(createRow(input), 0),
|
|
20815
20916
|
update: async (id2, patch) => {
|
|
20816
20917
|
const existing = await get(id2);
|
|
20817
|
-
if (!existing || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
|
|
20918
|
+
if (!existing || patch.expectedContent !== void 0 && existing.content !== patch.expectedContent || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
|
|
20818
20919
|
return null;
|
|
20819
20920
|
const snapshot = snapshots.get(id2);
|
|
20820
20921
|
const memory = {
|
|
20821
20922
|
...snapshot.memory,
|
|
20822
|
-
content: patch.content,
|
|
20923
|
+
content: patch.content ?? snapshot.memory.content,
|
|
20823
20924
|
updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Math.max(Date.now(), (snapshot.memory.topics_extracted_at ?? 0) + 1)
|
|
20824
20925
|
};
|
|
20825
20926
|
if (patch.scope !== void 0) memory.scope = patch.scope;
|
|
20826
|
-
if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
|
|
20927
|
+
if (patch.embedding === void 0 && patch.content !== void 0 && patch.content !== snapshot.memory.content) {
|
|
20827
20928
|
delete memory.embedding;
|
|
20828
20929
|
delete memory.embedding_model;
|
|
20829
20930
|
}
|
|
@@ -22825,13 +22926,20 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
22825
22926
|
}
|
|
22826
22927
|
}
|
|
22827
22928
|
}
|
|
22929
|
+
const vaultPreparation = createVaultPreparation();
|
|
22828
22930
|
const settled = await Promise.allSettled(
|
|
22829
22931
|
facets.map(async (facet) => {
|
|
22830
22932
|
const prior = previous?.sections.find((s) => s.key === facet.key);
|
|
22831
22933
|
if (prior && !staleKeys.has(facet.key)) {
|
|
22832
22934
|
return prior;
|
|
22833
22935
|
}
|
|
22834
|
-
return synthesizeFacet(
|
|
22936
|
+
return synthesizeFacet(
|
|
22937
|
+
facet,
|
|
22938
|
+
recallCtx,
|
|
22939
|
+
options,
|
|
22940
|
+
fallbackPriors.get(facet.key),
|
|
22941
|
+
vaultPreparation
|
|
22942
|
+
);
|
|
22835
22943
|
})
|
|
22836
22944
|
);
|
|
22837
22945
|
const sections = settled.map((r, i) => {
|
|
@@ -22985,7 +23093,7 @@ async function attributeFacts(ctx, candidates, facets) {
|
|
|
22985
23093
|
}
|
|
22986
23094
|
return keys;
|
|
22987
23095
|
}
|
|
22988
|
-
async function synthesizeFacet(facet, ctx, options, prior) {
|
|
23096
|
+
async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
22989
23097
|
const scopes = options.scopes ?? DEFAULT_SCOPES;
|
|
22990
23098
|
const limit = options.limit ?? DEFAULT_FACET_RECALL_LIMIT;
|
|
22991
23099
|
const factTypeWeights = { ...DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, ...options.factTypeWeights };
|
|
@@ -23002,6 +23110,7 @@ async function synthesizeFacet(facet, ctx, options, prior) {
|
|
|
23002
23110
|
};
|
|
23003
23111
|
}
|
|
23004
23112
|
const recalled = await recall(facet.query, ctx, {
|
|
23113
|
+
vaultPreparation,
|
|
23005
23114
|
scopes,
|
|
23006
23115
|
limit: hasReviewGate ? RECALL_MAX_LIMIT : limit,
|
|
23007
23116
|
types: ["fact"],
|