@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/expo/index.cjs
CHANGED
|
@@ -2543,7 +2543,13 @@ async function readJsonField(model, column, walletAddress) {
|
|
|
2543
2543
|
}
|
|
2544
2544
|
}
|
|
2545
2545
|
async function searchChunksOp(ctx, queryVector, options) {
|
|
2546
|
-
const {
|
|
2546
|
+
const {
|
|
2547
|
+
limit = 10,
|
|
2548
|
+
minSimilarity = 0.5,
|
|
2549
|
+
conversationId,
|
|
2550
|
+
embeddingModel,
|
|
2551
|
+
chunkCache
|
|
2552
|
+
} = options || {};
|
|
2547
2553
|
const activeConversations = await ctx.conversationsCollection.query(import_watermelondb.Q.where("is_deleted", false)).fetch();
|
|
2548
2554
|
const activeConversationIds = new Set(
|
|
2549
2555
|
// Use _getRaw for reliable raw column access
|
|
@@ -2563,23 +2569,54 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
2563
2569
|
continue;
|
|
2564
2570
|
}
|
|
2565
2571
|
}
|
|
2572
|
+
const version = Number(message._getRaw("updated_at")) || 0;
|
|
2573
|
+
const cached = chunkCache?.get(message.id);
|
|
2574
|
+
if (cached && cached.version === version) {
|
|
2575
|
+
if (cached.chunks.length > 0) {
|
|
2576
|
+
for (let ci = 0; ci < cached.chunks.length; ci++) {
|
|
2577
|
+
const vec = cached.chunks[ci];
|
|
2578
|
+
if (vec.length === 0) continue;
|
|
2579
|
+
const similarity = cosineSimilarity(queryVector, vec);
|
|
2580
|
+
if (similarity >= minSimilarity) {
|
|
2581
|
+
candidates.push({
|
|
2582
|
+
message,
|
|
2583
|
+
similarity,
|
|
2584
|
+
chunkTextSource: { kind: "chunk-cached", chunkIndex: ci, version }
|
|
2585
|
+
});
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
} else if (cached.fallback) {
|
|
2589
|
+
const similarity = cosineSimilarity(queryVector, cached.fallback);
|
|
2590
|
+
if (similarity >= minSimilarity) {
|
|
2591
|
+
candidates.push({ message, similarity, chunkTextSource: { kind: "message" } });
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
continue;
|
|
2595
|
+
}
|
|
2566
2596
|
const chunks = await readJsonField(message, "chunks", ctx.walletAddress);
|
|
2567
2597
|
if (chunks && chunks.length > 0) {
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2598
|
+
const vectors = chunks.map(
|
|
2599
|
+
(chunk) => chunk.vector && chunk.vector.length > 0 ? Float32Array.from(chunk.vector) : new Float32Array(0)
|
|
2600
|
+
);
|
|
2601
|
+
chunkCache?.set(message.id, { version, chunks: vectors });
|
|
2602
|
+
for (let ci = 0; ci < chunks.length; ci++) {
|
|
2603
|
+
const vec = vectors[ci];
|
|
2604
|
+
if (vec.length === 0) continue;
|
|
2605
|
+
const similarity = cosineSimilarity(queryVector, vec);
|
|
2571
2606
|
if (similarity >= minSimilarity) {
|
|
2572
2607
|
candidates.push({
|
|
2573
2608
|
message,
|
|
2574
2609
|
similarity,
|
|
2575
|
-
chunkTextSource: { kind: "chunk", text:
|
|
2610
|
+
chunkTextSource: { kind: "chunk", text: chunks[ci].text }
|
|
2576
2611
|
});
|
|
2577
2612
|
}
|
|
2578
2613
|
}
|
|
2579
2614
|
} else {
|
|
2580
2615
|
const messageVector = await readJsonField(message, "vector", ctx.walletAddress);
|
|
2581
2616
|
if (!messageVector || messageVector.length === 0) continue;
|
|
2582
|
-
const
|
|
2617
|
+
const fallback = Float32Array.from(messageVector);
|
|
2618
|
+
chunkCache?.set(message.id, { version, chunks: [], fallback });
|
|
2619
|
+
const similarity = cosineSimilarity(queryVector, fallback);
|
|
2583
2620
|
if (similarity >= minSimilarity) {
|
|
2584
2621
|
candidates.push({ message, similarity, chunkTextSource: { kind: "message" } });
|
|
2585
2622
|
}
|
|
@@ -2606,9 +2643,31 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
2606
2643
|
})
|
|
2607
2644
|
)
|
|
2608
2645
|
);
|
|
2646
|
+
const chunkStateByMsgId = /* @__PURE__ */ new Map();
|
|
2647
|
+
const needsChunkText = /* @__PURE__ */ new Set();
|
|
2648
|
+
for (const c of topK) {
|
|
2649
|
+
if (c.chunkTextSource.kind === "chunk-cached") needsChunkText.add(c.message.id);
|
|
2650
|
+
}
|
|
2651
|
+
await Promise.all(
|
|
2652
|
+
Array.from(needsChunkText, async (id) => {
|
|
2653
|
+
const m = uniqueMessages.get(id);
|
|
2654
|
+
const parsed = await readJsonField(m, "chunks", ctx.walletAddress);
|
|
2655
|
+
const version = Number(m._getRaw("updated_at")) || 0;
|
|
2656
|
+
if (parsed) chunkStateByMsgId.set(id, { version, chunks: parsed });
|
|
2657
|
+
})
|
|
2658
|
+
);
|
|
2609
2659
|
return topK.map(({ message, similarity, chunkTextSource }) => {
|
|
2610
2660
|
const stored = { ...storedById.get(message.id) };
|
|
2611
|
-
|
|
2661
|
+
let chunkText2;
|
|
2662
|
+
if (chunkTextSource.kind === "chunk") {
|
|
2663
|
+
chunkText2 = chunkTextSource.text;
|
|
2664
|
+
} else if (chunkTextSource.kind === "chunk-cached") {
|
|
2665
|
+
const state = chunkStateByMsgId.get(message.id);
|
|
2666
|
+
const chunk = state && state.version === chunkTextSource.version ? state.chunks[chunkTextSource.chunkIndex] : void 0;
|
|
2667
|
+
chunkText2 = chunk?.text ?? stored.content;
|
|
2668
|
+
} else {
|
|
2669
|
+
chunkText2 = stored.content;
|
|
2670
|
+
}
|
|
2612
2671
|
return { chunkText: chunkText2, message: stored, similarity };
|
|
2613
2672
|
});
|
|
2614
2673
|
}
|
|
@@ -4840,9 +4899,9 @@ function recencyMultiplier(updatedAt, opts = {}) {
|
|
|
4840
4899
|
const updatedMs = updatedAt.getTime();
|
|
4841
4900
|
if (!Number.isFinite(updatedMs)) return noDate;
|
|
4842
4901
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
4843
|
-
const
|
|
4844
|
-
if (!Number.isFinite(
|
|
4845
|
-
const ageDays = Math.max(0, (
|
|
4902
|
+
const nowMs2 = now.getTime();
|
|
4903
|
+
if (!Number.isFinite(nowMs2)) return noDate;
|
|
4904
|
+
const ageDays = Math.max(0, (nowMs2 - updatedMs) / DAY_MS);
|
|
4846
4905
|
const perYearDecay = opts.perYearDecay ?? DEFAULT_PER_YEAR_DECAY;
|
|
4847
4906
|
const floor = opts.floor ?? DEFAULT_FLOOR;
|
|
4848
4907
|
const decay = perYearDecay * (ageDays / 365);
|
|
@@ -4860,14 +4919,42 @@ var init_recency = __esm({
|
|
|
4860
4919
|
});
|
|
4861
4920
|
|
|
4862
4921
|
// src/lib/memory/reranker.ts
|
|
4922
|
+
function isRerankerAvailable() {
|
|
4923
|
+
return available;
|
|
4924
|
+
}
|
|
4925
|
+
function isModuleMissing(err) {
|
|
4926
|
+
let e = err;
|
|
4927
|
+
for (let depth = 0; depth < 5 && e !== null && e !== void 0; depth++) {
|
|
4928
|
+
const code = e.code;
|
|
4929
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true;
|
|
4930
|
+
if (e instanceof Error && /cannot find (module|package)|failed to resolve|unable to resolve module|requiring unknown module/i.test(
|
|
4931
|
+
e.message
|
|
4932
|
+
)) {
|
|
4933
|
+
return true;
|
|
4934
|
+
}
|
|
4935
|
+
e = e.cause;
|
|
4936
|
+
}
|
|
4937
|
+
return false;
|
|
4938
|
+
}
|
|
4863
4939
|
async function getModel() {
|
|
4940
|
+
if (available === false) throw new RerankerUnavailableError(void 0);
|
|
4864
4941
|
if (!modelPromise) {
|
|
4865
4942
|
const load = (async () => {
|
|
4866
|
-
|
|
4943
|
+
let transformers;
|
|
4944
|
+
try {
|
|
4945
|
+
transformers = await import("@huggingface/transformers");
|
|
4946
|
+
} catch (err) {
|
|
4947
|
+
if (isModuleMissing(err)) {
|
|
4948
|
+
available = false;
|
|
4949
|
+
throw new RerankerUnavailableError(err);
|
|
4950
|
+
}
|
|
4951
|
+
throw err;
|
|
4952
|
+
}
|
|
4867
4953
|
const [tokenizer, model] = await Promise.all([
|
|
4868
4954
|
transformers.AutoTokenizer.from_pretrained(MODEL_ID),
|
|
4869
4955
|
transformers.AutoModelForSequenceClassification.from_pretrained(MODEL_ID)
|
|
4870
4956
|
]);
|
|
4957
|
+
available = true;
|
|
4871
4958
|
return { tokenizer, model };
|
|
4872
4959
|
})();
|
|
4873
4960
|
modelPromise = load;
|
|
@@ -4909,11 +4996,19 @@ async function rerankPairs(query, items) {
|
|
|
4909
4996
|
}
|
|
4910
4997
|
return items.map((item, i) => ({ id: item.id, content: item.content, score: scores[i] })).sort((a, b) => b.score - a.score);
|
|
4911
4998
|
}
|
|
4912
|
-
var MODEL_ID, modelPromise;
|
|
4999
|
+
var MODEL_ID, RerankerUnavailableError, available, modelPromise;
|
|
4913
5000
|
var init_reranker = __esm({
|
|
4914
5001
|
"src/lib/memory/reranker.ts"() {
|
|
4915
5002
|
"use strict";
|
|
4916
5003
|
MODEL_ID = "Xenova/ms-marco-MiniLM-L-6-v2";
|
|
5004
|
+
RerankerUnavailableError = class extends Error {
|
|
5005
|
+
constructor(reason) {
|
|
5006
|
+
super("cross-encoder reranker unavailable (@huggingface/transformers not installed)");
|
|
5007
|
+
this.name = "RerankerUnavailableError";
|
|
5008
|
+
this.reason = reason;
|
|
5009
|
+
}
|
|
5010
|
+
};
|
|
5011
|
+
available = void 0;
|
|
4917
5012
|
modelPromise = null;
|
|
4918
5013
|
}
|
|
4919
5014
|
});
|
|
@@ -5582,22 +5677,67 @@ async function recall(query, ctx, options = {}) {
|
|
|
5582
5677
|
const flags = flagsForBudget(requestedBudget);
|
|
5583
5678
|
const decomposeAvailable = flags.decompose && !!options.decomposeOptions;
|
|
5584
5679
|
const usedBudget = requestedBudget === "high" && !decomposeAvailable ? "mid" : requestedBudget;
|
|
5680
|
+
const t0 = nowMs();
|
|
5681
|
+
let prepMs = 0;
|
|
5682
|
+
let factLaneMs = 0;
|
|
5683
|
+
let chunkLaneMs = 0;
|
|
5684
|
+
let fuseMs = 0;
|
|
5685
|
+
const factResults = [];
|
|
5686
|
+
const chunkResults = [];
|
|
5687
|
+
let vaultSize;
|
|
5688
|
+
let didRerank = false;
|
|
5689
|
+
let hadV2Head = false;
|
|
5690
|
+
const emitDiagnostics = (candidateCount) => {
|
|
5691
|
+
const cb = options.onDiagnostics;
|
|
5692
|
+
if (!cb) return;
|
|
5693
|
+
const degraded = [];
|
|
5694
|
+
if (flags.rerank && factResults.length > 0 && hadV2Head && !didRerank) {
|
|
5695
|
+
degraded.push("rerank-unavailable");
|
|
5696
|
+
}
|
|
5697
|
+
if (flags.decompose && !decomposeAvailable) degraded.push("decompose-unavailable");
|
|
5698
|
+
const diagnostics = {
|
|
5699
|
+
usedBudget,
|
|
5700
|
+
reranked: didRerank,
|
|
5701
|
+
candidateCount,
|
|
5702
|
+
...vaultSize !== void 0 && { vaultSize },
|
|
5703
|
+
factCount: factResults.length,
|
|
5704
|
+
chunkCount: chunkResults.length,
|
|
5705
|
+
timings: {
|
|
5706
|
+
total: nowMs() - t0,
|
|
5707
|
+
prep: prepMs,
|
|
5708
|
+
factLane: factLaneMs,
|
|
5709
|
+
chunkLane: chunkLaneMs,
|
|
5710
|
+
fuse: fuseMs
|
|
5711
|
+
},
|
|
5712
|
+
degraded
|
|
5713
|
+
};
|
|
5714
|
+
try {
|
|
5715
|
+
cb(diagnostics);
|
|
5716
|
+
} catch {
|
|
5717
|
+
}
|
|
5718
|
+
};
|
|
5585
5719
|
if (!query || typeof query !== "string" || query.trim().length === 0) {
|
|
5720
|
+
emitDiagnostics(0);
|
|
5586
5721
|
return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
|
|
5587
5722
|
}
|
|
5588
5723
|
const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
|
|
5589
5724
|
const wantsTemporal = types.includes("fact") && ctx.vaultCtx;
|
|
5725
|
+
const prepStart = nowMs();
|
|
5590
5726
|
const [queryEmbedding, entityRanking, temporalRanking] = await Promise.all([
|
|
5591
5727
|
needsChunkEmbedding ? generateEmbedding(query, ctx.embeddingOptions) : Promise.resolve(void 0),
|
|
5592
5728
|
buildGraphLaneRanking(query, ctx),
|
|
5593
5729
|
wantsTemporal ? buildTemporalLaneRanking(query, ctx.vaultCtx, options.now) : Promise.resolve([])
|
|
5594
5730
|
]);
|
|
5595
|
-
|
|
5596
|
-
const chunkResults = [];
|
|
5597
|
-
let vaultSize;
|
|
5731
|
+
prepMs = nowMs() - prepStart;
|
|
5598
5732
|
if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
|
|
5733
|
+
const factStart = nowMs();
|
|
5599
5734
|
const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
|
|
5600
|
-
const {
|
|
5735
|
+
const {
|
|
5736
|
+
results,
|
|
5737
|
+
vaultSize: size,
|
|
5738
|
+
reranked,
|
|
5739
|
+
hadV2Head: v2Head
|
|
5740
|
+
} = await searchVaultMemoriesWithSize(
|
|
5601
5741
|
query,
|
|
5602
5742
|
ctx.vaultCtx,
|
|
5603
5743
|
ctx.embeddingOptions,
|
|
@@ -5648,14 +5788,19 @@ async function recall(query, ctx, options = {}) {
|
|
|
5648
5788
|
)
|
|
5649
5789
|
);
|
|
5650
5790
|
vaultSize = size;
|
|
5791
|
+
didRerank = reranked;
|
|
5792
|
+
hadV2Head = v2Head;
|
|
5793
|
+
factLaneMs = nowMs() - factStart;
|
|
5651
5794
|
}
|
|
5652
5795
|
if (types.includes("chunk") && ctx.storageCtx && queryEmbedding) {
|
|
5796
|
+
const chunkStart = nowMs();
|
|
5653
5797
|
const chunkMinScore = options.minScore ?? DEFAULT_CHUNK_MIN_SCORE;
|
|
5654
5798
|
const results = await searchChunksOp(ctx.storageCtx, queryEmbedding, {
|
|
5655
5799
|
limit: types.includes("fact") ? Math.max(limit * 2, 16) : limit,
|
|
5656
5800
|
minSimilarity: chunkMinScore,
|
|
5657
5801
|
embeddingModel: ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL,
|
|
5658
|
-
...options.conversationId && { conversationId: options.conversationId }
|
|
5802
|
+
...options.conversationId && { conversationId: options.conversationId },
|
|
5803
|
+
...ctx.chunkCache && { chunkCache: ctx.chunkCache }
|
|
5659
5804
|
});
|
|
5660
5805
|
chunkResults.push(
|
|
5661
5806
|
...dedupeBy(
|
|
@@ -5665,18 +5810,23 @@ async function recall(query, ctx, options = {}) {
|
|
|
5665
5810
|
(r) => r.chunkText.trim()
|
|
5666
5811
|
)
|
|
5667
5812
|
);
|
|
5813
|
+
chunkLaneMs = nowMs() - chunkStart;
|
|
5668
5814
|
}
|
|
5815
|
+
const fuseStart = nowMs();
|
|
5669
5816
|
if (types.length === 1 || factResults.length === 0 || chunkResults.length === 0) {
|
|
5670
5817
|
const memories2 = [
|
|
5671
5818
|
...factResults.map(toFactMemory),
|
|
5672
5819
|
...chunkResults.map(toChunkMemory)
|
|
5673
5820
|
];
|
|
5674
5821
|
memories2.sort((a, b) => b.score - a.score);
|
|
5822
|
+
const candidateCount = factResults.length + chunkResults.length;
|
|
5823
|
+
fuseMs = nowMs() - fuseStart;
|
|
5824
|
+
emitDiagnostics(candidateCount);
|
|
5675
5825
|
return {
|
|
5676
5826
|
memories: memories2.slice(0, limit),
|
|
5677
5827
|
usedBudget,
|
|
5678
|
-
reranked:
|
|
5679
|
-
candidateCount
|
|
5828
|
+
reranked: didRerank,
|
|
5829
|
+
candidateCount,
|
|
5680
5830
|
...vaultSize !== void 0 && { vaultSize }
|
|
5681
5831
|
};
|
|
5682
5832
|
}
|
|
@@ -5725,10 +5875,12 @@ async function recall(query, ctx, options = {}) {
|
|
|
5725
5875
|
suppressed = next;
|
|
5726
5876
|
memories = selectWith(suppressed);
|
|
5727
5877
|
}
|
|
5878
|
+
fuseMs = nowMs() - fuseStart;
|
|
5879
|
+
emitDiagnostics(byId.size);
|
|
5728
5880
|
return {
|
|
5729
5881
|
memories,
|
|
5730
5882
|
usedBudget,
|
|
5731
|
-
reranked:
|
|
5883
|
+
reranked: didRerank,
|
|
5732
5884
|
candidateCount: byId.size,
|
|
5733
5885
|
...vaultSize !== void 0 && { vaultSize }
|
|
5734
5886
|
};
|
|
@@ -5792,7 +5944,7 @@ function toChunkMemory(r) {
|
|
|
5792
5944
|
updatedAt: r.message.createdAt
|
|
5793
5945
|
};
|
|
5794
5946
|
}
|
|
5795
|
-
var DEFAULT_LIMIT, DEFAULT_BUDGET, DEFAULT_FACT_MIN_SCORE, DEFAULT_CHUNK_MIN_SCORE;
|
|
5947
|
+
var DEFAULT_LIMIT, DEFAULT_BUDGET, DEFAULT_FACT_MIN_SCORE, nowMs, DEFAULT_CHUNK_MIN_SCORE;
|
|
5796
5948
|
var init_recall = __esm({
|
|
5797
5949
|
"src/lib/memory/recall.ts"() {
|
|
5798
5950
|
"use strict";
|
|
@@ -5808,6 +5960,7 @@ var init_recall = __esm({
|
|
|
5808
5960
|
DEFAULT_LIMIT = 8;
|
|
5809
5961
|
DEFAULT_BUDGET = "low";
|
|
5810
5962
|
DEFAULT_FACT_MIN_SCORE = 0.1;
|
|
5963
|
+
nowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
5811
5964
|
DEFAULT_CHUNK_MIN_SCORE = 0.5;
|
|
5812
5965
|
}
|
|
5813
5966
|
});
|
|
@@ -6007,6 +6160,9 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
6007
6160
|
bm25AdmissionDivisor: options?.bm25AdmissionDivisor,
|
|
6008
6161
|
rrfK: options?.rrfK
|
|
6009
6162
|
});
|
|
6163
|
+
if (options?.v2HeadStats) {
|
|
6164
|
+
options.v2HeadStats.hadResults = v2Ranked.length > 0;
|
|
6165
|
+
}
|
|
6010
6166
|
let combined;
|
|
6011
6167
|
let tailSlice = [];
|
|
6012
6168
|
if (options?.rerank) {
|
|
@@ -6027,8 +6183,13 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
6027
6183
|
return { ...r, similarity: v2 * (1 + ceWeight * ce) };
|
|
6028
6184
|
});
|
|
6029
6185
|
combined.sort((a, b) => b.similarity - a.similarity);
|
|
6186
|
+
if (headSlice.length > 0 && options.rerankStats) options.rerankStats.applied = true;
|
|
6030
6187
|
} catch (err) {
|
|
6031
|
-
|
|
6188
|
+
if (err instanceof RerankerUnavailableError) {
|
|
6189
|
+
getLogger().debug("[memory/search] cross-encoder unavailable; using V2 ranking");
|
|
6190
|
+
} else {
|
|
6191
|
+
getLogger().warn("[memory/search] cross-encoder rerank failed; using V2 ranking", err);
|
|
6192
|
+
}
|
|
6032
6193
|
combined = v2Ranked;
|
|
6033
6194
|
}
|
|
6034
6195
|
} else {
|
|
@@ -6162,6 +6323,9 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
6162
6323
|
(r) => r !== null
|
|
6163
6324
|
);
|
|
6164
6325
|
combined.sort((a, b) => b.similarity - a.similarity);
|
|
6326
|
+
if (options?.v2HeadStats) {
|
|
6327
|
+
options.v2HeadStats.hadResults = combined.length > 0;
|
|
6328
|
+
}
|
|
6165
6329
|
if (options?.includeUnrankedTail) {
|
|
6166
6330
|
const fusedIds = new Set(combined.map((r) => r.uniqueId));
|
|
6167
6331
|
for (const item of items) {
|
|
@@ -6197,11 +6361,16 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
6197
6361
|
}));
|
|
6198
6362
|
head.sort((a, b) => b.similarity - a.similarity);
|
|
6199
6363
|
combined = [...head, ...tailSlice];
|
|
6364
|
+
if (headSlice.length > 0 && options.rerankStats) options.rerankStats.applied = true;
|
|
6200
6365
|
} catch (err) {
|
|
6201
|
-
|
|
6202
|
-
"[memory/search]
|
|
6203
|
-
|
|
6204
|
-
|
|
6366
|
+
if (err instanceof RerankerUnavailableError) {
|
|
6367
|
+
getLogger().debug("[memory/search] cross-encoder unavailable; using fused ranking");
|
|
6368
|
+
} else {
|
|
6369
|
+
getLogger().warn(
|
|
6370
|
+
"[memory/search] composite cross-encoder rerank failed; using fused ranking",
|
|
6371
|
+
err
|
|
6372
|
+
);
|
|
6373
|
+
}
|
|
6205
6374
|
}
|
|
6206
6375
|
}
|
|
6207
6376
|
if (options?.mmr) {
|
|
@@ -6293,7 +6462,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6293
6462
|
const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
|
|
6294
6463
|
const scopes = searchOptions?.scopes;
|
|
6295
6464
|
if (!query || typeof query !== "string") {
|
|
6296
|
-
return { results: [], vaultSize: 0 };
|
|
6465
|
+
return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
|
|
6297
6466
|
}
|
|
6298
6467
|
const folderId = searchOptions?.folderId;
|
|
6299
6468
|
const queryOpts = {};
|
|
@@ -6310,7 +6479,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6310
6479
|
);
|
|
6311
6480
|
}
|
|
6312
6481
|
if (memories.length === 0) {
|
|
6313
|
-
return { results: [], vaultSize: loaded.length };
|
|
6482
|
+
return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
|
|
6314
6483
|
}
|
|
6315
6484
|
const queryEmbedding = await generateEmbedding(query, embeddingOptions);
|
|
6316
6485
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
@@ -6386,12 +6555,18 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6386
6555
|
memories.map((m) => [m.uniqueId, { createdAt: m.createdAt, updatedAt: m.updatedAt }])
|
|
6387
6556
|
);
|
|
6388
6557
|
const stampTimestamps = (out) => {
|
|
6389
|
-
|
|
6558
|
+
const results2 = out.results.map((r) => {
|
|
6390
6559
|
const ts = timestampById.get(r.uniqueId);
|
|
6391
6560
|
return ts ? { ...r, createdAt: ts.createdAt, updatedAt: ts.updatedAt } : r;
|
|
6392
6561
|
});
|
|
6393
|
-
return
|
|
6562
|
+
return {
|
|
6563
|
+
results: results2,
|
|
6564
|
+
vaultSize: out.vaultSize,
|
|
6565
|
+
reranked: out.reranked ?? false,
|
|
6566
|
+
hadV2Head: out.hadV2Head ?? false
|
|
6567
|
+
};
|
|
6394
6568
|
};
|
|
6569
|
+
const rerankStats = { applied: false };
|
|
6395
6570
|
const useFusion = searchOptions?.useFusion ?? true;
|
|
6396
6571
|
const tuning = {
|
|
6397
6572
|
...searchOptions?.recencyAlpha !== void 0 && { recencyAlpha: searchOptions.recencyAlpha },
|
|
@@ -6418,6 +6593,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6418
6593
|
query: sq,
|
|
6419
6594
|
embedding: subEmbeddings[i]
|
|
6420
6595
|
}));
|
|
6596
|
+
const v2HeadStats = { hadResults: false };
|
|
6421
6597
|
const composite = await rankComposite(query, queryEmbedding, subQueries, embeddedItems, {
|
|
6422
6598
|
limit,
|
|
6423
6599
|
minSimilarity,
|
|
@@ -6429,12 +6605,20 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6429
6605
|
...searchOptions.mmr !== void 0 && { mmr: searchOptions.mmr },
|
|
6430
6606
|
...tuning,
|
|
6431
6607
|
...searchOptions.entityRanking && { entityRanking: searchOptions.entityRanking },
|
|
6432
|
-
...searchOptions.temporalRanking && { temporalRanking: searchOptions.temporalRanking }
|
|
6608
|
+
...searchOptions.temporalRanking && { temporalRanking: searchOptions.temporalRanking },
|
|
6609
|
+
rerankStats,
|
|
6610
|
+
v2HeadStats
|
|
6611
|
+
});
|
|
6612
|
+
return stampTimestamps({
|
|
6613
|
+
results: composite,
|
|
6614
|
+
vaultSize: loaded.length,
|
|
6615
|
+
reranked: rerankStats.applied,
|
|
6616
|
+
hadV2Head: v2HeadStats.hadResults
|
|
6433
6617
|
});
|
|
6434
|
-
return stampTimestamps({ results: composite, vaultSize: loaded.length });
|
|
6435
6618
|
}
|
|
6436
6619
|
}
|
|
6437
6620
|
if (useFusion && searchOptions?.rerank) {
|
|
6621
|
+
const v2HeadStats = { hadResults: false };
|
|
6438
6622
|
const results2 = await rankFusedVaultMemoriesAsync(query, queryEmbedding, embeddedItems, {
|
|
6439
6623
|
limit,
|
|
6440
6624
|
minSimilarity,
|
|
@@ -6446,9 +6630,16 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6446
6630
|
...searchOptions.mmr !== void 0 && { mmr: searchOptions.mmr },
|
|
6447
6631
|
...tuning,
|
|
6448
6632
|
...searchOptions.entityRanking && { entityRanking: searchOptions.entityRanking },
|
|
6449
|
-
...searchOptions.temporalRanking && { temporalRanking: searchOptions.temporalRanking }
|
|
6633
|
+
...searchOptions.temporalRanking && { temporalRanking: searchOptions.temporalRanking },
|
|
6634
|
+
rerankStats,
|
|
6635
|
+
v2HeadStats
|
|
6636
|
+
});
|
|
6637
|
+
return stampTimestamps({
|
|
6638
|
+
results: results2,
|
|
6639
|
+
vaultSize: loaded.length,
|
|
6640
|
+
reranked: rerankStats.applied,
|
|
6641
|
+
hadV2Head: v2HeadStats.hadResults
|
|
6450
6642
|
});
|
|
6451
|
-
return stampTimestamps({ results: results2, vaultSize: loaded.length });
|
|
6452
6643
|
}
|
|
6453
6644
|
if (useFusion) {
|
|
6454
6645
|
const results2 = rankFusedVaultMemories(query, queryEmbedding, embeddedItems, {
|
|
@@ -6458,7 +6649,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6458
6649
|
...searchOptions?.entityRanking && { entityRanking: searchOptions.entityRanking },
|
|
6459
6650
|
...searchOptions?.temporalRanking && { temporalRanking: searchOptions.temporalRanking }
|
|
6460
6651
|
});
|
|
6461
|
-
return stampTimestamps({ results: results2, vaultSize: loaded.length });
|
|
6652
|
+
return stampTimestamps({ results: results2, vaultSize: loaded.length, hadV2Head: results2.length > 0 });
|
|
6462
6653
|
}
|
|
6463
6654
|
const results = rankVaultMemories(query, queryEmbedding, embeddedItems, {
|
|
6464
6655
|
limit,
|
|
@@ -6470,7 +6661,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6470
6661
|
supersessionWindow: searchOptions.supersessionWindow
|
|
6471
6662
|
}
|
|
6472
6663
|
});
|
|
6473
|
-
return stampTimestamps({ results, vaultSize: loaded.length });
|
|
6664
|
+
return stampTimestamps({ results, vaultSize: loaded.length, hadV2Head: results.length > 0 });
|
|
6474
6665
|
}
|
|
6475
6666
|
async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
|
|
6476
6667
|
const { results } = await searchVaultMemoriesWithSize(
|
|
@@ -6767,6 +6958,7 @@ __export(index_exports, {
|
|
|
6767
6958
|
ChatMessage: () => Message,
|
|
6768
6959
|
ConversationMemoryModel: () => ConversationMemory,
|
|
6769
6960
|
DEFAULT_CACHE_EXPIRATION_MS: () => DEFAULT_CACHE_EXPIRATION_MS,
|
|
6961
|
+
DEFAULT_CHUNK_CACHE_SIZE: () => DEFAULT_CHUNK_CACHE_SIZE,
|
|
6770
6962
|
DEFAULT_CHUNK_OVERLAP: () => DEFAULT_CHUNK_OVERLAP,
|
|
6771
6963
|
DEFAULT_CHUNK_SIZE: () => DEFAULT_CHUNK_SIZE,
|
|
6772
6964
|
DEFAULT_MIN_CHUNK_SIZE: () => DEFAULT_MIN_CHUNK_SIZE,
|
|
@@ -6780,6 +6972,7 @@ __export(index_exports, {
|
|
|
6780
6972
|
QueueManager: () => QueueManager,
|
|
6781
6973
|
RECALL_MAX_LIMIT: () => RECALL_MAX_LIMIT,
|
|
6782
6974
|
RECALL_TOOL_NAME: () => RECALL_TOOL_NAME,
|
|
6975
|
+
RerankerUnavailableError: () => RerankerUnavailableError,
|
|
6783
6976
|
SDK_SCHEMA_VERSION: () => SDK_SCHEMA_VERSION,
|
|
6784
6977
|
STREAM_RESUMABLE_HEADER: () => STREAM_RESUMABLE_HEADER,
|
|
6785
6978
|
StoredVaultFolderModel: () => VaultFolder,
|
|
@@ -6812,6 +7005,7 @@ __export(index_exports, {
|
|
|
6812
7005
|
conversationMemoryToStored: () => conversationMemoryToStored,
|
|
6813
7006
|
cosineInt8: () => cosineInt8,
|
|
6814
7007
|
createAutoExtractor: () => createAutoExtractor,
|
|
7008
|
+
createChunkVectorCache: () => createChunkVectorCache,
|
|
6815
7009
|
createCryptoPricePreProcessor: () => createCryptoPricePreProcessor,
|
|
6816
7010
|
createMemoryEngineTool: () => createMemoryEngineTool,
|
|
6817
7011
|
createMemoryVaultSearchTool: () => createMemoryVaultSearchTool,
|
|
@@ -6861,6 +7055,7 @@ __export(index_exports, {
|
|
|
6861
7055
|
getVaultMemoryOp: () => getVaultMemoryOp,
|
|
6862
7056
|
hasEncryptionKey: () => hasEncryptionKey,
|
|
6863
7057
|
isPiiRedactor: () => isPiiRedactor,
|
|
7058
|
+
isRerankerAvailable: () => isRerankerAvailable,
|
|
6864
7059
|
moveMemoriesToFolderOp: () => moveMemoriesToFolderOp,
|
|
6865
7060
|
noopLogger: () => noopLogger,
|
|
6866
7061
|
onKeyAvailable: () => onKeyAvailable,
|
|
@@ -13460,6 +13655,13 @@ function createAutoExtractor(options) {
|
|
|
13460
13655
|
};
|
|
13461
13656
|
}
|
|
13462
13657
|
|
|
13658
|
+
// src/lib/memory/chunkVectorCache.ts
|
|
13659
|
+
init_lruCache();
|
|
13660
|
+
var DEFAULT_CHUNK_CACHE_SIZE = 5e3;
|
|
13661
|
+
function createChunkVectorCache(maxSize = DEFAULT_CHUNK_CACHE_SIZE) {
|
|
13662
|
+
return new LRUCache(maxSize);
|
|
13663
|
+
}
|
|
13664
|
+
|
|
13463
13665
|
// src/lib/memory/index.ts
|
|
13464
13666
|
init_recall();
|
|
13465
13667
|
|
|
@@ -13724,6 +13926,9 @@ function parseAnswer(body, base, parseSchema) {
|
|
|
13724
13926
|
};
|
|
13725
13927
|
}
|
|
13726
13928
|
|
|
13929
|
+
// src/lib/memory/index.ts
|
|
13930
|
+
init_reranker();
|
|
13931
|
+
|
|
13727
13932
|
// src/lib/memory/topicExtract.ts
|
|
13728
13933
|
init_operations2();
|
|
13729
13934
|
init_operations3();
|
|
@@ -15105,6 +15310,13 @@ function useChatStorage(options) {
|
|
|
15105
15310
|
[vaultCtx]
|
|
15106
15311
|
);
|
|
15107
15312
|
const vaultEmbeddingCacheRef = (0, import_react4.useRef)(createVaultEmbeddingCache());
|
|
15313
|
+
const chunkVectorCacheRef = (0, import_react4.useRef)(createChunkVectorCache());
|
|
15314
|
+
(0, import_react4.useEffect)(() => {
|
|
15315
|
+
return onClearAllEncryptionState(() => {
|
|
15316
|
+
vaultEmbeddingCacheRef.current.clear();
|
|
15317
|
+
chunkVectorCacheRef.current.clear();
|
|
15318
|
+
});
|
|
15319
|
+
}, []);
|
|
15108
15320
|
const createRecallTool2 = (0, import_react4.useCallback)(
|
|
15109
15321
|
(toolOptions, callbacks) => {
|
|
15110
15322
|
if (!getToken) {
|
|
@@ -15121,7 +15333,8 @@ function useChatStorage(options) {
|
|
|
15121
15333
|
model: embeddingModel,
|
|
15122
15334
|
maskInput: maskEmbeddingInput
|
|
15123
15335
|
},
|
|
15124
|
-
vaultCache: vaultEmbeddingCacheRef.current
|
|
15336
|
+
vaultCache: vaultEmbeddingCacheRef.current,
|
|
15337
|
+
chunkCache: chunkVectorCacheRef.current
|
|
15125
15338
|
// entityCtx is intentionally omitted on Expo for now — the
|
|
15126
15339
|
// W5 graph lane is a no-op without it (recall falls through
|
|
15127
15340
|
// to fact + chunk lanes). Wire it up when the Expo client
|
|
@@ -15163,7 +15376,8 @@ function useChatStorage(options) {
|
|
|
15163
15376
|
model: embeddingModel,
|
|
15164
15377
|
maskInput: maskEmbeddingInput
|
|
15165
15378
|
},
|
|
15166
|
-
vaultCache: vaultEmbeddingCacheRef.current
|
|
15379
|
+
vaultCache: vaultEmbeddingCacheRef.current,
|
|
15380
|
+
chunkCache: chunkVectorCacheRef.current
|
|
15167
15381
|
},
|
|
15168
15382
|
resolvedOptions
|
|
15169
15383
|
);
|
|
@@ -18490,6 +18704,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
|
|
|
18490
18704
|
ChatMessage,
|
|
18491
18705
|
ConversationMemoryModel,
|
|
18492
18706
|
DEFAULT_CACHE_EXPIRATION_MS,
|
|
18707
|
+
DEFAULT_CHUNK_CACHE_SIZE,
|
|
18493
18708
|
DEFAULT_CHUNK_OVERLAP,
|
|
18494
18709
|
DEFAULT_CHUNK_SIZE,
|
|
18495
18710
|
DEFAULT_MIN_CHUNK_SIZE,
|
|
@@ -18503,6 +18718,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
|
|
|
18503
18718
|
QueueManager,
|
|
18504
18719
|
RECALL_MAX_LIMIT,
|
|
18505
18720
|
RECALL_TOOL_NAME,
|
|
18721
|
+
RerankerUnavailableError,
|
|
18506
18722
|
SDK_SCHEMA_VERSION,
|
|
18507
18723
|
STREAM_RESUMABLE_HEADER,
|
|
18508
18724
|
StoredVaultFolderModel,
|
|
@@ -18535,6 +18751,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
|
|
|
18535
18751
|
conversationMemoryToStored,
|
|
18536
18752
|
cosineInt8,
|
|
18537
18753
|
createAutoExtractor,
|
|
18754
|
+
createChunkVectorCache,
|
|
18538
18755
|
createCryptoPricePreProcessor,
|
|
18539
18756
|
createMemoryEngineTool,
|
|
18540
18757
|
createMemoryVaultSearchTool,
|
|
@@ -18584,6 +18801,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
|
|
|
18584
18801
|
getVaultMemoryOp,
|
|
18585
18802
|
hasEncryptionKey,
|
|
18586
18803
|
isPiiRedactor,
|
|
18804
|
+
isRerankerAvailable,
|
|
18587
18805
|
moveMemoriesToFolderOp,
|
|
18588
18806
|
noopLogger,
|
|
18589
18807
|
onKeyAvailable,
|