@mcp-abap-adt/llm-agent 26.0.0 → 28.0.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 +2 -0
- package/dist/credentials/static.d.ts +9 -0
- package/dist/credentials/static.d.ts.map +1 -0
- package/dist/credentials/static.js +12 -0
- package/dist/credentials/static.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/builder.d.ts +11 -1
- package/dist/interfaces/builder.d.ts.map +1 -1
- package/dist/interfaces/collect-server-descriptors.d.ts +12 -0
- package/dist/interfaces/collect-server-descriptors.d.ts.map +1 -0
- package/dist/interfaces/collect-server-descriptors.js +19 -0
- package/dist/interfaces/collect-server-descriptors.js.map +1 -0
- package/dist/interfaces/index.d.ts +3 -2
- package/dist/interfaces/index.d.ts.map +1 -1
- package/dist/interfaces/index.js.map +1 -1
- package/dist/interfaces/mcp-connection-strategy.d.ts +29 -2
- package/dist/interfaces/mcp-connection-strategy.d.ts.map +1 -1
- package/dist/interfaces/mcp-server-from-factory.d.ts +15 -0
- package/dist/interfaces/mcp-server-from-factory.d.ts.map +1 -0
- package/dist/interfaces/mcp-server-from-factory.js +37 -0
- package/dist/interfaces/mcp-server-from-factory.js.map +1 -0
- package/dist/interfaces/mcp-server.d.ts +24 -0
- package/dist/interfaces/mcp-server.d.ts.map +1 -0
- package/dist/interfaces/mcp-server.js +2 -0
- package/dist/interfaces/mcp-server.js.map +1 -0
- package/dist/interfaces/pipeline-plugin.d.ts +16 -6
- package/dist/interfaces/pipeline-plugin.d.ts.map +1 -1
- package/dist/interfaces/plugin.d.ts +11 -3
- package/dist/interfaces/plugin.d.ts.map +1 -1
- package/dist/interfaces/rag.d.ts +124 -21
- package/dist/interfaces/rag.d.ts.map +1 -1
- package/dist/interfaces/rag.js.map +1 -1
- package/dist/interfaces/tool-catalog.d.ts +4 -2
- package/dist/interfaces/tool-catalog.d.ts.map +1 -1
- package/dist/interfaces/tool-catalog.js.map +1 -1
- package/dist/interfaces/types.d.ts +2 -1
- package/dist/interfaces/types.d.ts.map +1 -1
- package/dist/interfaces/types.js.map +1 -1
- package/dist/llm/base-llm-provider.d.ts +29 -4
- package/dist/llm/base-llm-provider.d.ts.map +1 -1
- package/dist/llm/base-llm-provider.js +45 -9
- package/dist/llm/base-llm-provider.js.map +1 -1
- package/dist/logger/normalise-logger.d.ts +28 -0
- package/dist/logger/normalise-logger.d.ts.map +1 -0
- package/dist/logger/normalise-logger.js +50 -0
- package/dist/logger/normalise-logger.js.map +1 -0
- package/dist/logger/text-logger.d.ts +14 -0
- package/dist/logger/text-logger.d.ts.map +1 -0
- package/dist/logger/text-logger.js +2 -0
- package/dist/logger/text-logger.js.map +1 -0
- package/dist/policy/fallback-llm-call-strategy.d.ts +3 -3
- package/dist/policy/fallback-llm-call-strategy.d.ts.map +1 -1
- package/dist/policy/fallback-llm-call-strategy.js +3 -2
- package/dist/policy/fallback-llm-call-strategy.js.map +1 -1
- package/dist/rag/catalog/index.d.ts +2 -0
- package/dist/rag/catalog/index.d.ts.map +1 -0
- package/dist/rag/catalog/index.js +2 -0
- package/dist/rag/catalog/index.js.map +1 -0
- package/dist/rag/catalog/validation.d.ts +56 -0
- package/dist/rag/catalog/validation.d.ts.map +1 -0
- package/dist/rag/catalog/validation.js +168 -0
- package/dist/rag/catalog/validation.js.map +1 -0
- package/dist/rag/corrections/errors.d.ts +47 -0
- package/dist/rag/corrections/errors.d.ts.map +1 -1
- package/dist/rag/corrections/errors.js +73 -0
- package/dist/rag/corrections/errors.js.map +1 -1
- package/dist/rag/identity-filter.d.ts +19 -0
- package/dist/rag/identity-filter.d.ts.map +1 -0
- package/dist/rag/identity-filter.js +31 -0
- package/dist/rag/identity-filter.js.map +1 -0
- package/dist/rag/in-memory-rag.d.ts +3 -1
- package/dist/rag/in-memory-rag.d.ts.map +1 -1
- package/dist/rag/in-memory-rag.js +20 -15
- package/dist/rag/in-memory-rag.js.map +1 -1
- package/dist/rag/index.d.ts +3 -0
- package/dist/rag/index.d.ts.map +1 -1
- package/dist/rag/index.js +2 -0
- package/dist/rag/index.js.map +1 -1
- package/dist/rag/mcp-tools/index.d.ts +1 -1
- package/dist/rag/mcp-tools/index.d.ts.map +1 -1
- package/dist/rag/mcp-tools/index.js.map +1 -1
- package/dist/rag/mcp-tools/rag-collection-tools.d.ts +36 -5
- package/dist/rag/mcp-tools/rag-collection-tools.d.ts.map +1 -1
- package/dist/rag/mcp-tools/rag-collection-tools.js +121 -58
- package/dist/rag/mcp-tools/rag-collection-tools.js.map +1 -1
- package/dist/rag/providers/base-provider.d.ts +8 -6
- package/dist/rag/providers/base-provider.d.ts.map +1 -1
- package/dist/rag/providers/base-provider.js +18 -0
- package/dist/rag/providers/base-provider.js.map +1 -1
- package/dist/rag/providers/in-memory-rag-provider.d.ts +4 -7
- package/dist/rag/providers/in-memory-rag-provider.d.ts.map +1 -1
- package/dist/rag/providers/in-memory-rag-provider.js +11 -4
- package/dist/rag/providers/in-memory-rag-provider.js.map +1 -1
- package/dist/rag/providers/vector-rag-provider.d.ts +4 -7
- package/dist/rag/providers/vector-rag-provider.d.ts.map +1 -1
- package/dist/rag/providers/vector-rag-provider.js +11 -4
- package/dist/rag/providers/vector-rag-provider.js.map +1 -1
- package/dist/rag/registry/index.d.ts +1 -0
- package/dist/rag/registry/index.d.ts.map +1 -1
- package/dist/rag/registry/index.js +1 -0
- package/dist/rag/registry/index.js.map +1 -1
- package/dist/rag/registry/simple-rag-registry.d.ts +74 -30
- package/dist/rag/registry/simple-rag-registry.d.ts.map +1 -1
- package/dist/rag/registry/simple-rag-registry.js +265 -100
- package/dist/rag/registry/simple-rag-registry.js.map +1 -1
- package/dist/rag/registry/store-key.d.ts +15 -0
- package/dist/rag/registry/store-key.d.ts.map +1 -0
- package/dist/rag/registry/store-key.js +25 -0
- package/dist/rag/registry/store-key.js.map +1 -0
- package/dist/rag/search-strategy.d.ts +9 -0
- package/dist/rag/search-strategy.d.ts.map +1 -1
- package/dist/rag/search-strategy.js +49 -22
- package/dist/rag/search-strategy.js.map +1 -1
- package/dist/rag/tokenizer.d.ts +17 -0
- package/dist/rag/tokenizer.d.ts.map +1 -0
- package/dist/rag/tokenizer.js +38 -0
- package/dist/rag/tokenizer.js.map +1 -0
- package/dist/rag/vector-rag.d.ts +2 -2
- package/dist/rag/vector-rag.d.ts.map +1 -1
- package/dist/rag/vector-rag.js +29 -21
- package/dist/rag/vector-rag.js.map +1 -1
- package/dist/resilience/embedder-resilience.d.ts +2 -2
- package/dist/resilience/embedder-resilience.d.ts.map +1 -1
- package/dist/resilience/embedder-resilience.js +3 -1
- package/dist/resilience/embedder-resilience.js.map +1 -1
- package/dist/testing/rag-filter-conformance.d.ts +60 -0
- package/dist/testing/rag-filter-conformance.d.ts.map +1 -0
- package/dist/testing/rag-filter-conformance.js +379 -0
- package/dist/testing/rag-filter-conformance.js.map +1 -0
- package/dist/types.d.ts +11 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -2
- package/dist/interfaces/failure-strategy.d.ts +0 -95
- package/dist/interfaces/failure-strategy.d.ts.map +0 -1
- package/dist/interfaces/failure-strategy.js +0 -96
- package/dist/interfaces/failure-strategy.js.map +0 -1
- package/dist/llm/rate-limit.d.ts +0 -165
- package/dist/llm/rate-limit.d.ts.map +0 -1
- package/dist/llm/rate-limit.js +0 -394
- package/dist/llm/rate-limit.js.map +0 -1
- package/dist/resilience/status.d.ts +0 -29
- package/dist/resilience/status.d.ts.map +0 -1
- package/dist/resilience/status.js +0 -51
- package/dist/resilience/status.js.map +0 -1
|
@@ -12,24 +12,50 @@ function cosine(a, b) {
|
|
|
12
12
|
}
|
|
13
13
|
return dot / (Math.sqrt(na) * Math.sqrt(nb) || 1);
|
|
14
14
|
}
|
|
15
|
-
function
|
|
16
|
-
const docTokens =
|
|
15
|
+
function keywordStats(candidates, tokenize) {
|
|
16
|
+
const docTokens = candidates.map((c) => tokenize(c.text));
|
|
17
|
+
const df = new Map();
|
|
18
|
+
let total = 0;
|
|
19
|
+
for (const tokens of docTokens) {
|
|
20
|
+
total += tokens.length;
|
|
21
|
+
for (const t of new Set(tokens))
|
|
22
|
+
df.set(t, (df.get(t) ?? 0) + 1);
|
|
23
|
+
}
|
|
24
|
+
const n = docTokens.length;
|
|
25
|
+
return { docTokens, df, n, avgDocLength: n === 0 ? 0 : total / n };
|
|
26
|
+
}
|
|
27
|
+
function bm25(queryTokens, docIdx, stats) {
|
|
28
|
+
const docTokens = stats.docTokens[docIdx];
|
|
17
29
|
if (queryTokens.length === 0 || docTokens.length === 0)
|
|
18
30
|
return 0;
|
|
19
|
-
const avgDocLength =
|
|
20
|
-
const n =
|
|
31
|
+
const avgDocLength = stats.avgDocLength || 1;
|
|
32
|
+
const n = stats.n || 1;
|
|
21
33
|
const k1 = 1.2;
|
|
22
34
|
const b = 0.75;
|
|
23
35
|
let score = 0;
|
|
24
36
|
for (const token of new Set(queryTokens)) {
|
|
25
|
-
const df =
|
|
37
|
+
const df = stats.df.get(token) ?? 0;
|
|
26
38
|
const idf = Math.log((n - df + 0.5) / (df + 0.5) + 1);
|
|
27
39
|
const tf = docTokens.filter((t) => t === token).length;
|
|
28
40
|
const tfScored = (tf * (k1 + 1)) /
|
|
29
41
|
(tf + k1 * (1 - b + b * (docTokens.length / avgDocLength)));
|
|
30
42
|
score += idf * tfScored;
|
|
31
43
|
}
|
|
32
|
-
return
|
|
44
|
+
return score;
|
|
45
|
+
}
|
|
46
|
+
/** Raw BM25 of every candidate, in candidate order. */
|
|
47
|
+
function bm25Scores(query, candidates, context) {
|
|
48
|
+
const queryTokens = context.tokenize(query.text);
|
|
49
|
+
const stats = keywordStats(candidates, context.tokenize);
|
|
50
|
+
return candidates.map((_c, i) => bm25(queryTokens, i, stats));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Raw BM25 is unbounded; the historical absolute scale, kept for the score
|
|
54
|
+
* `Bm25OnlyStrategy` reports (ranking uses the raw value, so the clamp no
|
|
55
|
+
* longer flattens strong matches into a tie).
|
|
56
|
+
*/
|
|
57
|
+
function bm25Absolute(raw) {
|
|
58
|
+
return Math.min(raw / 5, 1.0);
|
|
33
59
|
}
|
|
34
60
|
// ---------------------------------------------------------------------------
|
|
35
61
|
// WeightedFusionStrategy
|
|
@@ -43,13 +69,17 @@ export class WeightedFusionStrategy {
|
|
|
43
69
|
this.keywordWeight = config?.keywordWeight ?? 0.3;
|
|
44
70
|
}
|
|
45
71
|
score(query, candidates, context) {
|
|
46
|
-
|
|
72
|
+
// BM25 normalised per query over these candidates (divided by the best
|
|
73
|
+
// one), so both parts are in [0, 1] and the weights mean what they say:
|
|
74
|
+
// the best keyword match contributes exactly `keywordWeight`.
|
|
75
|
+
const raw = bm25Scores(query, candidates, context);
|
|
76
|
+
const max = Math.max(0, ...raw);
|
|
47
77
|
return candidates
|
|
48
|
-
.map((c) => ({
|
|
78
|
+
.map((c, i) => ({
|
|
49
79
|
text: c.text,
|
|
50
80
|
metadata: c.metadata,
|
|
51
81
|
score: cosine(query.vector, c.vector) * this.vectorWeight +
|
|
52
|
-
|
|
82
|
+
(max > 0 ? raw[i] / max : 0) * this.keywordWeight,
|
|
53
83
|
}))
|
|
54
84
|
.sort((a, b) => b.score - a.score);
|
|
55
85
|
}
|
|
@@ -72,26 +102,22 @@ export class RrfStrategy {
|
|
|
72
102
|
this.k = config?.k ?? 60;
|
|
73
103
|
}
|
|
74
104
|
score(query, candidates, context) {
|
|
75
|
-
const queryTokens = context.tokenize(query.text);
|
|
76
105
|
// Score by each method independently
|
|
77
106
|
const vectorScores = candidates.map((c, i) => ({
|
|
78
107
|
idx: i,
|
|
79
108
|
score: cosine(query.vector, c.vector),
|
|
80
109
|
}));
|
|
81
|
-
const
|
|
82
|
-
idx: i,
|
|
83
|
-
score: bm25(queryTokens, c.text, context),
|
|
84
|
-
}));
|
|
110
|
+
const bm25Ranked = bm25Scores(query, candidates, context).map((score, idx) => ({ idx, score }));
|
|
85
111
|
// Sort each list desc to get ranks
|
|
86
112
|
vectorScores.sort((a, b) => b.score - a.score);
|
|
87
|
-
|
|
113
|
+
bm25Ranked.sort((a, b) => b.score - a.score);
|
|
88
114
|
// Build rank maps (0-indexed rank)
|
|
89
115
|
const vectorRank = new Map();
|
|
90
116
|
const bm25Rank = new Map();
|
|
91
117
|
for (let i = 0; i < vectorScores.length; i++)
|
|
92
118
|
vectorRank.set(vectorScores[i].idx, i);
|
|
93
|
-
for (let i = 0; i <
|
|
94
|
-
bm25Rank.set(
|
|
119
|
+
for (let i = 0; i < bm25Ranked.length; i++)
|
|
120
|
+
bm25Rank.set(bm25Ranked[i].idx, i);
|
|
95
121
|
// Compute RRF score
|
|
96
122
|
return candidates
|
|
97
123
|
.map((c, i) => ({
|
|
@@ -132,14 +158,15 @@ export class VectorOnlyStrategy {
|
|
|
132
158
|
export class Bm25OnlyStrategy {
|
|
133
159
|
name = 'bm25-only';
|
|
134
160
|
score(query, candidates, context) {
|
|
135
|
-
const
|
|
161
|
+
const raw = bm25Scores(query, candidates, context);
|
|
136
162
|
return candidates
|
|
137
|
-
.map((c) => ({
|
|
163
|
+
.map((c, i) => ({ c, raw: raw[i] }))
|
|
164
|
+
.sort((a, b) => b.raw - a.raw)
|
|
165
|
+
.map(({ c, raw: r }) => ({
|
|
138
166
|
text: c.text,
|
|
139
167
|
metadata: c.metadata,
|
|
140
|
-
score:
|
|
141
|
-
}))
|
|
142
|
-
.sort((a, b) => b.score - a.score);
|
|
168
|
+
score: bm25Absolute(r),
|
|
169
|
+
}));
|
|
143
170
|
}
|
|
144
171
|
}
|
|
145
172
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-strategy.js","sourceRoot":"","sources":["../../src/rag/search-strategy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"search-strategy.js","sourceRoot":"","sources":["../../src/rag/search-strategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keyword tokenizer both in-memory stores use — for records AND queries,
|
|
3
|
+
* so the two sides always agree.
|
|
4
|
+
*
|
|
5
|
+
* - Splits on anything that is not an ASCII letter, digit or underscore, and
|
|
6
|
+
* lower-cases; one-character tokens are dropped.
|
|
7
|
+
* - An identifier is split into its parts — camelCase / PascalCase (an acronym
|
|
8
|
+
* run ends before the next capitalised word: `GetXMLParser` → get, xml,
|
|
9
|
+
* parser) and snake_case — and the whole identifier is kept as well, so
|
|
10
|
+
* `ReadFunctionInclude` matches both "function include" and itself.
|
|
11
|
+
*
|
|
12
|
+
* No suffix normalisation (plural / -ing / -ed stemming): measured on the
|
|
13
|
+
* tool-retrieval eval (scripts/rag-eval), even a plural-only rule lowered MRR
|
|
14
|
+
* on the keyword-only and the Ollama-embedder in-memory configs.
|
|
15
|
+
*/
|
|
16
|
+
export declare function tokenizeSearchText(text: string): string[];
|
|
17
|
+
//# sourceMappingURL=tokenizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../src/rag/tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBzD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keyword tokenizer both in-memory stores use — for records AND queries,
|
|
3
|
+
* so the two sides always agree.
|
|
4
|
+
*
|
|
5
|
+
* - Splits on anything that is not an ASCII letter, digit or underscore, and
|
|
6
|
+
* lower-cases; one-character tokens are dropped.
|
|
7
|
+
* - An identifier is split into its parts — camelCase / PascalCase (an acronym
|
|
8
|
+
* run ends before the next capitalised word: `GetXMLParser` → get, xml,
|
|
9
|
+
* parser) and snake_case — and the whole identifier is kept as well, so
|
|
10
|
+
* `ReadFunctionInclude` matches both "function include" and itself.
|
|
11
|
+
*
|
|
12
|
+
* No suffix normalisation (plural / -ing / -ed stemming): measured on the
|
|
13
|
+
* tool-retrieval eval (scripts/rag-eval), even a plural-only rule lowered MRR
|
|
14
|
+
* on the keyword-only and the Ollama-embedder in-memory configs.
|
|
15
|
+
*/
|
|
16
|
+
export function tokenizeSearchText(text) {
|
|
17
|
+
const out = [];
|
|
18
|
+
for (const word of text.split(/[^A-Za-z0-9_]+/)) {
|
|
19
|
+
if (word.length === 0)
|
|
20
|
+
continue;
|
|
21
|
+
const parts = word
|
|
22
|
+
.split('_')
|
|
23
|
+
.flatMap((p) => p.split(/(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/))
|
|
24
|
+
.filter((p) => p.length > 0);
|
|
25
|
+
if (parts.length > 1) {
|
|
26
|
+
const whole = word.toLowerCase();
|
|
27
|
+
if (whole.length > 1)
|
|
28
|
+
out.push(whole);
|
|
29
|
+
}
|
|
30
|
+
for (const p of parts) {
|
|
31
|
+
const t = p.toLowerCase();
|
|
32
|
+
if (t.length > 1)
|
|
33
|
+
out.push(t);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/rag/tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAChC,MAAM,KAAK,GAAG,IAAI;aACf,KAAK,CAAC,GAAG,CAAC;aACV,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACb,CAAC,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAC3D;aACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/rag/vector-rag.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { type CallOptions, RagError, type RagMetadata, type RagResult, type Resu
|
|
|
4
4
|
import type { IDocumentEnricher, IQueryPreprocessor } from './preprocessor.js';
|
|
5
5
|
import type { ISearchStrategy } from './search-strategy.js';
|
|
6
6
|
export interface VectorRagConfig {
|
|
7
|
-
/** Cosine similarity threshold for dedup
|
|
7
|
+
/** Cosine similarity threshold for dedup of records written without an id
|
|
8
|
+
* (a record with an id is replaced only by the same id). Default: 0.92 */
|
|
8
9
|
dedupThreshold?: number;
|
|
9
10
|
/** Namespace for this store. */
|
|
10
11
|
namespace?: string;
|
|
@@ -22,7 +23,6 @@ export interface VectorRagConfig {
|
|
|
22
23
|
export declare class VectorRag implements IRag {
|
|
23
24
|
private readonly embedder;
|
|
24
25
|
private records;
|
|
25
|
-
private readonly index;
|
|
26
26
|
private readonly dedupThreshold;
|
|
27
27
|
private readonly namespace?;
|
|
28
28
|
private vectorWeight;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector-rag.d.ts","sourceRoot":"","sources":["../../src/rag/vector-rag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EACL,KAAK,WAAW,EAChB,QAAQ,EACR,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,MAAM,EACZ,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"vector-rag.d.ts","sourceRoot":"","sources":["../../src/rag/vector-rag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EACL,KAAK,WAAW,EAChB,QAAQ,EACR,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,MAAM,EACZ,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE/E,OAAO,KAAK,EAIV,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAU9B,MAAM,WAAW,eAAe;IAC9B;+EAC2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,wFAAwF;IACxF,kBAAkB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC1C,uEAAuE;IACvE,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACzC;AAED,qBAAa,SAAU,YAAW,IAAI;IAWlC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAV3B,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAuB;IAC1D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAsB;gBAGrC,QAAQ,EAAE,SAAS,EACpC,MAAM,GAAE,eAAoB;IAgB9B,4DAA4D;IAC5D,aAAa,CAAC,MAAM,EAAE;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GAAG,IAAI;IAaR,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,MAAM;IAYd,OAAO,CAAC,iBAAiB;IA4CnB,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,WAAW,EACrB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IA2B5B,iBAAiB,CACrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,WAAW,EACrB,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAS5B,KAAK,CACT,SAAS,EAAE,eAAe,EAC1B,CAAC,EAAE,MAAM,EACT,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,QAAQ,CAAC,CAAC;IA+EnC,WAAW,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAenE,OAAO,CACX,EAAE,EAAE,MAAM,EACV,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC;IAY9C,MAAM,IAAI,iBAAiB;IA+B3B,KAAK,IAAI,IAAI;CAGd"}
|
package/dist/rag/vector-rag.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { RagError, } from '../interfaces/types.js';
|
|
2
|
+
import { matchesRagIdentity, ragIdentityFilter } from './identity-filter.js';
|
|
2
3
|
import { InvertedIndex } from './inverted-index.js';
|
|
3
4
|
import { FallbackQueryEmbedding, QueryEmbedding } from './query-embedding.js';
|
|
4
5
|
import { WeightedFusionStrategy } from './search-strategy.js';
|
|
6
|
+
import { tokenizeSearchText } from './tokenizer.js';
|
|
5
7
|
export class VectorRag {
|
|
6
8
|
embedder;
|
|
7
9
|
records = [];
|
|
8
|
-
index = new InvertedIndex();
|
|
9
10
|
dedupThreshold;
|
|
10
11
|
namespace;
|
|
11
12
|
vectorWeight;
|
|
@@ -42,10 +43,7 @@ export class VectorRag {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
tokenize(s) {
|
|
45
|
-
return s
|
|
46
|
-
.toLowerCase()
|
|
47
|
-
.split(/[^a-z0-9]/)
|
|
48
|
-
.filter((t) => t.length > 1);
|
|
46
|
+
return tokenizeSearchText(s);
|
|
49
47
|
}
|
|
50
48
|
cosine(a, b) {
|
|
51
49
|
let dot = 0;
|
|
@@ -59,7 +57,6 @@ export class VectorRag {
|
|
|
59
57
|
return dot / (Math.sqrt(na) * Math.sqrt(nb) || 1);
|
|
60
58
|
}
|
|
61
59
|
upsertKnownVector(text, vector, metadata) {
|
|
62
|
-
const newTokens = this.tokenize(text);
|
|
63
60
|
// Idempotent upsert: if metadata.id matches, replace in-place
|
|
64
61
|
if (metadata.id) {
|
|
65
62
|
for (let i = 0; i < this.records.length; i++) {
|
|
@@ -67,25 +64,25 @@ export class VectorRag {
|
|
|
67
64
|
if (slot === null)
|
|
68
65
|
continue;
|
|
69
66
|
if (slot.metadata.id === metadata.id) {
|
|
70
|
-
const oldTokens = this.tokenize(slot.text);
|
|
71
67
|
slot.text = text;
|
|
72
68
|
slot.vector = vector;
|
|
73
69
|
slot.metadata = { ...slot.metadata, ...metadata };
|
|
74
|
-
this.index.update(i, oldTokens, newTokens);
|
|
75
70
|
return { ok: true, value: undefined };
|
|
76
71
|
}
|
|
77
72
|
}
|
|
78
73
|
}
|
|
79
|
-
|
|
74
|
+
// Similarity dedup only between records written WITHOUT an id: a record
|
|
75
|
+
// with an id is replaced only by the same id (above). Merging on
|
|
76
|
+
// similarity alone let a near-identical tool record overwrite another
|
|
77
|
+
// tool's record (ReadFunctionInclude vanished under ReadFunctionGroup).
|
|
78
|
+
for (let i = 0; !metadata.id && i < this.records.length; i++) {
|
|
80
79
|
const slot = this.records[i];
|
|
81
|
-
if (slot === null)
|
|
80
|
+
if (slot === null || slot.metadata.id)
|
|
82
81
|
continue;
|
|
83
82
|
if (this.cosine(slot.vector, vector) >= this.dedupThreshold) {
|
|
84
|
-
const oldTokens = this.tokenize(slot.text);
|
|
85
83
|
slot.text = text;
|
|
86
84
|
slot.vector = vector;
|
|
87
85
|
slot.metadata = { ...slot.metadata, ...metadata };
|
|
88
|
-
this.index.update(i, oldTokens, newTokens);
|
|
89
86
|
return { ok: true, value: undefined };
|
|
90
87
|
}
|
|
91
88
|
}
|
|
@@ -93,12 +90,9 @@ export class VectorRag {
|
|
|
93
90
|
const freeIdx = this.records.indexOf(null);
|
|
94
91
|
if (freeIdx !== -1) {
|
|
95
92
|
this.records[freeIdx] = { text, vector, metadata };
|
|
96
|
-
this.index.add(freeIdx, newTokens);
|
|
97
93
|
}
|
|
98
94
|
else {
|
|
99
|
-
const docIdx = this.records.length;
|
|
100
95
|
this.records.push({ text, vector, metadata });
|
|
101
|
-
this.index.add(docIdx, newTokens);
|
|
102
96
|
}
|
|
103
97
|
return { ok: true, value: undefined };
|
|
104
98
|
}
|
|
@@ -156,13 +150,17 @@ export class VectorRag {
|
|
|
156
150
|
: new FallbackQueryEmbedding(embedding, this.embedder);
|
|
157
151
|
const queryVector = await effectiveEmbedding.toVector();
|
|
158
152
|
const targetNamespace = options?.ragFilter?.namespace;
|
|
153
|
+
const identity = ragIdentityFilter(options);
|
|
154
|
+
// Filtered BEFORE the strategy scores and top-k slices, so a scoped
|
|
155
|
+
// query still gets up to k of its own records.
|
|
159
156
|
const filtered = this.records.filter((r) => r !== null &&
|
|
160
157
|
!(r.metadata.ttl !== undefined && r.metadata.ttl < nowSecs) &&
|
|
161
158
|
!(targetNamespace !== undefined &&
|
|
162
159
|
r.metadata.namespace !== targetNamespace) &&
|
|
163
160
|
!(this.namespace !== undefined &&
|
|
164
161
|
r.metadata.namespace !== undefined &&
|
|
165
|
-
r.metadata.namespace !== this.namespace)
|
|
162
|
+
r.metadata.namespace !== this.namespace) &&
|
|
163
|
+
matchesRagIdentity(r.metadata, identity));
|
|
166
164
|
const candidates = filtered.map((r) => ({
|
|
167
165
|
text: r.text,
|
|
168
166
|
vector: r.vector,
|
|
@@ -172,9 +170,22 @@ export class VectorRag {
|
|
|
172
170
|
text: searchText,
|
|
173
171
|
vector: queryVector,
|
|
174
172
|
};
|
|
173
|
+
// Keyword statistics over THESE candidates only, never the whole store
|
|
174
|
+
// — see ISearchContext.index. Built on first read: the built-in
|
|
175
|
+
// strategies compute their own from `candidates` and never read it.
|
|
176
|
+
const tokenize = this.tokenize.bind(this);
|
|
177
|
+
let candidateIndex;
|
|
175
178
|
const context = {
|
|
176
|
-
index
|
|
177
|
-
|
|
179
|
+
get index() {
|
|
180
|
+
if (!candidateIndex) {
|
|
181
|
+
candidateIndex = new InvertedIndex();
|
|
182
|
+
candidates.forEach((c, i) => {
|
|
183
|
+
candidateIndex?.add(i, tokenize(c.text));
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return candidateIndex;
|
|
187
|
+
},
|
|
188
|
+
tokenize,
|
|
178
189
|
};
|
|
179
190
|
const scored = this.strategy
|
|
180
191
|
.score(searchQuery, candidates, context)
|
|
@@ -220,7 +231,6 @@ export class VectorRag {
|
|
|
220
231
|
for (let i = 0; i < this.records.length; i++) {
|
|
221
232
|
const r = this.records[i];
|
|
222
233
|
if (r !== null && r.metadata.id === id) {
|
|
223
|
-
this.index.remove(i, this.tokenize(r.text));
|
|
224
234
|
this.records[i] = null;
|
|
225
235
|
return { ok: true, value: true };
|
|
226
236
|
}
|
|
@@ -229,7 +239,6 @@ export class VectorRag {
|
|
|
229
239
|
},
|
|
230
240
|
clearAll: async () => {
|
|
231
241
|
this.records.length = 0;
|
|
232
|
-
this.index.clear();
|
|
233
242
|
return { ok: true, value: undefined };
|
|
234
243
|
},
|
|
235
244
|
upsertPrecomputedRaw: async (id, text, vector, metadata, options) => {
|
|
@@ -239,7 +248,6 @@ export class VectorRag {
|
|
|
239
248
|
}
|
|
240
249
|
clear() {
|
|
241
250
|
this.records.length = 0;
|
|
242
|
-
this.index.clear();
|
|
243
251
|
}
|
|
244
252
|
}
|
|
245
253
|
//# sourceMappingURL=vector-rag.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector-rag.js","sourceRoot":"","sources":["../../src/rag/vector-rag.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,QAAQ,GAIT,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAO9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"vector-rag.js","sourceRoot":"","sources":["../../src/rag/vector-rag.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* guard would then read a foreign object as ours.
|
|
13
13
|
*/
|
|
14
14
|
import type { IEmbedder } from '../interfaces/rag.js';
|
|
15
|
-
import type {
|
|
15
|
+
import type { AnyLogger } from '../logger/normalise-logger.js';
|
|
16
16
|
import type { EmbedderRetryOptions } from './retry-embedder.js';
|
|
17
17
|
export declare const RESILIENCE_META: unique symbol;
|
|
18
18
|
export interface EmbedderResilienceMetadata {
|
|
@@ -36,7 +36,7 @@ export interface ComposeResilienceOptions {
|
|
|
36
36
|
/** Provider-derived or default cap; never triggers the conflict check. */
|
|
37
37
|
fallbackMaxBatchSize?: number;
|
|
38
38
|
retry?: Partial<EmbedderRetryOptions>;
|
|
39
|
-
logger?:
|
|
39
|
+
logger?: AnyLogger;
|
|
40
40
|
}
|
|
41
41
|
export declare function composeResilientEmbedder(inner: IEmbedder, options?: ComposeResilienceOptions): IEmbedder;
|
|
42
42
|
//# sourceMappingURL=embedder-resilience.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedder-resilience.d.ts","sourceRoot":"","sources":["../../src/resilience/embedder-resilience.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"embedder-resilience.d.ts","sourceRoot":"","sources":["../../src/resilience/embedder-resilience.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAM/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,eAAO,MAAM,eAAe,eAAkD,CAAC;AAE/E,MAAM,WAAW,0BAA0B;IACzC,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,0DAA0D;AAC1D,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,SAAS,GACX,0BAA0B,GAAG,SAAS,CAIxC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EAAE,SAAS,EACZ,IAAI,EAAE,0BAA0B,GAC/B,IAAI,CAON;AAED,MAAM,WAAW,wBAAwB;IACvC,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,wBAAwB,GACjC,SAAS,CAiCX"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* guard would then read a foreign object as ours.
|
|
13
13
|
*/
|
|
14
14
|
import { isBatchEmbedder, isBatchSizeLimited } from '../interfaces/rag.js';
|
|
15
|
+
import { normaliseLogger } from '../logger/normalise-logger.js';
|
|
15
16
|
import { BatchChunkingEmbedder, DEFAULT_MAX_BATCH_SIZE, } from './batch-chunking-embedder.js';
|
|
16
17
|
import { withRetry } from './retry-embedder.js';
|
|
17
18
|
export const RESILIENCE_META = Symbol.for('@mcp-abap-adt/embedder-resilience');
|
|
@@ -36,6 +37,7 @@ export function brandResilient(e, meta) {
|
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
export function composeResilientEmbedder(inner, options) {
|
|
40
|
+
const log = options?.logger ? normaliseLogger(options.logger) : undefined;
|
|
39
41
|
const existing = getResilienceMetadata(inner);
|
|
40
42
|
if (existing) {
|
|
41
43
|
const requested = options?.explicitMaxBatchSize;
|
|
@@ -43,7 +45,7 @@ export function composeResilientEmbedder(inner, options) {
|
|
|
43
45
|
// hides the provider, so a derived value falls to the default and would
|
|
44
46
|
// look like a conflict nobody configured. Only an explicit request counts.
|
|
45
47
|
if (requested !== undefined && requested !== existing.maxBatchSize) {
|
|
46
|
-
|
|
48
|
+
log?.log({
|
|
47
49
|
type: 'warning',
|
|
48
50
|
traceId: 'embedder-resolution',
|
|
49
51
|
message: `Embedder is already composed with maxBatchSize ${String(existing.maxBatchSize)}; ` +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedder-resilience.js","sourceRoot":"","sources":["../../src/resilience/embedder-resilience.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AAO/E,0DAA0D;AAC1D,MAAM,UAAU,qBAAqB,CACnC,CAAY;IAEZ,OAAQ,CAAwD,CAC9D,eAAe,CAChB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,CAAY,EACZ,IAAgC;IAEhC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,eAAe,EAAE;QACxC,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,KAAK;QACnB,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;AACL,CAAC;AAWD,MAAM,UAAU,wBAAwB,CACtC,KAAgB,EAChB,OAAkC;IAElC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,OAAO,EAAE,oBAAoB,CAAC;QAChD,yEAAyE;QACzE,wEAAwE;QACxE,2EAA2E;QAC3E,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC;YACnE,
|
|
1
|
+
{"version":3,"file":"embedder-resilience.js","sourceRoot":"","sources":["../../src/resilience/embedder-resilience.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AAO/E,0DAA0D;AAC1D,MAAM,UAAU,qBAAqB,CACnC,CAAY;IAEZ,OAAQ,CAAwD,CAC9D,eAAe,CAChB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,CAAY,EACZ,IAAgC;IAEhC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,eAAe,EAAE;QACxC,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,KAAK;QACnB,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;AACL,CAAC;AAWD,MAAM,UAAU,wBAAwB,CACtC,KAAgB,EAChB,OAAkC;IAElC,MAAM,GAAG,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,OAAO,EAAE,oBAAoB,CAAC;QAChD,yEAAyE;QACzE,wEAAwE;QACxE,2EAA2E;QAC3E,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC;YACnE,GAAG,EAAE,GAAG,CAAC;gBACP,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,qBAAqB;gBAC9B,OAAO,EACL,kDAAkD,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI;oBACnF,0BAA0B,SAAS,oCAAoC;aAC1E,CAAC,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,GAAG,GACP,OAAO,EAAE,oBAAoB;QAC7B,OAAO,EAAE,oBAAoB;QAC7B,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC;IAE5E,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,YAAY;QAC3B,CAAC,CAAC,IAAI,qBAAqB,CAAC,OAAO,EAAE,GAAG,CAAC;QACzC,CAAC,CAAC,OAAO,CAAC;IAEZ,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpE,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conformance kit for the identity filter every `IRag` store must honour.
|
|
3
|
+
*
|
|
4
|
+
* `query(embedding, k, { ragFilter })` may carry `sessionId` and/or `userId`
|
|
5
|
+
* (the pipeline's `rag-query` stage sets them for `scope: 'session' | 'user'`).
|
|
6
|
+
* A store that ignores them lets one user's records surface in another
|
|
7
|
+
* user's context. The contract:
|
|
8
|
+
*
|
|
9
|
+
* - `ragFilter.sessionId` set → only records whose `metadata.sessionId`
|
|
10
|
+
* equals it; a record without `sessionId` is excluded.
|
|
11
|
+
* - `ragFilter.userId` set → the same for `metadata.userId`.
|
|
12
|
+
* - both set → both must match; neither set → no identity filtering.
|
|
13
|
+
* - the filter applies BEFORE top-k: a filtered query still returns up to `k`
|
|
14
|
+
* matching records.
|
|
15
|
+
*
|
|
16
|
+
* The same kit covers the other two filters every store applies:
|
|
17
|
+
*
|
|
18
|
+
* - `ragFilter.namespace` set → only records whose `metadata.namespace`
|
|
19
|
+
* equals it; a record without `namespace` is excluded. Not set → records of
|
|
20
|
+
* every namespace (for a store configured without a namespace of its own).
|
|
21
|
+
* - `metadata.ttl` (epoch seconds) in the past → the record is expired and
|
|
22
|
+
* never returned; a future or absent `ttl` keeps it.
|
|
23
|
+
* - both apply BEFORE top-k too.
|
|
24
|
+
*
|
|
25
|
+
* Framework-agnostic: each case throws (`node:assert`) on a violation, so a
|
|
26
|
+
* store package runs them under its own test runner:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* for (const c of ragFilterConformanceCases) {
|
|
30
|
+
* it(c.name, () => c.run(async () => new MyRag({ embedder: conformanceEmbedder() })));
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* Every case asks the factory for a FRESH, empty store and seeds it through
|
|
35
|
+
* `writer().upsertRaw`.
|
|
36
|
+
*/
|
|
37
|
+
import type { IEmbedder, IRag } from '../interfaces/rag.js';
|
|
38
|
+
import type { RagMetadata } from '../interfaces/types.js';
|
|
39
|
+
/** A record a conformance case seeds. `metadata.id` identifies it in results. */
|
|
40
|
+
export interface ConformanceRecord {
|
|
41
|
+
id: string;
|
|
42
|
+
text: string;
|
|
43
|
+
metadata: RagMetadata;
|
|
44
|
+
}
|
|
45
|
+
export interface RagFilterConformanceCase {
|
|
46
|
+
readonly name: string;
|
|
47
|
+
run(makeStore: () => Promise<IRag>): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
/** Dimension of {@link conformanceEmbedder}'s vectors. */
|
|
50
|
+
export declare const CONFORMANCE_EMBEDDING_DIM = 64;
|
|
51
|
+
/**
|
|
52
|
+
* Deterministic bag-of-words embedder: every token lands in one of
|
|
53
|
+
* {@link CONFORMANCE_EMBEDDING_DIM} buckets, and the vector is L2-normalised.
|
|
54
|
+
* Texts that share tokens are close; texts that share none are orthogonal —
|
|
55
|
+
* which the top-k case relies on, and which keeps the conformance texts far
|
|
56
|
+
* apart enough that no store's near-duplicate merge folds two records.
|
|
57
|
+
*/
|
|
58
|
+
export declare function conformanceEmbedder(): IEmbedder;
|
|
59
|
+
export declare const ragFilterConformanceCases: readonly RagFilterConformanceCase[];
|
|
60
|
+
//# sourceMappingURL=rag-filter-conformance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rag-filter-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/rag-filter-conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEvE,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED,0DAA0D;AAC1D,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAkB5C;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,CAc/C;AAgCD,eAAO,MAAM,yBAAyB,EAAE,SAAS,wBAAwB,EA8RxE,CAAC"}
|