@anuma/sdk 2.4.0 → 2.4.1
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-SF5AYTXH.mjs → chunk-UOUJUZM4.mjs} +229 -35
- package/dist/expo/index.cjs +256 -38
- package/dist/expo/index.d.mts +146 -1
- package/dist/expo/index.d.ts +146 -1
- package/dist/expo/index.mjs +25 -3
- package/dist/expo/{recall-PCKDVF3U.mjs → recall-HI7VO3VM.mjs} +1 -1
- package/dist/react/{chunk-JUDJVX66.mjs → chunk-IYDQBFS2.mjs} +229 -35
- package/dist/react/index.cjs +252 -37
- package/dist/react/index.d.mts +153 -1
- package/dist/react/index.d.ts +153 -1
- package/dist/react/index.mjs +21 -2
- package/dist/react/{recall-DSJSBDR4.mjs → recall-G3CS444F.mjs} +1 -1
- package/dist/server/{chunk-3AWYZRTS.mjs → chunk-3MLG7SUH.mjs} +229 -35
- package/dist/server/index.cjs +245 -36
- package/dist/server/index.d.mts +153 -1
- package/dist/server/index.d.ts +153 -1
- package/dist/server/index.mjs +14 -1
- package/dist/server/{recall-EWMI64SA.mjs → recall-MJHGXMHZ.mjs} +1 -1
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -2770,7 +2770,13 @@ async function searchMessagesOp(ctx, queryVector, options) {
|
|
|
2770
2770
|
);
|
|
2771
2771
|
}
|
|
2772
2772
|
async function searchChunksOp(ctx, queryVector, options) {
|
|
2773
|
-
const {
|
|
2773
|
+
const {
|
|
2774
|
+
limit = 10,
|
|
2775
|
+
minSimilarity = 0.5,
|
|
2776
|
+
conversationId,
|
|
2777
|
+
embeddingModel,
|
|
2778
|
+
chunkCache
|
|
2779
|
+
} = options || {};
|
|
2774
2780
|
const activeConversations = await ctx.conversationsCollection.query(import_watermelondb.Q.where("is_deleted", false)).fetch();
|
|
2775
2781
|
const activeConversationIds = new Set(
|
|
2776
2782
|
// Use _getRaw for reliable raw column access
|
|
@@ -2790,23 +2796,54 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
2790
2796
|
continue;
|
|
2791
2797
|
}
|
|
2792
2798
|
}
|
|
2799
|
+
const version = Number(message._getRaw("updated_at")) || 0;
|
|
2800
|
+
const cached = chunkCache?.get(message.id);
|
|
2801
|
+
if (cached && cached.version === version) {
|
|
2802
|
+
if (cached.chunks.length > 0) {
|
|
2803
|
+
for (let ci = 0; ci < cached.chunks.length; ci++) {
|
|
2804
|
+
const vec = cached.chunks[ci];
|
|
2805
|
+
if (vec.length === 0) continue;
|
|
2806
|
+
const similarity = cosineSimilarity(queryVector, vec);
|
|
2807
|
+
if (similarity >= minSimilarity) {
|
|
2808
|
+
candidates.push({
|
|
2809
|
+
message,
|
|
2810
|
+
similarity,
|
|
2811
|
+
chunkTextSource: { kind: "chunk-cached", chunkIndex: ci, version }
|
|
2812
|
+
});
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
} else if (cached.fallback) {
|
|
2816
|
+
const similarity = cosineSimilarity(queryVector, cached.fallback);
|
|
2817
|
+
if (similarity >= minSimilarity) {
|
|
2818
|
+
candidates.push({ message, similarity, chunkTextSource: { kind: "message" } });
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
continue;
|
|
2822
|
+
}
|
|
2793
2823
|
const chunks = await readJsonField(message, "chunks", ctx.walletAddress);
|
|
2794
2824
|
if (chunks && chunks.length > 0) {
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2825
|
+
const vectors = chunks.map(
|
|
2826
|
+
(chunk) => chunk.vector && chunk.vector.length > 0 ? Float32Array.from(chunk.vector) : new Float32Array(0)
|
|
2827
|
+
);
|
|
2828
|
+
chunkCache?.set(message.id, { version, chunks: vectors });
|
|
2829
|
+
for (let ci = 0; ci < chunks.length; ci++) {
|
|
2830
|
+
const vec = vectors[ci];
|
|
2831
|
+
if (vec.length === 0) continue;
|
|
2832
|
+
const similarity = cosineSimilarity(queryVector, vec);
|
|
2798
2833
|
if (similarity >= minSimilarity) {
|
|
2799
2834
|
candidates.push({
|
|
2800
2835
|
message,
|
|
2801
2836
|
similarity,
|
|
2802
|
-
chunkTextSource: { kind: "chunk", text:
|
|
2837
|
+
chunkTextSource: { kind: "chunk", text: chunks[ci].text }
|
|
2803
2838
|
});
|
|
2804
2839
|
}
|
|
2805
2840
|
}
|
|
2806
2841
|
} else {
|
|
2807
2842
|
const messageVector = await readJsonField(message, "vector", ctx.walletAddress);
|
|
2808
2843
|
if (!messageVector || messageVector.length === 0) continue;
|
|
2809
|
-
const
|
|
2844
|
+
const fallback = Float32Array.from(messageVector);
|
|
2845
|
+
chunkCache?.set(message.id, { version, chunks: [], fallback });
|
|
2846
|
+
const similarity = cosineSimilarity(queryVector, fallback);
|
|
2810
2847
|
if (similarity >= minSimilarity) {
|
|
2811
2848
|
candidates.push({ message, similarity, chunkTextSource: { kind: "message" } });
|
|
2812
2849
|
}
|
|
@@ -2833,9 +2870,31 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
2833
2870
|
})
|
|
2834
2871
|
)
|
|
2835
2872
|
);
|
|
2873
|
+
const chunkStateByMsgId = /* @__PURE__ */ new Map();
|
|
2874
|
+
const needsChunkText = /* @__PURE__ */ new Set();
|
|
2875
|
+
for (const c of topK) {
|
|
2876
|
+
if (c.chunkTextSource.kind === "chunk-cached") needsChunkText.add(c.message.id);
|
|
2877
|
+
}
|
|
2878
|
+
await Promise.all(
|
|
2879
|
+
Array.from(needsChunkText, async (id) => {
|
|
2880
|
+
const m = uniqueMessages.get(id);
|
|
2881
|
+
const parsed = await readJsonField(m, "chunks", ctx.walletAddress);
|
|
2882
|
+
const version = Number(m._getRaw("updated_at")) || 0;
|
|
2883
|
+
if (parsed) chunkStateByMsgId.set(id, { version, chunks: parsed });
|
|
2884
|
+
})
|
|
2885
|
+
);
|
|
2836
2886
|
return topK.map(({ message, similarity, chunkTextSource }) => {
|
|
2837
2887
|
const stored = { ...storedById.get(message.id) };
|
|
2838
|
-
|
|
2888
|
+
let chunkText2;
|
|
2889
|
+
if (chunkTextSource.kind === "chunk") {
|
|
2890
|
+
chunkText2 = chunkTextSource.text;
|
|
2891
|
+
} else if (chunkTextSource.kind === "chunk-cached") {
|
|
2892
|
+
const state = chunkStateByMsgId.get(message.id);
|
|
2893
|
+
const chunk = state && state.version === chunkTextSource.version ? state.chunks[chunkTextSource.chunkIndex] : void 0;
|
|
2894
|
+
chunkText2 = chunk?.text ?? stored.content;
|
|
2895
|
+
} else {
|
|
2896
|
+
chunkText2 = stored.content;
|
|
2897
|
+
}
|
|
2839
2898
|
return { chunkText: chunkText2, message: stored, similarity };
|
|
2840
2899
|
});
|
|
2841
2900
|
}
|
|
@@ -5172,9 +5231,9 @@ function recencyMultiplier(updatedAt, opts = {}) {
|
|
|
5172
5231
|
const updatedMs = updatedAt.getTime();
|
|
5173
5232
|
if (!Number.isFinite(updatedMs)) return noDate;
|
|
5174
5233
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
5175
|
-
const
|
|
5176
|
-
if (!Number.isFinite(
|
|
5177
|
-
const ageDays = Math.max(0, (
|
|
5234
|
+
const nowMs2 = now.getTime();
|
|
5235
|
+
if (!Number.isFinite(nowMs2)) return noDate;
|
|
5236
|
+
const ageDays = Math.max(0, (nowMs2 - updatedMs) / DAY_MS);
|
|
5178
5237
|
const perYearDecay = opts.perYearDecay ?? DEFAULT_PER_YEAR_DECAY;
|
|
5179
5238
|
const floor = opts.floor ?? DEFAULT_FLOOR;
|
|
5180
5239
|
const decay = perYearDecay * (ageDays / 365);
|
|
@@ -5192,14 +5251,42 @@ var init_recency = __esm({
|
|
|
5192
5251
|
});
|
|
5193
5252
|
|
|
5194
5253
|
// src/lib/memory/reranker.ts
|
|
5254
|
+
function isRerankerAvailable() {
|
|
5255
|
+
return available;
|
|
5256
|
+
}
|
|
5257
|
+
function isModuleMissing(err) {
|
|
5258
|
+
let e = err;
|
|
5259
|
+
for (let depth = 0; depth < 5 && e !== null && e !== void 0; depth++) {
|
|
5260
|
+
const code = e.code;
|
|
5261
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true;
|
|
5262
|
+
if (e instanceof Error && /cannot find (module|package)|failed to resolve|unable to resolve module|requiring unknown module/i.test(
|
|
5263
|
+
e.message
|
|
5264
|
+
)) {
|
|
5265
|
+
return true;
|
|
5266
|
+
}
|
|
5267
|
+
e = e.cause;
|
|
5268
|
+
}
|
|
5269
|
+
return false;
|
|
5270
|
+
}
|
|
5195
5271
|
async function getModel() {
|
|
5272
|
+
if (available === false) throw new RerankerUnavailableError(void 0);
|
|
5196
5273
|
if (!modelPromise) {
|
|
5197
5274
|
const load = (async () => {
|
|
5198
|
-
|
|
5275
|
+
let transformers;
|
|
5276
|
+
try {
|
|
5277
|
+
transformers = await import("@huggingface/transformers");
|
|
5278
|
+
} catch (err) {
|
|
5279
|
+
if (isModuleMissing(err)) {
|
|
5280
|
+
available = false;
|
|
5281
|
+
throw new RerankerUnavailableError(err);
|
|
5282
|
+
}
|
|
5283
|
+
throw err;
|
|
5284
|
+
}
|
|
5199
5285
|
const [tokenizer, model] = await Promise.all([
|
|
5200
5286
|
transformers.AutoTokenizer.from_pretrained(MODEL_ID),
|
|
5201
5287
|
transformers.AutoModelForSequenceClassification.from_pretrained(MODEL_ID)
|
|
5202
5288
|
]);
|
|
5289
|
+
available = true;
|
|
5203
5290
|
return { tokenizer, model };
|
|
5204
5291
|
})();
|
|
5205
5292
|
modelPromise = load;
|
|
@@ -5241,11 +5328,19 @@ async function rerankPairs(query, items) {
|
|
|
5241
5328
|
}
|
|
5242
5329
|
return items.map((item, i) => ({ id: item.id, content: item.content, score: scores[i] })).sort((a, b) => b.score - a.score);
|
|
5243
5330
|
}
|
|
5244
|
-
var MODEL_ID, modelPromise;
|
|
5331
|
+
var MODEL_ID, RerankerUnavailableError, available, modelPromise;
|
|
5245
5332
|
var init_reranker = __esm({
|
|
5246
5333
|
"src/lib/memory/reranker.ts"() {
|
|
5247
5334
|
"use strict";
|
|
5248
5335
|
MODEL_ID = "Xenova/ms-marco-MiniLM-L-6-v2";
|
|
5336
|
+
RerankerUnavailableError = class extends Error {
|
|
5337
|
+
constructor(reason) {
|
|
5338
|
+
super("cross-encoder reranker unavailable (@huggingface/transformers not installed)");
|
|
5339
|
+
this.name = "RerankerUnavailableError";
|
|
5340
|
+
this.reason = reason;
|
|
5341
|
+
}
|
|
5342
|
+
};
|
|
5343
|
+
available = void 0;
|
|
5249
5344
|
modelPromise = null;
|
|
5250
5345
|
}
|
|
5251
5346
|
});
|
|
@@ -5914,22 +6009,67 @@ async function recall(query, ctx, options = {}) {
|
|
|
5914
6009
|
const flags = flagsForBudget(requestedBudget);
|
|
5915
6010
|
const decomposeAvailable = flags.decompose && !!options.decomposeOptions;
|
|
5916
6011
|
const usedBudget = requestedBudget === "high" && !decomposeAvailable ? "mid" : requestedBudget;
|
|
6012
|
+
const t0 = nowMs();
|
|
6013
|
+
let prepMs = 0;
|
|
6014
|
+
let factLaneMs = 0;
|
|
6015
|
+
let chunkLaneMs = 0;
|
|
6016
|
+
let fuseMs = 0;
|
|
6017
|
+
const factResults = [];
|
|
6018
|
+
const chunkResults = [];
|
|
6019
|
+
let vaultSize;
|
|
6020
|
+
let didRerank = false;
|
|
6021
|
+
let hadV2Head = false;
|
|
6022
|
+
const emitDiagnostics = (candidateCount) => {
|
|
6023
|
+
const cb = options.onDiagnostics;
|
|
6024
|
+
if (!cb) return;
|
|
6025
|
+
const degraded = [];
|
|
6026
|
+
if (flags.rerank && factResults.length > 0 && hadV2Head && !didRerank) {
|
|
6027
|
+
degraded.push("rerank-unavailable");
|
|
6028
|
+
}
|
|
6029
|
+
if (flags.decompose && !decomposeAvailable) degraded.push("decompose-unavailable");
|
|
6030
|
+
const diagnostics = {
|
|
6031
|
+
usedBudget,
|
|
6032
|
+
reranked: didRerank,
|
|
6033
|
+
candidateCount,
|
|
6034
|
+
...vaultSize !== void 0 && { vaultSize },
|
|
6035
|
+
factCount: factResults.length,
|
|
6036
|
+
chunkCount: chunkResults.length,
|
|
6037
|
+
timings: {
|
|
6038
|
+
total: nowMs() - t0,
|
|
6039
|
+
prep: prepMs,
|
|
6040
|
+
factLane: factLaneMs,
|
|
6041
|
+
chunkLane: chunkLaneMs,
|
|
6042
|
+
fuse: fuseMs
|
|
6043
|
+
},
|
|
6044
|
+
degraded
|
|
6045
|
+
};
|
|
6046
|
+
try {
|
|
6047
|
+
cb(diagnostics);
|
|
6048
|
+
} catch {
|
|
6049
|
+
}
|
|
6050
|
+
};
|
|
5917
6051
|
if (!query || typeof query !== "string" || query.trim().length === 0) {
|
|
6052
|
+
emitDiagnostics(0);
|
|
5918
6053
|
return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
|
|
5919
6054
|
}
|
|
5920
6055
|
const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
|
|
5921
6056
|
const wantsTemporal = types.includes("fact") && ctx.vaultCtx;
|
|
6057
|
+
const prepStart = nowMs();
|
|
5922
6058
|
const [queryEmbedding, entityRanking, temporalRanking] = await Promise.all([
|
|
5923
6059
|
needsChunkEmbedding ? generateEmbedding(query, ctx.embeddingOptions) : Promise.resolve(void 0),
|
|
5924
6060
|
buildGraphLaneRanking(query, ctx),
|
|
5925
6061
|
wantsTemporal ? buildTemporalLaneRanking(query, ctx.vaultCtx, options.now) : Promise.resolve([])
|
|
5926
6062
|
]);
|
|
5927
|
-
|
|
5928
|
-
const chunkResults = [];
|
|
5929
|
-
let vaultSize;
|
|
6063
|
+
prepMs = nowMs() - prepStart;
|
|
5930
6064
|
if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
|
|
6065
|
+
const factStart = nowMs();
|
|
5931
6066
|
const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
|
|
5932
|
-
const {
|
|
6067
|
+
const {
|
|
6068
|
+
results,
|
|
6069
|
+
vaultSize: size,
|
|
6070
|
+
reranked,
|
|
6071
|
+
hadV2Head: v2Head
|
|
6072
|
+
} = await searchVaultMemoriesWithSize(
|
|
5933
6073
|
query,
|
|
5934
6074
|
ctx.vaultCtx,
|
|
5935
6075
|
ctx.embeddingOptions,
|
|
@@ -5980,14 +6120,19 @@ async function recall(query, ctx, options = {}) {
|
|
|
5980
6120
|
)
|
|
5981
6121
|
);
|
|
5982
6122
|
vaultSize = size;
|
|
6123
|
+
didRerank = reranked;
|
|
6124
|
+
hadV2Head = v2Head;
|
|
6125
|
+
factLaneMs = nowMs() - factStart;
|
|
5983
6126
|
}
|
|
5984
6127
|
if (types.includes("chunk") && ctx.storageCtx && queryEmbedding) {
|
|
6128
|
+
const chunkStart = nowMs();
|
|
5985
6129
|
const chunkMinScore = options.minScore ?? DEFAULT_CHUNK_MIN_SCORE;
|
|
5986
6130
|
const results = await searchChunksOp(ctx.storageCtx, queryEmbedding, {
|
|
5987
6131
|
limit: types.includes("fact") ? Math.max(limit * 2, 16) : limit,
|
|
5988
6132
|
minSimilarity: chunkMinScore,
|
|
5989
6133
|
embeddingModel: ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL,
|
|
5990
|
-
...options.conversationId && { conversationId: options.conversationId }
|
|
6134
|
+
...options.conversationId && { conversationId: options.conversationId },
|
|
6135
|
+
...ctx.chunkCache && { chunkCache: ctx.chunkCache }
|
|
5991
6136
|
});
|
|
5992
6137
|
chunkResults.push(
|
|
5993
6138
|
...dedupeBy(
|
|
@@ -5997,18 +6142,23 @@ async function recall(query, ctx, options = {}) {
|
|
|
5997
6142
|
(r) => r.chunkText.trim()
|
|
5998
6143
|
)
|
|
5999
6144
|
);
|
|
6145
|
+
chunkLaneMs = nowMs() - chunkStart;
|
|
6000
6146
|
}
|
|
6147
|
+
const fuseStart = nowMs();
|
|
6001
6148
|
if (types.length === 1 || factResults.length === 0 || chunkResults.length === 0) {
|
|
6002
6149
|
const memories2 = [
|
|
6003
6150
|
...factResults.map(toFactMemory),
|
|
6004
6151
|
...chunkResults.map(toChunkMemory)
|
|
6005
6152
|
];
|
|
6006
6153
|
memories2.sort((a, b) => b.score - a.score);
|
|
6154
|
+
const candidateCount = factResults.length + chunkResults.length;
|
|
6155
|
+
fuseMs = nowMs() - fuseStart;
|
|
6156
|
+
emitDiagnostics(candidateCount);
|
|
6007
6157
|
return {
|
|
6008
6158
|
memories: memories2.slice(0, limit),
|
|
6009
6159
|
usedBudget,
|
|
6010
|
-
reranked:
|
|
6011
|
-
candidateCount
|
|
6160
|
+
reranked: didRerank,
|
|
6161
|
+
candidateCount,
|
|
6012
6162
|
...vaultSize !== void 0 && { vaultSize }
|
|
6013
6163
|
};
|
|
6014
6164
|
}
|
|
@@ -6057,10 +6207,12 @@ async function recall(query, ctx, options = {}) {
|
|
|
6057
6207
|
suppressed = next;
|
|
6058
6208
|
memories = selectWith(suppressed);
|
|
6059
6209
|
}
|
|
6210
|
+
fuseMs = nowMs() - fuseStart;
|
|
6211
|
+
emitDiagnostics(byId.size);
|
|
6060
6212
|
return {
|
|
6061
6213
|
memories,
|
|
6062
6214
|
usedBudget,
|
|
6063
|
-
reranked:
|
|
6215
|
+
reranked: didRerank,
|
|
6064
6216
|
candidateCount: byId.size,
|
|
6065
6217
|
...vaultSize !== void 0 && { vaultSize }
|
|
6066
6218
|
};
|
|
@@ -6124,7 +6276,7 @@ function toChunkMemory(r) {
|
|
|
6124
6276
|
updatedAt: r.message.createdAt
|
|
6125
6277
|
};
|
|
6126
6278
|
}
|
|
6127
|
-
var DEFAULT_LIMIT, DEFAULT_BUDGET, DEFAULT_FACT_MIN_SCORE, DEFAULT_CHUNK_MIN_SCORE;
|
|
6279
|
+
var DEFAULT_LIMIT, DEFAULT_BUDGET, DEFAULT_FACT_MIN_SCORE, nowMs, DEFAULT_CHUNK_MIN_SCORE;
|
|
6128
6280
|
var init_recall = __esm({
|
|
6129
6281
|
"src/lib/memory/recall.ts"() {
|
|
6130
6282
|
"use strict";
|
|
@@ -6140,6 +6292,7 @@ var init_recall = __esm({
|
|
|
6140
6292
|
DEFAULT_LIMIT = 8;
|
|
6141
6293
|
DEFAULT_BUDGET = "low";
|
|
6142
6294
|
DEFAULT_FACT_MIN_SCORE = 0.1;
|
|
6295
|
+
nowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
6143
6296
|
DEFAULT_CHUNK_MIN_SCORE = 0.5;
|
|
6144
6297
|
}
|
|
6145
6298
|
});
|
|
@@ -6339,6 +6492,9 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
6339
6492
|
bm25AdmissionDivisor: options?.bm25AdmissionDivisor,
|
|
6340
6493
|
rrfK: options?.rrfK
|
|
6341
6494
|
});
|
|
6495
|
+
if (options?.v2HeadStats) {
|
|
6496
|
+
options.v2HeadStats.hadResults = v2Ranked.length > 0;
|
|
6497
|
+
}
|
|
6342
6498
|
let combined;
|
|
6343
6499
|
let tailSlice = [];
|
|
6344
6500
|
if (options?.rerank) {
|
|
@@ -6359,8 +6515,13 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
6359
6515
|
return { ...r, similarity: v2 * (1 + ceWeight * ce) };
|
|
6360
6516
|
});
|
|
6361
6517
|
combined.sort((a, b) => b.similarity - a.similarity);
|
|
6518
|
+
if (headSlice.length > 0 && options.rerankStats) options.rerankStats.applied = true;
|
|
6362
6519
|
} catch (err) {
|
|
6363
|
-
|
|
6520
|
+
if (err instanceof RerankerUnavailableError) {
|
|
6521
|
+
getLogger().debug("[memory/search] cross-encoder unavailable; using V2 ranking");
|
|
6522
|
+
} else {
|
|
6523
|
+
getLogger().warn("[memory/search] cross-encoder rerank failed; using V2 ranking", err);
|
|
6524
|
+
}
|
|
6364
6525
|
combined = v2Ranked;
|
|
6365
6526
|
}
|
|
6366
6527
|
} else {
|
|
@@ -6494,6 +6655,9 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
6494
6655
|
(r) => r !== null
|
|
6495
6656
|
);
|
|
6496
6657
|
combined.sort((a, b) => b.similarity - a.similarity);
|
|
6658
|
+
if (options?.v2HeadStats) {
|
|
6659
|
+
options.v2HeadStats.hadResults = combined.length > 0;
|
|
6660
|
+
}
|
|
6497
6661
|
if (options?.includeUnrankedTail) {
|
|
6498
6662
|
const fusedIds = new Set(combined.map((r) => r.uniqueId));
|
|
6499
6663
|
for (const item of items) {
|
|
@@ -6529,11 +6693,16 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
6529
6693
|
}));
|
|
6530
6694
|
head.sort((a, b) => b.similarity - a.similarity);
|
|
6531
6695
|
combined = [...head, ...tailSlice];
|
|
6696
|
+
if (headSlice.length > 0 && options.rerankStats) options.rerankStats.applied = true;
|
|
6532
6697
|
} catch (err) {
|
|
6533
|
-
|
|
6534
|
-
"[memory/search]
|
|
6535
|
-
|
|
6536
|
-
|
|
6698
|
+
if (err instanceof RerankerUnavailableError) {
|
|
6699
|
+
getLogger().debug("[memory/search] cross-encoder unavailable; using fused ranking");
|
|
6700
|
+
} else {
|
|
6701
|
+
getLogger().warn(
|
|
6702
|
+
"[memory/search] composite cross-encoder rerank failed; using fused ranking",
|
|
6703
|
+
err
|
|
6704
|
+
);
|
|
6705
|
+
}
|
|
6537
6706
|
}
|
|
6538
6707
|
}
|
|
6539
6708
|
if (options?.mmr) {
|
|
@@ -6625,7 +6794,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6625
6794
|
const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
|
|
6626
6795
|
const scopes = searchOptions?.scopes;
|
|
6627
6796
|
if (!query || typeof query !== "string") {
|
|
6628
|
-
return { results: [], vaultSize: 0 };
|
|
6797
|
+
return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
|
|
6629
6798
|
}
|
|
6630
6799
|
const folderId = searchOptions?.folderId;
|
|
6631
6800
|
const queryOpts = {};
|
|
@@ -6642,7 +6811,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6642
6811
|
);
|
|
6643
6812
|
}
|
|
6644
6813
|
if (memories.length === 0) {
|
|
6645
|
-
return { results: [], vaultSize: loaded.length };
|
|
6814
|
+
return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
|
|
6646
6815
|
}
|
|
6647
6816
|
const queryEmbedding = await generateEmbedding(query, embeddingOptions);
|
|
6648
6817
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
@@ -6718,12 +6887,18 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6718
6887
|
memories.map((m) => [m.uniqueId, { createdAt: m.createdAt, updatedAt: m.updatedAt }])
|
|
6719
6888
|
);
|
|
6720
6889
|
const stampTimestamps = (out) => {
|
|
6721
|
-
|
|
6890
|
+
const results2 = out.results.map((r) => {
|
|
6722
6891
|
const ts = timestampById.get(r.uniqueId);
|
|
6723
6892
|
return ts ? { ...r, createdAt: ts.createdAt, updatedAt: ts.updatedAt } : r;
|
|
6724
6893
|
});
|
|
6725
|
-
return
|
|
6894
|
+
return {
|
|
6895
|
+
results: results2,
|
|
6896
|
+
vaultSize: out.vaultSize,
|
|
6897
|
+
reranked: out.reranked ?? false,
|
|
6898
|
+
hadV2Head: out.hadV2Head ?? false
|
|
6899
|
+
};
|
|
6726
6900
|
};
|
|
6901
|
+
const rerankStats = { applied: false };
|
|
6727
6902
|
const useFusion = searchOptions?.useFusion ?? true;
|
|
6728
6903
|
const tuning = {
|
|
6729
6904
|
...searchOptions?.recencyAlpha !== void 0 && { recencyAlpha: searchOptions.recencyAlpha },
|
|
@@ -6750,6 +6925,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6750
6925
|
query: sq,
|
|
6751
6926
|
embedding: subEmbeddings[i]
|
|
6752
6927
|
}));
|
|
6928
|
+
const v2HeadStats = { hadResults: false };
|
|
6753
6929
|
const composite = await rankComposite(query, queryEmbedding, subQueries, embeddedItems, {
|
|
6754
6930
|
limit,
|
|
6755
6931
|
minSimilarity,
|
|
@@ -6761,12 +6937,20 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6761
6937
|
...searchOptions.mmr !== void 0 && { mmr: searchOptions.mmr },
|
|
6762
6938
|
...tuning,
|
|
6763
6939
|
...searchOptions.entityRanking && { entityRanking: searchOptions.entityRanking },
|
|
6764
|
-
...searchOptions.temporalRanking && { temporalRanking: searchOptions.temporalRanking }
|
|
6940
|
+
...searchOptions.temporalRanking && { temporalRanking: searchOptions.temporalRanking },
|
|
6941
|
+
rerankStats,
|
|
6942
|
+
v2HeadStats
|
|
6943
|
+
});
|
|
6944
|
+
return stampTimestamps({
|
|
6945
|
+
results: composite,
|
|
6946
|
+
vaultSize: loaded.length,
|
|
6947
|
+
reranked: rerankStats.applied,
|
|
6948
|
+
hadV2Head: v2HeadStats.hadResults
|
|
6765
6949
|
});
|
|
6766
|
-
return stampTimestamps({ results: composite, vaultSize: loaded.length });
|
|
6767
6950
|
}
|
|
6768
6951
|
}
|
|
6769
6952
|
if (useFusion && searchOptions?.rerank) {
|
|
6953
|
+
const v2HeadStats = { hadResults: false };
|
|
6770
6954
|
const results2 = await rankFusedVaultMemoriesAsync(query, queryEmbedding, embeddedItems, {
|
|
6771
6955
|
limit,
|
|
6772
6956
|
minSimilarity,
|
|
@@ -6778,9 +6962,16 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6778
6962
|
...searchOptions.mmr !== void 0 && { mmr: searchOptions.mmr },
|
|
6779
6963
|
...tuning,
|
|
6780
6964
|
...searchOptions.entityRanking && { entityRanking: searchOptions.entityRanking },
|
|
6781
|
-
...searchOptions.temporalRanking && { temporalRanking: searchOptions.temporalRanking }
|
|
6965
|
+
...searchOptions.temporalRanking && { temporalRanking: searchOptions.temporalRanking },
|
|
6966
|
+
rerankStats,
|
|
6967
|
+
v2HeadStats
|
|
6968
|
+
});
|
|
6969
|
+
return stampTimestamps({
|
|
6970
|
+
results: results2,
|
|
6971
|
+
vaultSize: loaded.length,
|
|
6972
|
+
reranked: rerankStats.applied,
|
|
6973
|
+
hadV2Head: v2HeadStats.hadResults
|
|
6782
6974
|
});
|
|
6783
|
-
return stampTimestamps({ results: results2, vaultSize: loaded.length });
|
|
6784
6975
|
}
|
|
6785
6976
|
if (useFusion) {
|
|
6786
6977
|
const results2 = rankFusedVaultMemories(query, queryEmbedding, embeddedItems, {
|
|
@@ -6790,7 +6981,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6790
6981
|
...searchOptions?.entityRanking && { entityRanking: searchOptions.entityRanking },
|
|
6791
6982
|
...searchOptions?.temporalRanking && { temporalRanking: searchOptions.temporalRanking }
|
|
6792
6983
|
});
|
|
6793
|
-
return stampTimestamps({ results: results2, vaultSize: loaded.length });
|
|
6984
|
+
return stampTimestamps({ results: results2, vaultSize: loaded.length, hadV2Head: results2.length > 0 });
|
|
6794
6985
|
}
|
|
6795
6986
|
const results = rankVaultMemories(query, queryEmbedding, embeddedItems, {
|
|
6796
6987
|
limit,
|
|
@@ -6802,7 +6993,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6802
6993
|
supersessionWindow: searchOptions.supersessionWindow
|
|
6803
6994
|
}
|
|
6804
6995
|
});
|
|
6805
|
-
return stampTimestamps({ results, vaultSize: loaded.length });
|
|
6996
|
+
return stampTimestamps({ results, vaultSize: loaded.length, hadV2Head: results.length > 0 });
|
|
6806
6997
|
}
|
|
6807
6998
|
async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
|
|
6808
6999
|
const { results } = await searchVaultMemoriesWithSize(
|
|
@@ -7118,6 +7309,7 @@ __export(index_exports, {
|
|
|
7118
7309
|
ConversationMemoryModel: () => ConversationMemory,
|
|
7119
7310
|
DEFAULT_BACKUP_FOLDER: () => DEFAULT_BACKUP_FOLDER,
|
|
7120
7311
|
DEFAULT_CACHE_EXPIRATION_MS: () => DEFAULT_CACHE_EXPIRATION_MS,
|
|
7312
|
+
DEFAULT_CHUNK_CACHE_SIZE: () => DEFAULT_CHUNK_CACHE_SIZE,
|
|
7121
7313
|
DEFAULT_CHUNK_OVERLAP: () => DEFAULT_CHUNK_OVERLAP,
|
|
7122
7314
|
DEFAULT_CHUNK_SIZE: () => DEFAULT_CHUNK_SIZE,
|
|
7123
7315
|
DEFAULT_DRIVE_CONVERSATIONS_FOLDER: () => DEFAULT_CONVERSATIONS_FOLDER,
|
|
@@ -7149,6 +7341,7 @@ __export(index_exports, {
|
|
|
7149
7341
|
R2_DEFAULT_TTL_MS: () => R2_DEFAULT_TTL_MS,
|
|
7150
7342
|
RECALL_MAX_LIMIT: () => RECALL_MAX_LIMIT,
|
|
7151
7343
|
RECALL_TOOL_NAME: () => RECALL_TOOL_NAME,
|
|
7344
|
+
RerankerUnavailableError: () => RerankerUnavailableError,
|
|
7152
7345
|
SDK_SCHEMA_VERSION: () => SDK_SCHEMA_VERSION,
|
|
7153
7346
|
SERVER_TOOL_DEPENDENCY_SETS: () => SERVER_TOOL_DEPENDENCY_SETS,
|
|
7154
7347
|
SLIDER_CONFIG: () => SLIDER_CONFIG,
|
|
@@ -7207,6 +7400,7 @@ __export(index_exports, {
|
|
|
7207
7400
|
conversationMemoryToStored: () => conversationMemoryToStored,
|
|
7208
7401
|
cosineInt8: () => cosineInt8,
|
|
7209
7402
|
createAutoExtractor: () => createAutoExtractor,
|
|
7403
|
+
createChunkVectorCache: () => createChunkVectorCache,
|
|
7210
7404
|
createCryptoPricePreProcessor: () => createCryptoPricePreProcessor,
|
|
7211
7405
|
createGitHubTools: () => createGitHubTools,
|
|
7212
7406
|
createMediaBatchOp: () => createMediaBatchOp,
|
|
@@ -7362,6 +7556,7 @@ __export(index_exports, {
|
|
|
7362
7556
|
isNotionCallback: () => isNotionCallback,
|
|
7363
7557
|
isOPFSSupported: () => isOPFSSupported,
|
|
7364
7558
|
isR2UrlExpired: () => isR2UrlExpired,
|
|
7559
|
+
isRerankerAvailable: () => isRerankerAvailable,
|
|
7365
7560
|
isSupportedFile: () => isSupportedFile,
|
|
7366
7561
|
isSupportedMediaType: () => isSupportedMediaType,
|
|
7367
7562
|
linkMemoryEntitiesOp: () => linkMemoryEntitiesOp,
|
|
@@ -14811,6 +15006,13 @@ function createAutoExtractor(options) {
|
|
|
14811
15006
|
};
|
|
14812
15007
|
}
|
|
14813
15008
|
|
|
15009
|
+
// src/lib/memory/chunkVectorCache.ts
|
|
15010
|
+
init_lruCache();
|
|
15011
|
+
var DEFAULT_CHUNK_CACHE_SIZE = 5e3;
|
|
15012
|
+
function createChunkVectorCache(maxSize = DEFAULT_CHUNK_CACHE_SIZE) {
|
|
15013
|
+
return new LRUCache(maxSize);
|
|
15014
|
+
}
|
|
15015
|
+
|
|
14814
15016
|
// src/lib/memory/index.ts
|
|
14815
15017
|
init_recall();
|
|
14816
15018
|
|
|
@@ -15075,6 +15277,9 @@ function parseAnswer(body, base, parseSchema) {
|
|
|
15075
15277
|
};
|
|
15076
15278
|
}
|
|
15077
15279
|
|
|
15280
|
+
// src/lib/memory/index.ts
|
|
15281
|
+
init_reranker();
|
|
15282
|
+
|
|
15078
15283
|
// src/lib/memory/topicExtract.ts
|
|
15079
15284
|
init_operations2();
|
|
15080
15285
|
init_operations3();
|
|
@@ -18215,6 +18420,7 @@ function useChatStorage(options) {
|
|
|
18215
18420
|
[vaultCtx]
|
|
18216
18421
|
);
|
|
18217
18422
|
const vaultEmbeddingCacheRef = (0, import_react5.useRef)(createVaultEmbeddingCache());
|
|
18423
|
+
const chunkVectorCacheRef = (0, import_react5.useRef)(createChunkVectorCache());
|
|
18218
18424
|
const clientToolEmbeddingsCacheRef = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
|
|
18219
18425
|
(0, import_react5.useEffect)(() => {
|
|
18220
18426
|
if (!getToken) return;
|
|
@@ -18230,7 +18436,10 @@ function useChatStorage(options) {
|
|
|
18230
18436
|
})();
|
|
18231
18437
|
}, [vaultCtx, getToken, vaultEmbeddingOptions]);
|
|
18232
18438
|
(0, import_react5.useEffect)(() => {
|
|
18233
|
-
return onClearAllEncryptionState(() =>
|
|
18439
|
+
return onClearAllEncryptionState(() => {
|
|
18440
|
+
vaultEmbeddingCacheRef.current.clear();
|
|
18441
|
+
chunkVectorCacheRef.current.clear();
|
|
18442
|
+
});
|
|
18234
18443
|
}, []);
|
|
18235
18444
|
const createMemoryVaultSearchTool2 = (0, import_react5.useCallback)(
|
|
18236
18445
|
(searchOptions) => {
|
|
@@ -18258,6 +18467,7 @@ function useChatStorage(options) {
|
|
|
18258
18467
|
storageCtx,
|
|
18259
18468
|
embeddingOptions: vaultEmbeddingOptions,
|
|
18260
18469
|
vaultCache: vaultEmbeddingCacheRef.current,
|
|
18470
|
+
chunkCache: chunkVectorCacheRef.current,
|
|
18261
18471
|
// Graph lane fires when entityCtx is present and the query
|
|
18262
18472
|
// contains extractable entities. Empty memory_entity (e.g.
|
|
18263
18473
|
// before any auto-extraction linked entities) is a graceful
|
|
@@ -18305,6 +18515,7 @@ function useChatStorage(options) {
|
|
|
18305
18515
|
// would embed the raw query (often containing the user's PII).
|
|
18306
18516
|
embeddingOptions: vaultEmbeddingOptions,
|
|
18307
18517
|
vaultCache: vaultEmbeddingCacheRef.current,
|
|
18518
|
+
chunkCache: chunkVectorCacheRef.current,
|
|
18308
18519
|
// Graph lane fires only when entityCtx is present and the query
|
|
18309
18520
|
// has extractable entities; empty memory_entity is a graceful
|
|
18310
18521
|
// no-op (falls through to fact + chunk lanes). Mirrors createRecallTool.
|
|
@@ -29974,6 +30185,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
29974
30185
|
ConversationMemoryModel,
|
|
29975
30186
|
DEFAULT_BACKUP_FOLDER,
|
|
29976
30187
|
DEFAULT_CACHE_EXPIRATION_MS,
|
|
30188
|
+
DEFAULT_CHUNK_CACHE_SIZE,
|
|
29977
30189
|
DEFAULT_CHUNK_OVERLAP,
|
|
29978
30190
|
DEFAULT_CHUNK_SIZE,
|
|
29979
30191
|
DEFAULT_DRIVE_CONVERSATIONS_FOLDER,
|
|
@@ -30005,6 +30217,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
30005
30217
|
R2_DEFAULT_TTL_MS,
|
|
30006
30218
|
RECALL_MAX_LIMIT,
|
|
30007
30219
|
RECALL_TOOL_NAME,
|
|
30220
|
+
RerankerUnavailableError,
|
|
30008
30221
|
SDK_SCHEMA_VERSION,
|
|
30009
30222
|
SERVER_TOOL_DEPENDENCY_SETS,
|
|
30010
30223
|
SLIDER_CONFIG,
|
|
@@ -30063,6 +30276,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
30063
30276
|
conversationMemoryToStored,
|
|
30064
30277
|
cosineInt8,
|
|
30065
30278
|
createAutoExtractor,
|
|
30279
|
+
createChunkVectorCache,
|
|
30066
30280
|
createCryptoPricePreProcessor,
|
|
30067
30281
|
createGitHubTools,
|
|
30068
30282
|
createMediaBatchOp,
|
|
@@ -30218,6 +30432,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
30218
30432
|
isNotionCallback,
|
|
30219
30433
|
isOPFSSupported,
|
|
30220
30434
|
isR2UrlExpired,
|
|
30435
|
+
isRerankerAvailable,
|
|
30221
30436
|
isSupportedFile,
|
|
30222
30437
|
isSupportedMediaType,
|
|
30223
30438
|
linkMemoryEntitiesOp,
|