@anuma/sdk 6.33.2 → 6.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +1099 -293
- package/dist/expo/index.d.mts +218 -4
- package/dist/expo/index.d.ts +218 -4
- package/dist/expo/index.mjs +1095 -293
- package/dist/index.cjs +18 -6
- package/dist/index.mjs +18 -6
- package/dist/react/index.cjs +1180 -374
- package/dist/react/index.d.mts +251 -4
- package/dist/react/index.d.ts +251 -4
- package/dist/react/index.mjs +1176 -374
- package/dist/server/index.cjs +118 -86
- package/dist/server/index.d.mts +77 -3
- package/dist/server/index.d.ts +77 -3
- package/dist/server/index.mjs +118 -86
- package/dist/telemetry/index.d.mts +3 -4
- package/dist/telemetry/index.d.ts +3 -4
- package/dist/tools/selection/index.cjs +18 -6
- package/dist/tools/selection/index.mjs +18 -6
- package/package.json +1 -1
package/dist/server/index.cjs
CHANGED
|
@@ -19969,7 +19969,7 @@ async function embedOne(text12, options, outer) {
|
|
|
19969
19969
|
}
|
|
19970
19970
|
var DEFAULT_EMBEDDING_BATCH_SIZE = 100;
|
|
19971
19971
|
var DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
|
|
19972
|
-
async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs) {
|
|
19972
|
+
async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs, outer) {
|
|
19973
19973
|
const response = await withEmbeddingRetry(
|
|
19974
19974
|
() => withDeadline(
|
|
19975
19975
|
(signal) => postApiV1Embeddings({
|
|
@@ -19979,8 +19979,10 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
19979
19979
|
...signal && { signal }
|
|
19980
19980
|
}),
|
|
19981
19981
|
timeoutMs,
|
|
19982
|
-
"embedding batch request"
|
|
19983
|
-
|
|
19982
|
+
"embedding batch request",
|
|
19983
|
+
outer
|
|
19984
|
+
),
|
|
19985
|
+
outer
|
|
19984
19986
|
);
|
|
19985
19987
|
if (response.error) {
|
|
19986
19988
|
throw embeddingErrorFrom(response);
|
|
@@ -19998,6 +20000,11 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
19998
20000
|
}
|
|
19999
20001
|
async function generateEmbeddings(texts, options) {
|
|
20000
20002
|
if (texts.length === 0) return [];
|
|
20003
|
+
const total = options.totalTimeoutMs;
|
|
20004
|
+
if (total === void 0) return embedMany(texts, options, void 0);
|
|
20005
|
+
return withDeadline((signal) => embedMany(texts, options, signal), total, "embedding batch");
|
|
20006
|
+
}
|
|
20007
|
+
async function embedMany(texts, options, outer) {
|
|
20001
20008
|
const { baseUrl = BASE_URL, model, batchSize, cache } = options;
|
|
20002
20009
|
const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
|
|
20003
20010
|
const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
|
|
@@ -20018,7 +20025,8 @@ async function generateEmbeddings(texts, options) {
|
|
|
20018
20025
|
if (uncachedTexts.length === 0) {
|
|
20019
20026
|
return results;
|
|
20020
20027
|
}
|
|
20021
|
-
const headers = await resolveAuthHeaders(options);
|
|
20028
|
+
const headers = await resolveAuthHeaders(options, outer);
|
|
20029
|
+
if (outer?.aborted) throw outer.reason;
|
|
20022
20030
|
const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
20023
20031
|
let newEmbeddings;
|
|
20024
20032
|
if (uncachedTexts.length <= chunkSize) {
|
|
@@ -20029,7 +20037,8 @@ async function generateEmbeddings(texts, options) {
|
|
|
20029
20037
|
embeddingModel,
|
|
20030
20038
|
options.onUsage,
|
|
20031
20039
|
options.maskInput,
|
|
20032
|
-
timeoutMs
|
|
20040
|
+
timeoutMs,
|
|
20041
|
+
outer
|
|
20033
20042
|
);
|
|
20034
20043
|
} else {
|
|
20035
20044
|
const chunks = [];
|
|
@@ -20040,6 +20049,7 @@ async function generateEmbeddings(texts, options) {
|
|
|
20040
20049
|
let nextIndex = 0;
|
|
20041
20050
|
const worker = async () => {
|
|
20042
20051
|
while (nextIndex < chunks.length) {
|
|
20052
|
+
if (outer?.aborted) throw outer.reason;
|
|
20043
20053
|
const idx = nextIndex++;
|
|
20044
20054
|
allEmbeddings[idx] = await generateEmbeddingsBatch(
|
|
20045
20055
|
chunks[idx],
|
|
@@ -20048,7 +20058,8 @@ async function generateEmbeddings(texts, options) {
|
|
|
20048
20058
|
embeddingModel,
|
|
20049
20059
|
options.onUsage,
|
|
20050
20060
|
options.maskInput,
|
|
20051
|
-
timeoutMs
|
|
20061
|
+
timeoutMs,
|
|
20062
|
+
outer
|
|
20052
20063
|
);
|
|
20053
20064
|
}
|
|
20054
20065
|
};
|
|
@@ -20059,6 +20070,7 @@ async function generateEmbeddings(texts, options) {
|
|
|
20059
20070
|
await Promise.all(workers);
|
|
20060
20071
|
newEmbeddings = allEmbeddings.flat();
|
|
20061
20072
|
}
|
|
20073
|
+
if (outer?.aborted) throw outer.reason;
|
|
20062
20074
|
for (let i = 0; i < uncachedIndices.length; i++) {
|
|
20063
20075
|
const f32Embedding = Float32Array.from(newEmbeddings[i]);
|
|
20064
20076
|
results[uncachedIndices[i]] = Array.from(f32Embedding);
|
|
@@ -31574,7 +31586,7 @@ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, se
|
|
|
31574
31586
|
if (useFusion && !embeddingsUnavailable && facetQueries) {
|
|
31575
31587
|
let subEmbeddings;
|
|
31576
31588
|
try {
|
|
31577
|
-
subEmbeddings = await generateEmbeddings(facetQueries, embeddingOptions);
|
|
31589
|
+
subEmbeddings = prepared.facetEmbeddings ?? await generateEmbeddings(facetQueries, embeddingOptions);
|
|
31578
31590
|
} catch (err) {
|
|
31579
31591
|
getLogger().warn(
|
|
31580
31592
|
"memoryVault: sub-query embedding failed \u2014 falling back to single-query ranking: " + (err instanceof Error ? err.message : String(err))
|
|
@@ -31760,6 +31772,35 @@ var DEFAULT_SCOPE = "private";
|
|
|
31760
31772
|
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
|
|
31761
31773
|
var DEFAULT_CONSOLIDATE_TOP_K = 20;
|
|
31762
31774
|
async function retain(content, ctx, options = {}) {
|
|
31775
|
+
return retainWithPersistence(
|
|
31776
|
+
content,
|
|
31777
|
+
{
|
|
31778
|
+
embeddingOptions: ctx.embeddingOptions,
|
|
31779
|
+
vaultCache: ctx.vaultCache,
|
|
31780
|
+
persistence: {
|
|
31781
|
+
prepare: (query, searchOptions) => prepareVaultCandidates(
|
|
31782
|
+
query,
|
|
31783
|
+
ctx.vaultCtx,
|
|
31784
|
+
ctx.embeddingOptions,
|
|
31785
|
+
ctx.vaultCache,
|
|
31786
|
+
searchOptions
|
|
31787
|
+
),
|
|
31788
|
+
get: (id) => getVaultMemoryOp(ctx.vaultCtx, id),
|
|
31789
|
+
tombstones: (_embedding, _model, scope, folderId) => getAllVaultMemoriesOp(ctx.vaultCtx, {
|
|
31790
|
+
includeDeleted: true,
|
|
31791
|
+
scopes: [scope],
|
|
31792
|
+
...folderId !== void 0 && { folderId }
|
|
31793
|
+
}),
|
|
31794
|
+
create: (input) => createVaultMemoryOp(ctx.vaultCtx, input),
|
|
31795
|
+
update: (id, patch) => updateVaultMemoryOp(ctx.vaultCtx, id, patch),
|
|
31796
|
+
supersede: (id, successor) => supersedeVaultMemoryOp(ctx.vaultCtx, id, successor),
|
|
31797
|
+
createSuperseding: (input, target) => createSupersedingMemoryOp(ctx.vaultCtx, input, target)
|
|
31798
|
+
}
|
|
31799
|
+
},
|
|
31800
|
+
options
|
|
31801
|
+
);
|
|
31802
|
+
}
|
|
31803
|
+
async function retainWithPersistence(content, ctx, options = {}) {
|
|
31763
31804
|
const trimmed = content.trim();
|
|
31764
31805
|
if (trimmed.length === 0) {
|
|
31765
31806
|
throw new Error("retain: content cannot be empty");
|
|
@@ -31772,19 +31813,13 @@ async function retain(content, ctx, options = {}) {
|
|
|
31772
31813
|
let supersedeContent;
|
|
31773
31814
|
let prepared;
|
|
31774
31815
|
if (enableAutoMerge) {
|
|
31775
|
-
prepared = await
|
|
31776
|
-
|
|
31777
|
-
|
|
31778
|
-
|
|
31779
|
-
|
|
31780
|
-
{
|
|
31781
|
-
|
|
31782
|
-
useFusion: false,
|
|
31783
|
-
scopes: [resolvedScope],
|
|
31784
|
-
includeArchived: true,
|
|
31785
|
-
...options.folderId !== void 0 && { folderId: options.folderId }
|
|
31786
|
-
}
|
|
31787
|
-
);
|
|
31816
|
+
prepared = await ctx.persistence.prepare(trimmed, {
|
|
31817
|
+
limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
|
|
31818
|
+
useFusion: false,
|
|
31819
|
+
scopes: [resolvedScope],
|
|
31820
|
+
includeArchived: true,
|
|
31821
|
+
...options.folderId !== void 0 && { folderId: options.folderId }
|
|
31822
|
+
});
|
|
31788
31823
|
if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
|
|
31789
31824
|
throw new Error(
|
|
31790
31825
|
"retain: embeddings unavailable \u2014 refusing to auto-merge against an inert cosine lane, which would create a duplicate instead of merging into the existing memory. Retry when embeddings recover, or pass enableAutoMerge: false to force a create."
|
|
@@ -31815,7 +31850,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
31815
31850
|
);
|
|
31816
31851
|
if (matches.length > 0) {
|
|
31817
31852
|
const targetId = matches[0].uniqueId;
|
|
31818
|
-
const existing = await
|
|
31853
|
+
const existing = await ctx.persistence.get(targetId);
|
|
31819
31854
|
if (existing && !existing.supersededBy) {
|
|
31820
31855
|
const mergedSourceIds = unionStrings(
|
|
31821
31856
|
existing.sourceChunkIds ?? [],
|
|
@@ -31824,7 +31859,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
31824
31859
|
const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
|
|
31825
31860
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
31826
31861
|
const resurrect = resurrectFields(existing);
|
|
31827
|
-
const updated = await
|
|
31862
|
+
const updated = await ctx.persistence.update(targetId, {
|
|
31828
31863
|
content: existing.content,
|
|
31829
31864
|
proofCountIncrement: 1,
|
|
31830
31865
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -31851,7 +31886,8 @@ async function retain(content, ctx, options = {}) {
|
|
|
31851
31886
|
}
|
|
31852
31887
|
const contentToWrite = supersedeContent ?? trimmed;
|
|
31853
31888
|
const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
|
|
31854
|
-
const
|
|
31889
|
+
const generatedEmbedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
|
|
31890
|
+
const embedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
|
|
31855
31891
|
const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
31856
31892
|
if (options.respectTombstones) {
|
|
31857
31893
|
const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
|
|
@@ -31891,8 +31927,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
31891
31927
|
};
|
|
31892
31928
|
if (supersedeTargetIds.length > 0) {
|
|
31893
31929
|
const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
|
|
31894
|
-
const { created: created2, retired } = await
|
|
31895
|
-
ctx.vaultCtx,
|
|
31930
|
+
const { created: created2, retired } = await ctx.persistence.createSuperseding(
|
|
31896
31931
|
createOpts,
|
|
31897
31932
|
primaryTargetId
|
|
31898
31933
|
);
|
|
@@ -31908,11 +31943,11 @@ async function retain(content, ctx, options = {}) {
|
|
|
31908
31943
|
for (const staleId of restTargetIds) {
|
|
31909
31944
|
let ok = false;
|
|
31910
31945
|
try {
|
|
31911
|
-
ok = await
|
|
31946
|
+
ok = await ctx.persistence.supersede(staleId, created2.uniqueId) === true;
|
|
31912
31947
|
} catch {
|
|
31913
31948
|
}
|
|
31914
31949
|
if (ok) continue;
|
|
31915
|
-
const stillLive = await
|
|
31950
|
+
const stillLive = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(staleId) : ctx.persistence.get(staleId)).catch(() => null);
|
|
31916
31951
|
if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
|
|
31917
31952
|
}
|
|
31918
31953
|
if (liveLeftovers.length > 0) {
|
|
@@ -31939,7 +31974,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
31939
31974
|
`supersede: primary target ${primaryTargetId} retired or deleted inside the atomic write`
|
|
31940
31975
|
);
|
|
31941
31976
|
}
|
|
31942
|
-
const created = await
|
|
31977
|
+
const created = await ctx.persistence.create(createOpts);
|
|
31943
31978
|
cacheRowVector(
|
|
31944
31979
|
ctx.vaultCache,
|
|
31945
31980
|
created.uniqueId,
|
|
@@ -31958,11 +31993,7 @@ function unionStrings(a, b) {
|
|
|
31958
31993
|
return [.../* @__PURE__ */ new Set([...a, ...b])];
|
|
31959
31994
|
}
|
|
31960
31995
|
async function findTombstoneMatch(embedding, embeddingModel, scope, ctx, opts) {
|
|
31961
|
-
const rows = await
|
|
31962
|
-
includeDeleted: true,
|
|
31963
|
-
scopes: [scope],
|
|
31964
|
-
...opts.folderId !== void 0 && { folderId: opts.folderId }
|
|
31965
|
-
});
|
|
31996
|
+
const rows = await ctx.persistence.tombstones(embedding, embeddingModel, scope, opts.folderId);
|
|
31966
31997
|
let bestId = null;
|
|
31967
31998
|
let bestSim = opts.threshold;
|
|
31968
31999
|
for (const row of rows) {
|
|
@@ -32029,7 +32060,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
32029
32060
|
if (requestedIds.length === 0) return null;
|
|
32030
32061
|
const valid = [];
|
|
32031
32062
|
for (const id of requestedIds) {
|
|
32032
|
-
const existing = await
|
|
32063
|
+
const existing = await ctx.persistence.get(id);
|
|
32033
32064
|
if (existing && !existing.supersededBy) valid.push(id);
|
|
32034
32065
|
}
|
|
32035
32066
|
if (valid.length === 0) {
|
|
@@ -32041,7 +32072,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
32041
32072
|
return { supersede: valid, content: decision.content };
|
|
32042
32073
|
}
|
|
32043
32074
|
if (decision.action === "noop" && decision.targetId) {
|
|
32044
|
-
const existing = await
|
|
32075
|
+
const existing = await ctx.persistence.get(decision.targetId);
|
|
32045
32076
|
if (!existing || existing.supersededBy) {
|
|
32046
32077
|
return abandonToRace(
|
|
32047
32078
|
options,
|
|
@@ -32055,7 +32086,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
32055
32086
|
const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
|
|
32056
32087
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
32057
32088
|
const resurrect = resurrectFields(existing);
|
|
32058
|
-
const updated = await
|
|
32089
|
+
const updated = await ctx.persistence.update(decision.targetId, {
|
|
32059
32090
|
content: existing.content,
|
|
32060
32091
|
proofCountIncrement: 1,
|
|
32061
32092
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -32083,7 +32114,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
32083
32114
|
};
|
|
32084
32115
|
}
|
|
32085
32116
|
if (decision.action === "update" && decision.targetId && decision.content) {
|
|
32086
|
-
const existing = await
|
|
32117
|
+
const existing = await ctx.persistence.get(decision.targetId);
|
|
32087
32118
|
if (!existing || existing.supersededBy) {
|
|
32088
32119
|
return abandonToRace(
|
|
32089
32120
|
options,
|
|
@@ -32094,12 +32125,13 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
32094
32125
|
existing.sourceChunkIds ?? [],
|
|
32095
32126
|
options.sourceChunkIds ?? []
|
|
32096
32127
|
);
|
|
32097
|
-
const
|
|
32128
|
+
const generatedEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
|
|
32129
|
+
const newEmbedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
|
|
32098
32130
|
const consolidatedModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
32099
32131
|
const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
|
|
32100
32132
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
32101
32133
|
const resurrect = resurrectFields(existing);
|
|
32102
|
-
const updated = await
|
|
32134
|
+
const updated = await ctx.persistence.update(decision.targetId, {
|
|
32103
32135
|
content: decision.content,
|
|
32104
32136
|
proofCountIncrement: 1,
|
|
32105
32137
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -32143,7 +32175,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
32143
32175
|
return null;
|
|
32144
32176
|
}
|
|
32145
32177
|
async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
32146
|
-
const stillExists = await
|
|
32178
|
+
const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
|
|
32147
32179
|
if (stillExists) {
|
|
32148
32180
|
throw new Error(`retain: merge into memory ${targetId} failed to persist`);
|
|
32149
32181
|
}
|
|
@@ -33642,7 +33674,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
33642
33674
|
if (graphLaneFailed) degraded.push("graph-lane-failed");
|
|
33643
33675
|
if (temporalLaneFailed) degraded.push("temporal-lane-failed");
|
|
33644
33676
|
if (chunksScopeRestricted) degraded.push("chunks-scope-restricted");
|
|
33645
|
-
const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
|
|
33677
|
+
const laneRan = types.includes("fact") && (!!ctx.factSource || !!ctx.vaultCtx && !!ctx.vaultCache) || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
|
|
33646
33678
|
const scores = admitted.map((m) => m.score);
|
|
33647
33679
|
const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
|
|
33648
33680
|
const diagnostics = {
|
|
@@ -33684,7 +33716,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
33684
33716
|
return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
|
|
33685
33717
|
}
|
|
33686
33718
|
const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
|
|
33687
|
-
const wantsTemporal = types.includes("fact") && ctx.vaultCtx;
|
|
33719
|
+
const wantsTemporal = types.includes("fact") && (ctx.factSource || ctx.vaultCtx);
|
|
33688
33720
|
const graphRefiner = flags.traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
|
|
33689
33721
|
const queryEmbedTotalTimeoutMs = options.queryEmbedTotalTimeoutMs ?? DEFAULT_QUERY_EMBED_TOTAL_TIMEOUT_MS;
|
|
33690
33722
|
const prepStart = nowMs2();
|
|
@@ -33714,7 +33746,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
33714
33746
|
safeLane(
|
|
33715
33747
|
"graph",
|
|
33716
33748
|
() => graphLaneFailed = true,
|
|
33717
|
-
() => buildGraphLaneRanking(query, ctx, flags.traverse, {
|
|
33749
|
+
() => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(query, ctx, flags.traverse, {
|
|
33718
33750
|
...options.maxHops !== void 0 && { maxHops: options.maxHops },
|
|
33719
33751
|
...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
|
|
33720
33752
|
...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
|
|
@@ -33725,13 +33757,13 @@ async function recall(query, ctx, options = {}) {
|
|
|
33725
33757
|
wantsTemporal ? safeLane(
|
|
33726
33758
|
"temporal",
|
|
33727
33759
|
() => temporalLaneFailed = true,
|
|
33728
|
-
() => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
|
|
33760
|
+
() => ctx.factSource ? ctx.factSource.temporalRanking(query, options.now) : buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
|
|
33729
33761
|
) : Promise.resolve([])
|
|
33730
33762
|
]);
|
|
33731
33763
|
prepMs = nowMs2() - prepStart;
|
|
33732
33764
|
graphLaneCount = entityRanking.length;
|
|
33733
33765
|
temporalLaneCount = temporalRanking.length;
|
|
33734
|
-
if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
|
|
33766
|
+
if (types.includes("fact") && (ctx.factSource || ctx.vaultCtx && ctx.vaultCache)) {
|
|
33735
33767
|
const factStart = nowMs2();
|
|
33736
33768
|
const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
|
|
33737
33769
|
factFloor = vaultMinScore;
|
|
@@ -33747,50 +33779,50 @@ async function recall(query, ctx, options = {}) {
|
|
|
33747
33779
|
rankedOnCosine: factRankedOnCosine,
|
|
33748
33780
|
decryptLast: factDecryptLast,
|
|
33749
33781
|
rowsDecrypted: factRowsDecrypted
|
|
33750
|
-
} = await searchVaultMemoriesWithSize(
|
|
33751
|
-
|
|
33782
|
+
} = await (ctx.factSource?.search.bind(ctx.factSource) ?? ((searchQuery, searchOptions) => searchVaultMemoriesWithSize(
|
|
33783
|
+
searchQuery,
|
|
33752
33784
|
ctx.vaultCtx,
|
|
33753
33785
|
ctx.embeddingOptions,
|
|
33754
33786
|
ctx.vaultCache,
|
|
33755
|
-
|
|
33756
|
-
|
|
33757
|
-
|
|
33758
|
-
|
|
33759
|
-
|
|
33760
|
-
|
|
33761
|
-
|
|
33762
|
-
|
|
33763
|
-
|
|
33764
|
-
|
|
33765
|
-
|
|
33766
|
-
|
|
33767
|
-
|
|
33768
|
-
|
|
33769
|
-
|
|
33770
|
-
|
|
33771
|
-
|
|
33772
|
-
|
|
33773
|
-
|
|
33774
|
-
|
|
33775
|
-
|
|
33776
|
-
|
|
33777
|
-
|
|
33778
|
-
|
|
33779
|
-
|
|
33780
|
-
|
|
33781
|
-
|
|
33782
|
-
|
|
33783
|
-
|
|
33784
|
-
|
|
33785
|
-
|
|
33786
|
-
|
|
33787
|
-
|
|
33788
|
-
|
|
33789
|
-
|
|
33790
|
-
|
|
33791
|
-
|
|
33792
|
-
|
|
33793
|
-
);
|
|
33787
|
+
searchOptions
|
|
33788
|
+
)))(query, {
|
|
33789
|
+
limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
|
|
33790
|
+
minSimilarity: vaultMinScore,
|
|
33791
|
+
useFusion: true,
|
|
33792
|
+
rerank: flags.rerank,
|
|
33793
|
+
...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
|
|
33794
|
+
...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
|
|
33795
|
+
...options.rerankLoadTimeoutMs !== void 0 && {
|
|
33796
|
+
rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
|
|
33797
|
+
},
|
|
33798
|
+
...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
|
|
33799
|
+
...options.recency && { recency: options.recency },
|
|
33800
|
+
...options.mmr !== void 0 && { mmr: options.mmr },
|
|
33801
|
+
...options.supersessionBoost !== void 0 && {
|
|
33802
|
+
supersessionBoost: options.supersessionBoost
|
|
33803
|
+
},
|
|
33804
|
+
...options.supersessionWindow !== void 0 && {
|
|
33805
|
+
supersessionWindow: options.supersessionWindow
|
|
33806
|
+
},
|
|
33807
|
+
...options.proofCountAlpha !== void 0 && {
|
|
33808
|
+
proofCountAlpha: options.proofCountAlpha
|
|
33809
|
+
},
|
|
33810
|
+
...options.bm25AdmissionDivisor !== void 0 && {
|
|
33811
|
+
bm25AdmissionDivisor: options.bm25AdmissionDivisor
|
|
33812
|
+
},
|
|
33813
|
+
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
33814
|
+
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
33815
|
+
...subQueries && { subQueries },
|
|
33816
|
+
...options.scopes && { scopes: options.scopes },
|
|
33817
|
+
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
33818
|
+
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
33819
|
+
...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
|
|
33820
|
+
...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
|
|
33821
|
+
...entityRanking.length > 0 && { entityRanking },
|
|
33822
|
+
...temporalRanking.length > 0 && { temporalRanking },
|
|
33823
|
+
...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
|
|
33824
|
+
queryEmbedTotalTimeoutMs
|
|
33825
|
+
});
|
|
33794
33826
|
factResults.push(
|
|
33795
33827
|
...dedupeBy(
|
|
33796
33828
|
results,
|
package/dist/server/index.d.mts
CHANGED
|
@@ -1227,13 +1227,13 @@ interface EmbeddingOptions {
|
|
|
1227
1227
|
*/
|
|
1228
1228
|
tokenTimeoutMs?: number;
|
|
1229
1229
|
/**
|
|
1230
|
-
* Overall deadline, in ms, for one `generateEmbedding` call — the token read,
|
|
1230
|
+
* Overall deadline, in ms, for one `generateEmbedding` or `generateEmbeddings` call — the token read,
|
|
1231
1231
|
* every retry attempt and the backoff between them. Unset (the default) means
|
|
1232
1232
|
* only the per-attempt deadlines apply, which is right for background/bulk
|
|
1233
1233
|
* embeds. The recall query path sets it (see
|
|
1234
1234
|
* `RecallOptions.queryEmbedTotalTimeoutMs`) so an outage degrades a turn to
|
|
1235
|
-
* BM25 within a few seconds instead of ~4 x `timeoutMs`.
|
|
1236
|
-
*
|
|
1235
|
+
* BM25 within a few seconds instead of ~4 x `timeoutMs`. Batch calls share
|
|
1236
|
+
* one budget across authentication, all chunks, retries and backoff.
|
|
1237
1237
|
*/
|
|
1238
1238
|
totalTimeoutMs?: number;
|
|
1239
1239
|
}
|
|
@@ -5998,6 +5998,55 @@ interface VaultSearchResult {
|
|
|
5998
5998
|
* these to suppress the originating chunk in the chunk lane. */
|
|
5999
5999
|
sourceChunkIds?: string[] | null;
|
|
6000
6000
|
}
|
|
6001
|
+
/**
|
|
6002
|
+
* Search + rank in one call. Thin wrapper over {@link prepareVaultCandidates} +
|
|
6003
|
+
* {@link rankPreparedVaultCandidates}; behavior is unchanged.
|
|
6004
|
+
*/
|
|
6005
|
+
declare function searchVaultMemoriesWithSize(query: string, vaultCtx: VaultMemoryOperationsContext, embeddingOptions: EmbeddingOptions, cache: VaultEmbeddingCache, searchOptions?: MemoryVaultSearchOptions): Promise<{
|
|
6006
|
+
results: VaultSearchResult[];
|
|
6007
|
+
vaultSize: number;
|
|
6008
|
+
reranked: boolean;
|
|
6009
|
+
/**
|
|
6010
|
+
* Wall-clock ms this search spent inside the cross-encoder.
|
|
6011
|
+
*
|
|
6012
|
+
* 0 on every path that did not reach the CE, which `reranked` already
|
|
6013
|
+
* distinguishes from "ran and cost nothing". Reported because `factLane`
|
|
6014
|
+
* timing alone could not separate the rerank from the query embed, the vault
|
|
6015
|
+
* read and the fused ranking — see {@link RerankStats}.
|
|
6016
|
+
*/
|
|
6017
|
+
rerankMs: number;
|
|
6018
|
+
hadV2Head: boolean;
|
|
6019
|
+
/** True when this search had no usable cosine lane and ranked on BM25 alone. */
|
|
6020
|
+
embeddingsUnavailable: boolean;
|
|
6021
|
+
/**
|
|
6022
|
+
* True when this search actually scored rows against a real query vector.
|
|
6023
|
+
*
|
|
6024
|
+
* NOT the inverse of `embeddingsUnavailable`. That flag answers "did cosine
|
|
6025
|
+
* break?", and it is `false` on the degenerate returns below — an invalid
|
|
6026
|
+
* query, an empty scope, nothing decryptable — where cosine did not break so
|
|
6027
|
+
* much as never run. A caller asking "can this lane vouch that semantic
|
|
6028
|
+
* ranking happened?" (recall's chunk-lane reconciliation) must not read those
|
|
6029
|
+
* as a healthy cosine pass.
|
|
6030
|
+
*/
|
|
6031
|
+
rankedOnCosine: boolean;
|
|
6032
|
+
/**
|
|
6033
|
+
* Which vault read path ran — projected key scan (`true`) or legacy whole-vault
|
|
6034
|
+
* load (`false`). See {@link PreparedVaultCandidates.decryptLast}.
|
|
6035
|
+
*/
|
|
6036
|
+
decryptLast: boolean;
|
|
6037
|
+
/**
|
|
6038
|
+
* Rows this search paid to decrypt. Read against `vaultSize` — see
|
|
6039
|
+
* {@link PreparedVaultCandidates.rowsDecrypted}.
|
|
6040
|
+
*/
|
|
6041
|
+
rowsDecrypted: number;
|
|
6042
|
+
/**
|
|
6043
|
+
* Wall-clock ms spent embedding the query, and rows the lane had to re-embed
|
|
6044
|
+
* because their stored vector was unusable — see
|
|
6045
|
+
* {@link PreparedVaultCandidates.queryEmbedMs} and `rowsEmbedded`.
|
|
6046
|
+
*/
|
|
6047
|
+
queryEmbedMs: number;
|
|
6048
|
+
rowsEmbedded: number;
|
|
6049
|
+
}>;
|
|
6001
6050
|
/**
|
|
6002
6051
|
* Search vault memories by semantic similarity. Returns structured results
|
|
6003
6052
|
* sorted by descending similarity, filtered by threshold and limit.
|
|
@@ -6262,7 +6311,15 @@ interface RecallOptions {
|
|
|
6262
6311
|
*/
|
|
6263
6312
|
graphRefine?: boolean;
|
|
6264
6313
|
}
|
|
6314
|
+
/** A fact source supplies bounded candidates; recall owns ranking and result handling. */
|
|
6315
|
+
interface RecallFactSource {
|
|
6316
|
+
search: (query: string, options?: MemoryVaultSearchOptions) => ReturnType<typeof searchVaultMemoriesWithSize>;
|
|
6317
|
+
graphRanking: (query: string, traverse: boolean, options: RecallOptions) => Promise<string[]>;
|
|
6318
|
+
temporalRanking: (query: string, now?: number) => Promise<string[]>;
|
|
6319
|
+
}
|
|
6265
6320
|
interface RecallContext {
|
|
6321
|
+
/** Alternative to a WatermelonDB vault for fact-only recall. */
|
|
6322
|
+
factSource?: RecallFactSource;
|
|
6266
6323
|
/** Required when `types` includes 'fact'. */
|
|
6267
6324
|
vaultCtx?: VaultMemoryOperationsContext;
|
|
6268
6325
|
/** Required when `types` includes 'chunk'. */
|
|
@@ -10606,6 +10663,23 @@ interface PostgreSQLAdapterOptions {
|
|
|
10606
10663
|
* @param pgSchema - PostgreSQL schema namespace (defaults to "public")
|
|
10607
10664
|
*/
|
|
10608
10665
|
declare function schemaToCreateSQL(schema: AppSchema, pgSchema?: string): string[];
|
|
10666
|
+
/**
|
|
10667
|
+
* WatermelonDB `DatabaseAdapter` backed by any `pg.Pool`-compatible pool, so SDK operations run unchanged on the server.
|
|
10668
|
+
*
|
|
10669
|
+
* @example
|
|
10670
|
+
* ```typescript
|
|
10671
|
+
* import pg from "pg";
|
|
10672
|
+
* import { PostgreSQLAdapter, sdkSchema, sdkMigrations } from "@anuma/sdk/server";
|
|
10673
|
+
*
|
|
10674
|
+
* const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
|
10675
|
+
* const adapter = new PostgreSQLAdapter({
|
|
10676
|
+
* pool,
|
|
10677
|
+
* schema: sdkSchema,
|
|
10678
|
+
* migrations: sdkMigrations,
|
|
10679
|
+
* dbName: "anuma-server-wallet123",
|
|
10680
|
+
* });
|
|
10681
|
+
* ```
|
|
10682
|
+
*/
|
|
10609
10683
|
declare class PostgreSQLAdapter implements DatabaseAdapter {
|
|
10610
10684
|
schema: AppSchema;
|
|
10611
10685
|
dbName: string;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1227,13 +1227,13 @@ interface EmbeddingOptions {
|
|
|
1227
1227
|
*/
|
|
1228
1228
|
tokenTimeoutMs?: number;
|
|
1229
1229
|
/**
|
|
1230
|
-
* Overall deadline, in ms, for one `generateEmbedding` call — the token read,
|
|
1230
|
+
* Overall deadline, in ms, for one `generateEmbedding` or `generateEmbeddings` call — the token read,
|
|
1231
1231
|
* every retry attempt and the backoff between them. Unset (the default) means
|
|
1232
1232
|
* only the per-attempt deadlines apply, which is right for background/bulk
|
|
1233
1233
|
* embeds. The recall query path sets it (see
|
|
1234
1234
|
* `RecallOptions.queryEmbedTotalTimeoutMs`) so an outage degrades a turn to
|
|
1235
|
-
* BM25 within a few seconds instead of ~4 x `timeoutMs`.
|
|
1236
|
-
*
|
|
1235
|
+
* BM25 within a few seconds instead of ~4 x `timeoutMs`. Batch calls share
|
|
1236
|
+
* one budget across authentication, all chunks, retries and backoff.
|
|
1237
1237
|
*/
|
|
1238
1238
|
totalTimeoutMs?: number;
|
|
1239
1239
|
}
|
|
@@ -5998,6 +5998,55 @@ interface VaultSearchResult {
|
|
|
5998
5998
|
* these to suppress the originating chunk in the chunk lane. */
|
|
5999
5999
|
sourceChunkIds?: string[] | null;
|
|
6000
6000
|
}
|
|
6001
|
+
/**
|
|
6002
|
+
* Search + rank in one call. Thin wrapper over {@link prepareVaultCandidates} +
|
|
6003
|
+
* {@link rankPreparedVaultCandidates}; behavior is unchanged.
|
|
6004
|
+
*/
|
|
6005
|
+
declare function searchVaultMemoriesWithSize(query: string, vaultCtx: VaultMemoryOperationsContext, embeddingOptions: EmbeddingOptions, cache: VaultEmbeddingCache, searchOptions?: MemoryVaultSearchOptions): Promise<{
|
|
6006
|
+
results: VaultSearchResult[];
|
|
6007
|
+
vaultSize: number;
|
|
6008
|
+
reranked: boolean;
|
|
6009
|
+
/**
|
|
6010
|
+
* Wall-clock ms this search spent inside the cross-encoder.
|
|
6011
|
+
*
|
|
6012
|
+
* 0 on every path that did not reach the CE, which `reranked` already
|
|
6013
|
+
* distinguishes from "ran and cost nothing". Reported because `factLane`
|
|
6014
|
+
* timing alone could not separate the rerank from the query embed, the vault
|
|
6015
|
+
* read and the fused ranking — see {@link RerankStats}.
|
|
6016
|
+
*/
|
|
6017
|
+
rerankMs: number;
|
|
6018
|
+
hadV2Head: boolean;
|
|
6019
|
+
/** True when this search had no usable cosine lane and ranked on BM25 alone. */
|
|
6020
|
+
embeddingsUnavailable: boolean;
|
|
6021
|
+
/**
|
|
6022
|
+
* True when this search actually scored rows against a real query vector.
|
|
6023
|
+
*
|
|
6024
|
+
* NOT the inverse of `embeddingsUnavailable`. That flag answers "did cosine
|
|
6025
|
+
* break?", and it is `false` on the degenerate returns below — an invalid
|
|
6026
|
+
* query, an empty scope, nothing decryptable — where cosine did not break so
|
|
6027
|
+
* much as never run. A caller asking "can this lane vouch that semantic
|
|
6028
|
+
* ranking happened?" (recall's chunk-lane reconciliation) must not read those
|
|
6029
|
+
* as a healthy cosine pass.
|
|
6030
|
+
*/
|
|
6031
|
+
rankedOnCosine: boolean;
|
|
6032
|
+
/**
|
|
6033
|
+
* Which vault read path ran — projected key scan (`true`) or legacy whole-vault
|
|
6034
|
+
* load (`false`). See {@link PreparedVaultCandidates.decryptLast}.
|
|
6035
|
+
*/
|
|
6036
|
+
decryptLast: boolean;
|
|
6037
|
+
/**
|
|
6038
|
+
* Rows this search paid to decrypt. Read against `vaultSize` — see
|
|
6039
|
+
* {@link PreparedVaultCandidates.rowsDecrypted}.
|
|
6040
|
+
*/
|
|
6041
|
+
rowsDecrypted: number;
|
|
6042
|
+
/**
|
|
6043
|
+
* Wall-clock ms spent embedding the query, and rows the lane had to re-embed
|
|
6044
|
+
* because their stored vector was unusable — see
|
|
6045
|
+
* {@link PreparedVaultCandidates.queryEmbedMs} and `rowsEmbedded`.
|
|
6046
|
+
*/
|
|
6047
|
+
queryEmbedMs: number;
|
|
6048
|
+
rowsEmbedded: number;
|
|
6049
|
+
}>;
|
|
6001
6050
|
/**
|
|
6002
6051
|
* Search vault memories by semantic similarity. Returns structured results
|
|
6003
6052
|
* sorted by descending similarity, filtered by threshold and limit.
|
|
@@ -6262,7 +6311,15 @@ interface RecallOptions {
|
|
|
6262
6311
|
*/
|
|
6263
6312
|
graphRefine?: boolean;
|
|
6264
6313
|
}
|
|
6314
|
+
/** A fact source supplies bounded candidates; recall owns ranking and result handling. */
|
|
6315
|
+
interface RecallFactSource {
|
|
6316
|
+
search: (query: string, options?: MemoryVaultSearchOptions) => ReturnType<typeof searchVaultMemoriesWithSize>;
|
|
6317
|
+
graphRanking: (query: string, traverse: boolean, options: RecallOptions) => Promise<string[]>;
|
|
6318
|
+
temporalRanking: (query: string, now?: number) => Promise<string[]>;
|
|
6319
|
+
}
|
|
6265
6320
|
interface RecallContext {
|
|
6321
|
+
/** Alternative to a WatermelonDB vault for fact-only recall. */
|
|
6322
|
+
factSource?: RecallFactSource;
|
|
6266
6323
|
/** Required when `types` includes 'fact'. */
|
|
6267
6324
|
vaultCtx?: VaultMemoryOperationsContext;
|
|
6268
6325
|
/** Required when `types` includes 'chunk'. */
|
|
@@ -10606,6 +10663,23 @@ interface PostgreSQLAdapterOptions {
|
|
|
10606
10663
|
* @param pgSchema - PostgreSQL schema namespace (defaults to "public")
|
|
10607
10664
|
*/
|
|
10608
10665
|
declare function schemaToCreateSQL(schema: AppSchema, pgSchema?: string): string[];
|
|
10666
|
+
/**
|
|
10667
|
+
* WatermelonDB `DatabaseAdapter` backed by any `pg.Pool`-compatible pool, so SDK operations run unchanged on the server.
|
|
10668
|
+
*
|
|
10669
|
+
* @example
|
|
10670
|
+
* ```typescript
|
|
10671
|
+
* import pg from "pg";
|
|
10672
|
+
* import { PostgreSQLAdapter, sdkSchema, sdkMigrations } from "@anuma/sdk/server";
|
|
10673
|
+
*
|
|
10674
|
+
* const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
|
10675
|
+
* const adapter = new PostgreSQLAdapter({
|
|
10676
|
+
* pool,
|
|
10677
|
+
* schema: sdkSchema,
|
|
10678
|
+
* migrations: sdkMigrations,
|
|
10679
|
+
* dbName: "anuma-server-wallet123",
|
|
10680
|
+
* });
|
|
10681
|
+
* ```
|
|
10682
|
+
*/
|
|
10609
10683
|
declare class PostgreSQLAdapter implements DatabaseAdapter {
|
|
10610
10684
|
schema: AppSchema;
|
|
10611
10685
|
dbName: string;
|