rag-memory-epf-mcp 6.3.2 → 6.4.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/README.md +22 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +49 -14
- package/dist/src/tools/knowledge-graph-tools.js +9 -7
- package/docs/UPDATING.md +50 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -154,6 +154,28 @@ storeDocument(id, content, metadata)
|
|
|
154
154
|
|
|
155
155
|
## Changelog
|
|
156
156
|
|
|
157
|
+
### v6.4.0 (2026-10-03)
|
|
158
|
+
|
|
159
|
+
- (Published first as `6.4.0-rc.1` on the `next` dist-tag; promoted to `latest` after a canary of the published
|
|
160
|
+
artifact against a backup copy of a real project database: version and model as expected, `hybrid` mode on all
|
|
161
|
+
probes, the identifier probe's answer at rank 4 and the known-item probe's at rank 1, every score <= 2/61,
|
|
162
|
+
query-cold median 445 ms, `query_prefix_version` 2, entity/relation/document/chunk counts unchanged, no errors.)
|
|
163
|
+
|
|
164
|
+
- **Changed** `hybridSearch` default ranking = reciprocal rank fusion of the vector and FTS5 candidate lists
|
|
165
|
+
(k=60). A chunk that only FTS5 finds — typically an exact identifier, filename or setting key — can now reach
|
|
166
|
+
the top; before, it scored at most 0.0164 and sat under every vector candidate in the measured corpora.
|
|
167
|
+
`relevance_score` on the default call is a rank score (at most 2/61, comparable only within one call). Measured on frozen snapshots: exact-identifier hit@10 7/20 → 18/20; worse on 0 of
|
|
168
|
+
203 queries across three corpora.
|
|
169
|
+
- **Changed** the per-result summary path is opt-in (`RAG_MEMORY_SEARCH_SUMMARIES=on`). It embedded every
|
|
170
|
+
sentence fragment of every candidate (median 121 s per search) and its context boost pushed vector-0 chunks
|
|
171
|
+
to rank 1. `off` keeps working. Legacy paths (`summaries=on`, `useGraph: true`) keep the 6.3.2 formula.
|
|
172
|
+
- **Changed** with the default model (bge-m3) queries are embedded as raw text: the bge-v1.5 instruction the loader
|
|
173
|
+
prepended to every query is gone (bge-m3 needs none; stored vectors never had it). A custom `EMBEDDING_MODEL` keeps
|
|
174
|
+
the previous query instruction. Paraphrase hit@10 7 → 9 of 20, identifier hit@1 7 → 8,
|
|
175
|
+
document known-item (`hybridSearch`) unchanged or +1; entity known-item (`searchNodes`) hit@10 unchanged,
|
|
176
|
+
hit@1 -1 / -1 / +1 (hub / uap / hal). No re-index.
|
|
177
|
+
- Details and rollout: `docs/UPDATING.md`, `specs/changes/search-fusion-rrf/proposal.md`.
|
|
178
|
+
|
|
157
179
|
### v6.3.2 (2026-09-25)
|
|
158
180
|
|
|
159
181
|
- **Changed — on macOS the engine takes `-wal` and `-shm` out of cloud sync.** It sets
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ import { type SourceInput } from './src/observations/lifecycle.js';
|
|
|
3
3
|
import { EmbeddingGate } from './src/embeddingGate.js';
|
|
4
4
|
import type { EmbedPriority } from './src/embeddingGate.js';
|
|
5
5
|
import { BackfillCoordinator } from './src/backfillCoordinator.js';
|
|
6
|
+
export declare const LEGACY_QUERY_INSTRUCTION = "Represent this sentence for searching relevant passages: ";
|
|
7
|
+
export declare function embeddingInput(text: string, isQuery: boolean, defaultModel?: boolean): string;
|
|
8
|
+
export declare function makeEmbedFn(model: (input: string, opts: any) => Promise<{
|
|
9
|
+
data: any;
|
|
10
|
+
}>, defaultModel: boolean): (text: string, dims: number, isQuery: boolean) => Promise<Float32Array<ArrayBuffer>>;
|
|
6
11
|
export declare function compileFtsLiteralQuery(q: string): string | null;
|
|
7
12
|
export declare function resolveDbFilePath(envValue: string | undefined, cwd: string, serverDir: string): string;
|
|
8
13
|
export declare function parseMmapSize(raw: string | undefined): number;
|
package/dist/index.js
CHANGED
|
@@ -67,6 +67,24 @@ function printBanner(opts) {
|
|
|
67
67
|
// operators (every term is double-quoted; special characters stripped exactly
|
|
68
68
|
// as the pre-3.6 hybridSearch sanitizer did). Returns null when nothing
|
|
69
69
|
// searchable remains (contract: caller returns empty results + warning).
|
|
70
|
+
// search-fusion-rrf (query input): what the model sees for a text. For the DEFAULT model (bge-m3) queries are
|
|
71
|
+
// embedded as raw text — the model card: "the BGE-M3 model no longer requires adding instructions to the
|
|
72
|
+
// queries"; measured on the frozen hub snapshot (93 queries, full-corpus vector rank): 36 better, 6 worse, 51 same.
|
|
73
|
+
// A CUSTOM model (EMBEDDING_MODEL set to something else) keeps the pre-change query instruction: the evidence
|
|
74
|
+
// above is for bge-m3 only, and some models (e.g. bge v1.5) still recommend an instruction on queries.
|
|
75
|
+
// Passages are always raw. `isQuery` stays in the signature and in the embedding cache key.
|
|
76
|
+
export const LEGACY_QUERY_INSTRUCTION = 'Represent this sentence for searching relevant passages: ';
|
|
77
|
+
export function embeddingInput(text, isQuery, defaultModel = true) {
|
|
78
|
+
return isQuery && !defaultModel ? `${LEGACY_QUERY_INSTRUCTION}${text}` : text;
|
|
79
|
+
}
|
|
80
|
+
// The embed function handed to the gate. Exported so the input wiring is testable with a stub model.
|
|
81
|
+
export function makeEmbedFn(model, defaultModel) {
|
|
82
|
+
return async (text, dims, isQuery) => {
|
|
83
|
+
const input = embeddingInput(text, isQuery, defaultModel);
|
|
84
|
+
const r = await model(input, { pooling: 'cls', normalize: true });
|
|
85
|
+
return new Float32Array(r.data.slice(0, dims));
|
|
86
|
+
};
|
|
87
|
+
}
|
|
70
88
|
export function compileFtsLiteralQuery(q) {
|
|
71
89
|
const sanitized = q.replace(/["\*\(\)\-]/g, ' ').trim();
|
|
72
90
|
if (!sanitized)
|
|
@@ -335,8 +353,12 @@ export class RAGKnowledgeGraphManager {
|
|
|
335
353
|
.get(EMBEDDING_MODEL, MODEL_REVISION, MODEL_DTYPE, dims, 'cls', 1);
|
|
336
354
|
this.db.prepare(`INSERT INTO server_meta(key,value) VALUES('current_profile_id',?)
|
|
337
355
|
ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(String(row.id));
|
|
338
|
-
|
|
339
|
-
|
|
356
|
+
// query_prefix_version: diagnostic marker of the query-input convention of the engine that last INITIALISED
|
|
357
|
+
// this DB — 1 = instruction prepended to queries (<= 6.3.2, and custom models now), 2 = raw queries (default
|
|
358
|
+
// bge-m3 since search-fusion-rrf). It is written at init, not per query: it does not prove what the last query
|
|
359
|
+
// used, which engines are attached, or vector compatibility. Nothing reads it for logic.
|
|
360
|
+
this.db.prepare(`INSERT INTO server_meta(key,value) VALUES('query_prefix_version',?)
|
|
361
|
+
ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(IS_DEFAULT_MODEL_CONFIG ? '2' : '1');
|
|
340
362
|
return row.id;
|
|
341
363
|
}
|
|
342
364
|
// Real model loader used by the gate: version-independent cache dir with a
|
|
@@ -374,11 +396,7 @@ export class RAGKnowledgeGraphManager {
|
|
|
374
396
|
if (role === 'owner')
|
|
375
397
|
lock.markComplete();
|
|
376
398
|
console.error(`✅ ${EMBEDDING_MODEL} model loaded (${MODEL_DTYPE})`);
|
|
377
|
-
return
|
|
378
|
-
const input = isQuery ? `Represent this sentence for searching relevant passages: ${text}` : text;
|
|
379
|
-
const r = await model(input, { pooling: 'cls', normalize: true });
|
|
380
|
-
return new Float32Array(r.data.slice(0, dims));
|
|
381
|
-
};
|
|
399
|
+
return makeEmbedFn(model, IS_DEFAULT_MODEL_CONFIG);
|
|
382
400
|
}
|
|
383
401
|
catch (e) {
|
|
384
402
|
// Cache policy by CAUSE and ROLE (beta 2R B3 -> 4R M1 -> 5R M1), unit-
|
|
@@ -3549,6 +3567,9 @@ export class RAGKnowledgeGraphManager {
|
|
|
3549
3567
|
throw new Error('Database not initialized');
|
|
3550
3568
|
if (!this.encoding)
|
|
3551
3569
|
throw new Error('Tokenizer not initialized');
|
|
3570
|
+
// search-fusion-rrf: summary mode is read ONCE, at call entry (before any await), and used for the
|
|
3571
|
+
// whole call. Opt-in since this change (was opt-out via =off in v5..6.3.2).
|
|
3572
|
+
const summariesOn = process.env.RAG_MEMORY_SEARCH_SUMMARIES === 'on';
|
|
3552
3573
|
console.error(`🔍 Enhanced hybrid search: "${query}"`);
|
|
3553
3574
|
// Parity with searchNodes (beta 1R supplement): an unsearchable query gets
|
|
3554
3575
|
// an explicit warning instead of a silent empty envelope.
|
|
@@ -3612,6 +3633,11 @@ export class RAGKnowledgeGraphManager {
|
|
|
3612
3633
|
}
|
|
3613
3634
|
catch (embErr) {
|
|
3614
3635
|
vectorDegraded = true;
|
|
3636
|
+
// search-fusion-rrf (D5): a failure on a LATER cross-lingual variant used to leave the earlier
|
|
3637
|
+
// variants' vector candidates in resultMap while the envelope said 'fts-only'. Drop them so the
|
|
3638
|
+
// degraded call really is FTS-only (no vector rank, no summary, no graph) in every mode.
|
|
3639
|
+
resultMap.clear();
|
|
3640
|
+
primaryQueryEmbedding = null;
|
|
3615
3641
|
// 'inference_error' (not 'model_not_ready'): model_state may still read
|
|
3616
3642
|
// 'ready' here — a contradictory reason pair confused callers (beta B6).
|
|
3617
3643
|
degradationReason = this.degradationReason() ?? 'inference_error';
|
|
@@ -3619,6 +3645,12 @@ export class RAGKnowledgeGraphManager {
|
|
|
3619
3645
|
}
|
|
3620
3646
|
}
|
|
3621
3647
|
const vectorResults = Array.from(resultMap.values()).sort((a, b) => a.distance - b.distance);
|
|
3648
|
+
// search-fusion-rrf: vector rank (1-based, best distance across variants) for rank fusion.
|
|
3649
|
+
// Taken here, before FTS5-only candidates are appended to vectorResults below.
|
|
3650
|
+
const vectorRankOf = new Map(vectorResults.map((r, i) => [r.chunk_id, i + 1]));
|
|
3651
|
+
// Default ranking = reciprocal rank fusion of the vector list and the FTS5 list (k=60).
|
|
3652
|
+
// The legacy formula stays for the opt-in diagnostics (summaries on, graph re-ranker on).
|
|
3653
|
+
const rankFusion = !useGraph && !summariesOn;
|
|
3622
3654
|
// FTS5 full-text search as additional signal (Reciprocal Rank Fusion)
|
|
3623
3655
|
const ftsBoostMap = new Map();
|
|
3624
3656
|
try {
|
|
@@ -3807,12 +3839,12 @@ export class RAGKnowledgeGraphManager {
|
|
|
3807
3839
|
graphBoost += Math.min(entityBoost, 0.4);
|
|
3808
3840
|
}
|
|
3809
3841
|
// Generate semantic summary (skip when degraded — no embeddings available).
|
|
3810
|
-
//
|
|
3811
|
-
//
|
|
3812
|
-
// measured
|
|
3813
|
-
//
|
|
3842
|
+
// search-fusion-rrf: the summary path is OPT-IN (RAG_MEMORY_SEARCH_SUMMARIES=on). It embeds
|
|
3843
|
+
// every sentence fragment of every candidate one at a time (~400 inferences per search on a
|
|
3844
|
+
// real corpus, median 121 s measured 2026-10-03) and its unbounded context boost let
|
|
3845
|
+
// vector-0 chunks take rank 1 (known-item hit@1 9/10 off vs 4/10 on). Default = preview slices.
|
|
3814
3846
|
let summary, keyHighlight, relevanceScore;
|
|
3815
|
-
if (vectorDegraded || !primaryQueryEmbedding ||
|
|
3847
|
+
if (vectorDegraded || !primaryQueryEmbedding || !summariesOn) {
|
|
3816
3848
|
keyHighlight = result.text.slice(0, 150);
|
|
3817
3849
|
summary = result.text.slice(0, 300);
|
|
3818
3850
|
relevanceScore = 0;
|
|
@@ -3822,8 +3854,11 @@ export class RAGKnowledgeGraphManager {
|
|
|
3822
3854
|
));
|
|
3823
3855
|
}
|
|
3824
3856
|
const vectorSimilarity = Math.max(0, 1 - result.distance / 2);
|
|
3825
|
-
const ftsBoost = ftsBoostMap.get(result.chunk_id) || 0;
|
|
3826
|
-
const
|
|
3857
|
+
const ftsBoost = ftsBoostMap.get(result.chunk_id) || 0; // = 1/(60 + FTS rank), 0 if not an FTS hit
|
|
3858
|
+
const vectorRank = vectorRankOf.get(result.chunk_id);
|
|
3859
|
+
const finalScore = rankFusion
|
|
3860
|
+
? (vectorRank !== undefined ? 1 / (60 + vectorRank) : 0) + ftsBoost
|
|
3861
|
+
: Math.max(vectorSimilarity, relevanceScore) + graphBoost + ftsBoost;
|
|
3827
3862
|
// Determine document title and source ID
|
|
3828
3863
|
let documentTitle;
|
|
3829
3864
|
let sourceId;
|
|
@@ -277,7 +277,7 @@ export const addObservationsTool = {
|
|
|
277
277
|
};
|
|
278
278
|
// === HYBRID SEARCH TOOL ===
|
|
279
279
|
const hybridSearchCapability = {
|
|
280
|
-
description: 'Perform
|
|
280
|
+
description: 'Perform hybrid search over vector and FTS5 candidates with default reciprocal rank fusion and an optional legacy graph re-ranker',
|
|
281
281
|
parameters: {
|
|
282
282
|
type: 'object',
|
|
283
283
|
properties: {
|
|
@@ -300,7 +300,8 @@ const hybridSearchCapability = {
|
|
|
300
300
|
},
|
|
301
301
|
};
|
|
302
302
|
const hybridSearchDescription = () => `<description>
|
|
303
|
-
Hybrid document search: vector similarity + FTS5 BM25 over document chunks,
|
|
303
|
+
Hybrid document search: vector similarity + FTS5 BM25 over document chunks, fused by rank (reciprocal rank fusion,
|
|
304
|
+
k=60, so an exact identifier that only FTS5 finds can still enter the returned top results), with an **opt-in** knowledge-graph re-ranker.
|
|
304
305
|
Default (useGraph false) is the harm-reduced default for finding a fact you know exists (known-item retrieval).
|
|
305
306
|
useGraph: true is a legacy/experimental re-ranker kept for backward compatibility and controlled evaluation — it does not
|
|
306
307
|
add candidates, it only re-orders the vector/FTS pool, and measured on three real corpora (2026-08-17) it pushed the exact
|
|
@@ -310,14 +311,14 @@ chunk out of the top-5 in ~40% of known-item queries. For relationship explorati
|
|
|
310
311
|
<importantNotes>
|
|
311
312
|
- (!important!) **Graph re-ranking is opt-in (default false since v5.3.0)** — it re-orders candidates by matched/connected entity links, which is measured to hurt known-item retrieval; enable it only for backward compatibility or controlled evaluation
|
|
312
313
|
- (!important!) Graph re-ranking does not generate candidates — for "what is connected to X" use openNodes -> getNeighbors
|
|
313
|
-
- (!important!)
|
|
314
|
+
- (!important!) relevance_score is a RANK score on the default call: 1/(60 + vector rank) + 1/(60 + FTS rank), at most 2/61; it is not a similarity or probability and is only comparable within one call (vector_similarity and fts_boost are reported alongside)
|
|
314
315
|
- (!important!) **Best results when knowledge graph is well-populated** with entities and relationships
|
|
315
316
|
</importantNotes>
|
|
316
317
|
|
|
317
318
|
<whenToUseThisTool>
|
|
318
319
|
- When you need comprehensive search across documents and knowledge
|
|
319
320
|
- For complex queries requiring conceptual understanding
|
|
320
|
-
-
|
|
321
|
+
- Exact identifiers (file names, setting keys, function names, hashes) as well as natural-language questions
|
|
321
322
|
- **Before making decisions** - to gather all relevant information
|
|
322
323
|
- When researching topics that span multiple domains
|
|
323
324
|
- For discovery of implicit connections and patterns
|
|
@@ -325,7 +326,8 @@ chunk out of the top-5 in ~40% of known-item queries. For relationship explorati
|
|
|
325
326
|
|
|
326
327
|
<features>
|
|
327
328
|
- Vector similarity search using sentence transformers
|
|
328
|
-
-
|
|
329
|
+
- Rank fusion of vector and FTS5 candidates: an exact term found only by FTS5 can enter the returned top results even when vector candidates are present
|
|
330
|
+
- Optional legacy graph re-ranker (re-orders only; no traversal — use openNodes -> getNeighbors)
|
|
329
331
|
- Hybrid scoring combining multiple relevance signals
|
|
330
332
|
- Entity association highlighting
|
|
331
333
|
- Configurable result limits and graph usage
|
|
@@ -333,7 +335,7 @@ chunk out of the top-5 in ~40% of known-item queries. For relationship explorati
|
|
|
333
335
|
</features>
|
|
334
336
|
|
|
335
337
|
<bestPractices>
|
|
336
|
-
-
|
|
338
|
+
- Natural-language questions and exact identifiers both work; pass the identifier itself when you know it
|
|
337
339
|
- Keep graph re-ranking off for "find the fact I know exists"; for "what is connected to this" use openNodes -> getNeighbors, not useGraph
|
|
338
340
|
- Start with broader queries, then narrow down based on results
|
|
339
341
|
- Review entity associations to understand why results were selected
|
|
@@ -342,7 +344,7 @@ chunk out of the top-5 in ~40% of known-item queries. For relationship explorati
|
|
|
342
344
|
</bestPractices>
|
|
343
345
|
|
|
344
346
|
<parameters>
|
|
345
|
-
- query:
|
|
347
|
+
- query: Search query — a natural-language question or an exact term/identifier (string, required)
|
|
346
348
|
- limit: Maximum results to return, default 5 (number, optional)
|
|
347
349
|
- useGraph: Enable knowledge graph re-ranking, default false / opt-in (boolean, optional)
|
|
348
350
|
</parameters>
|
package/docs/UPDATING.md
CHANGED
|
@@ -108,6 +108,52 @@ path and holder pid (e.g. `.download-<key>.lock`). Verify the holder process
|
|
|
108
108
|
is genuinely gone or hung (`ps -p <pid>`), then remove the lock file manually;
|
|
109
109
|
the next start becomes a clean download owner.
|
|
110
110
|
|
|
111
|
+
## v6.4.0 (schema v14, unchanged): `hybridSearch` default = rank fusion, summaries opt-in
|
|
112
|
+
|
|
113
|
+
(Published first as `6.4.0-rc.1` on the `next` dist-tag; promoted to `latest` after the published artifact passed a
|
|
114
|
+
canary against a backup copy of a real project database — see the README changelog for what was checked.)
|
|
115
|
+
|
|
116
|
+
**What changed.** (1) The per-result summary path runs only with `RAG_MEMORY_SEARCH_SUMMARIES=on` (it used to
|
|
117
|
+
run unless the variable was `off`; `off` still means off). (2) With summaries off and `useGraph: false` — the
|
|
118
|
+
default call — results are ranked by reciprocal rank fusion of the vector list and the FTS5 list:
|
|
119
|
+
`relevance_score = 1/(60 + vector rank) + 1/(60 + FTS rank)`, a list a chunk is absent from contributes 0.
|
|
120
|
+
Healthy-path candidate gathering and depth are unchanged. If vector search fails after an earlier query variant
|
|
121
|
+
succeeded, the call now discards those partial vector candidates and returns a true FTS-only result (the previous
|
|
122
|
+
version could keep them while reporting `fts-only`). `summaries=on` or `useGraph: true` keep the 6.3.2 formula
|
|
123
|
+
(`max(vector_similarity, summary relevance) + graph boost + FTS term`) unchanged.
|
|
124
|
+
|
|
125
|
+
**Why.** Measured 2026-10-03 on the frozen eval snapshots (spec `specs/changes/search-fusion-rrf/proposal.md`):
|
|
126
|
+
the summary path embedded ~400 sentence fragments per search (median 121 s) and its unbounded context boost let
|
|
127
|
+
vector-0 chunks take rank 1 (known-item hit@1 9/10 with summaries off vs 4/10 on). With summaries off, a chunk
|
|
128
|
+
found only by FTS scored at most 0.0164 against ~0.4-0.6 for every vector candidate, so exact-identifier
|
|
129
|
+
queries surfaced their target in the top 10 for 7/20 queries although FTS ranked it first for 17/20. Rank fusion:
|
|
130
|
+
18/20, and worse than the old formula on 0 of 203 queries across three corpora.
|
|
131
|
+
|
|
132
|
+
**Query input (same release).** With the default model (bge-m3) queries are embedded as raw text; a custom
|
|
133
|
+
`EMBEDDING_MODEL` keeps the previous query instruction (the evidence below is for bge-m3 only). Up to 6.3.2 the loader prepended the bge-v1.5
|
|
134
|
+
instruction `Represent this sentence for searching relevant passages: ` to every query (hybridSearch, searchNodes,
|
|
135
|
+
graph seeds) while stored vectors were embedded without it; the bge-m3 model card says the model needs no query
|
|
136
|
+
instruction. Measured on the frozen snapshots: hybridSearch paraphrase hit@10 7 -> 9 / 20 and MRR 0.217 -> 0.275,
|
|
137
|
+
identifier hit@1 7 -> 8, known-item unchanged on hub / uap and hit@1 +1 on hal; searchNodes known-item (40 entities per
|
|
138
|
+
corpus) hit@10 unchanged, hit@1 -1 / -1 / +1. No re-index: only query vectors change; rolling back means a restart.
|
|
139
|
+
`server_meta.query_prefix_version` is a diagnostic marker written at init (2 = raw queries with the default model,
|
|
140
|
+
1 = instruction); it does not prove what the last query used.
|
|
141
|
+
|
|
142
|
+
**What a caller notices.** On the default call `relevance_score` is a rank score — at most 2/61 ≈ 0.0328, no lower
|
|
143
|
+
bound (a chunk in one list at rank r gets 1/(60+r)), comparable only within one call; do not threshold it against
|
|
144
|
+
old values or across queries/modes. `vector_similarity` and `fts_boost` keep their meaning. `content_summary`
|
|
145
|
+
/ `key_highlight` are preview slices unless summaries are turned on. The fragment-summary work is gone from default
|
|
146
|
+
searches: measured query-cached medians were 20 / 10 / 6 ms on the frozen hub / uap / hal runs; with the query
|
|
147
|
+
embedding cache cleared before every call (one Mac, final build) medians were about 220 / 228 /
|
|
148
|
+
203 ms (max 888 ms). Other machines and corpora are unmeasured — this is not a universal millisecond guarantee. With
|
|
149
|
+
`useGraph: true` and the variable unset, summaries are now off; set `RAG_MEMORY_SEARCH_SUMMARIES=on` to reproduce
|
|
150
|
+
the previous summary-enabled graph path.
|
|
151
|
+
|
|
152
|
+
**Fleet rollout.** No migration. Recommended like v5.3.0: publish an rc on the `next` dist-tag first, run it
|
|
153
|
+
against a real project database (identifier query + known-item probe), then promote to `latest`.
|
|
154
|
+
Regression locks: `test/search-fusion-rrf.test.mjs`, `test/search-summaries-off.test.mjs`, and
|
|
155
|
+
`test/graph-context-explain.test.mjs` (legacy path byte-identical with summaries on).
|
|
156
|
+
|
|
111
157
|
## v5.3.0 (schema v14, unchanged): `hybridSearch` graph re-ranking is opt-in
|
|
112
158
|
|
|
113
159
|
**What changed.** `useGraph` defaults to `false` (was `true`) — in the manager signature, the tool JSON
|
|
@@ -207,8 +253,10 @@ the real v14 (this is exactly how code-v8 never ran in production).
|
|
|
207
253
|
**Diagnostic env (v5)**: `RAG_MEMORY_SEARCH_SUMMARIES=off` disables the per-result
|
|
208
254
|
sentence-similarity summaries in `hybridSearch` (which embed every sentence of every
|
|
209
255
|
candidate — 100+ inferences, 90-120s cold per search, measured). Off = preview-slice
|
|
210
|
-
summaries,
|
|
211
|
-
|
|
256
|
+
summaries, the internal summary relevance is 0 (the response's `relevance_score` is still the final score) and
|
|
257
|
+
ranking rests on vector similarity + boosts. **Superseded by the next
|
|
258
|
+
release: summaries are off by default and opt-in with `=on`** (see the section above). The 3-arm release
|
|
259
|
+
harness sets this uniformly across all arms.
|
|
212
260
|
|
|
213
261
|
## v3.6 breaking response changes
|
|
214
262
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rag-memory-epf-mcp",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=24"
|
|
6
6
|
},
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"prepare": "npm run build",
|
|
46
46
|
"watch": "tsc --watch",
|
|
47
47
|
"verify:invariants": "node test/chunk-invariants.test.mjs",
|
|
48
|
-
"verify:engine": "node test/engine-smoke.test.mjs && node test/launch-smoke.test.mjs && node test/sync-atomicity.test.mjs && node test/dedup.test.mjs && node test/search-degradation.test.mjs && node test/entity-embed-cap.test.mjs && node test/migration12.test.mjs && node test/model-cache.test.mjs && node test/embedding-gate.test.mjs && node test/lazy-boot.test.mjs && node test/reconciliation.test.mjs && node test/backfill.test.mjs && node test/fts-query.test.mjs && node test/search-contracts.test.mjs && node test/tool-contracts.test.mjs && node test/bounded-exit.test.mjs && node test/observation-schema.test.mjs && node test/search-graph-default.test.mjs && node test/observation-migration.test.mjs && node test/observation-lifecycle.test.mjs && node test/observation-contracts.test.mjs && node test/observation-search.test.mjs && node test/observation-cascade.test.mjs && node test/observation-realdata.test.mjs && node test/chunker-c.test.mjs && node test/migration14.test.mjs && node test/chunk-params-validation.test.mjs && node test/vector-reuse.test.mjs && node test/entity-range-linking.test.mjs && node test/alias-link-gate.test.mjs && node test/entity-name-boundary.test.mjs && node test/stats-chunking.test.mjs && node test/migration14-realdata.test.mjs && node test/migration14-realdata-sync.test.mjs && node test/search-summaries-off.test.mjs && node test/document-return-contracts.test.mjs && node test/observation-date-prefix.test.mjs && node test/delete-entities-cascade.test.mjs && node test/delete-entities-kg-hygiene.test.mjs && node test/backup-publish-portable.test.mjs && node test/graph-context-explain.test.mjs && node test/eval-graph-role-libs.test.mjs && node test/eval-graph-role-t5b.test.mjs && node --test test/eval-graph-role-t8-fix.test.mjs && node --test test/eval-graph-role-t7-upstream.test.mjs && node --test test/eval-graph-role-t11-decision.test.mjs && node --test test/eval-graph-role-prereq-fix.test.mjs && node test/db-path.test.mjs && node test/mmap-option.test.mjs && node test/wal-exit.test.mjs && node test/wal-sidecar-guard.test.mjs",
|
|
48
|
+
"verify:engine": "node test/engine-smoke.test.mjs && node test/launch-smoke.test.mjs && node test/sync-atomicity.test.mjs && node test/dedup.test.mjs && node test/search-degradation.test.mjs && node test/entity-embed-cap.test.mjs && node test/migration12.test.mjs && node test/model-cache.test.mjs && node test/embedding-gate.test.mjs && node test/lazy-boot.test.mjs && node test/reconciliation.test.mjs && node test/backfill.test.mjs && node test/fts-query.test.mjs && node test/search-contracts.test.mjs && node test/tool-contracts.test.mjs && node test/bounded-exit.test.mjs && node test/observation-schema.test.mjs && node test/search-graph-default.test.mjs && node test/observation-migration.test.mjs && node test/observation-lifecycle.test.mjs && node test/observation-contracts.test.mjs && node test/observation-search.test.mjs && node test/observation-cascade.test.mjs && node test/observation-realdata.test.mjs && node test/chunker-c.test.mjs && node test/migration14.test.mjs && node test/chunk-params-validation.test.mjs && node test/vector-reuse.test.mjs && node test/entity-range-linking.test.mjs && node test/alias-link-gate.test.mjs && node test/entity-name-boundary.test.mjs && node test/stats-chunking.test.mjs && node test/migration14-realdata.test.mjs && node test/migration14-realdata-sync.test.mjs && node test/search-summaries-off.test.mjs && node test/search-fusion-rrf.test.mjs && node test/query-input.test.mjs && node test/document-return-contracts.test.mjs && node test/observation-date-prefix.test.mjs && node test/delete-entities-cascade.test.mjs && node test/delete-entities-kg-hygiene.test.mjs && node test/backup-publish-portable.test.mjs && node test/graph-context-explain.test.mjs && node test/eval-graph-role-libs.test.mjs && node test/eval-graph-role-t5b.test.mjs && node --test test/eval-graph-role-t8-fix.test.mjs && node --test test/eval-graph-role-t7-upstream.test.mjs && node --test test/eval-graph-role-t11-decision.test.mjs && node --test test/eval-graph-role-prereq-fix.test.mjs && node test/db-path.test.mjs && node test/mmap-option.test.mjs && node test/wal-exit.test.mjs && node test/wal-sidecar-guard.test.mjs",
|
|
49
49
|
"test": "npm run build && npm run verify:invariants && npm run verify:engine",
|
|
50
50
|
"prepublishOnly": "npm run build && npm run verify:invariants && npm run verify:engine"
|
|
51
51
|
},
|