@eucoder/rag 0.2.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.
Files changed (103) hide show
  1. package/README.md +384 -0
  2. package/dist/ab-testing.d.ts +52 -0
  3. package/dist/ab-testing.d.ts.map +1 -0
  4. package/dist/ab-testing.js +144 -0
  5. package/dist/ab-testing.js.map +1 -0
  6. package/dist/ab-testing.test.d.ts +2 -0
  7. package/dist/ab-testing.test.d.ts.map +1 -0
  8. package/dist/ab-testing.test.js +147 -0
  9. package/dist/ab-testing.test.js.map +1 -0
  10. package/dist/agentic-rag.d.ts +23 -0
  11. package/dist/agentic-rag.d.ts.map +1 -0
  12. package/dist/agentic-rag.js +170 -0
  13. package/dist/agentic-rag.js.map +1 -0
  14. package/dist/agentic-rag.test.d.ts +2 -0
  15. package/dist/agentic-rag.test.d.ts.map +1 -0
  16. package/dist/agentic-rag.test.js +174 -0
  17. package/dist/agentic-rag.test.js.map +1 -0
  18. package/dist/corrective-rag.d.ts +16 -0
  19. package/dist/corrective-rag.d.ts.map +1 -0
  20. package/dist/corrective-rag.js +85 -0
  21. package/dist/corrective-rag.js.map +1 -0
  22. package/dist/corrective-rag.test.d.ts +2 -0
  23. package/dist/corrective-rag.test.d.ts.map +1 -0
  24. package/dist/corrective-rag.test.js +140 -0
  25. package/dist/corrective-rag.test.js.map +1 -0
  26. package/dist/feedback.d.ts +77 -0
  27. package/dist/feedback.d.ts.map +1 -0
  28. package/dist/feedback.js +44 -0
  29. package/dist/feedback.js.map +1 -0
  30. package/dist/feedback.test.d.ts +2 -0
  31. package/dist/feedback.test.d.ts.map +1 -0
  32. package/dist/feedback.test.js +202 -0
  33. package/dist/feedback.test.js.map +1 -0
  34. package/dist/hybrid-search.d.ts +14 -0
  35. package/dist/hybrid-search.d.ts.map +1 -0
  36. package/dist/hybrid-search.js +70 -0
  37. package/dist/hybrid-search.js.map +1 -0
  38. package/dist/hybrid-search.test.d.ts +2 -0
  39. package/dist/hybrid-search.test.d.ts.map +1 -0
  40. package/dist/hybrid-search.test.js +93 -0
  41. package/dist/hybrid-search.test.js.map +1 -0
  42. package/dist/index.d.ts +17 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +12 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/knowledge-graph.d.ts +24 -0
  47. package/dist/knowledge-graph.d.ts.map +1 -0
  48. package/dist/knowledge-graph.js +131 -0
  49. package/dist/knowledge-graph.js.map +1 -0
  50. package/dist/knowledge-graph.test.d.ts +2 -0
  51. package/dist/knowledge-graph.test.d.ts.map +1 -0
  52. package/dist/knowledge-graph.test.js +140 -0
  53. package/dist/knowledge-graph.test.js.map +1 -0
  54. package/dist/llm-grader.d.ts +19 -0
  55. package/dist/llm-grader.d.ts.map +1 -0
  56. package/dist/llm-grader.js +63 -0
  57. package/dist/llm-grader.js.map +1 -0
  58. package/dist/metrics.d.ts +26 -0
  59. package/dist/metrics.d.ts.map +1 -0
  60. package/dist/metrics.js +100 -0
  61. package/dist/metrics.js.map +1 -0
  62. package/dist/optimizer.d.ts +52 -0
  63. package/dist/optimizer.d.ts.map +1 -0
  64. package/dist/optimizer.js +228 -0
  65. package/dist/optimizer.js.map +1 -0
  66. package/dist/optimizer.test.d.ts +2 -0
  67. package/dist/optimizer.test.d.ts.map +1 -0
  68. package/dist/optimizer.test.js +201 -0
  69. package/dist/optimizer.test.js.map +1 -0
  70. package/dist/self-improving.d.ts +85 -0
  71. package/dist/self-improving.d.ts.map +1 -0
  72. package/dist/self-improving.js +163 -0
  73. package/dist/self-improving.js.map +1 -0
  74. package/dist/self-improving.test.d.ts +2 -0
  75. package/dist/self-improving.test.d.ts.map +1 -0
  76. package/dist/self-improving.test.js +234 -0
  77. package/dist/self-improving.test.js.map +1 -0
  78. package/dist/types.d.ts +117 -0
  79. package/dist/types.d.ts.map +1 -0
  80. package/dist/types.js +2 -0
  81. package/dist/types.js.map +1 -0
  82. package/package.json +42 -0
  83. package/src/ab-testing.test.ts +239 -0
  84. package/src/ab-testing.ts +214 -0
  85. package/src/agentic-rag.test.ts +201 -0
  86. package/src/agentic-rag.ts +220 -0
  87. package/src/corrective-rag.test.ts +166 -0
  88. package/src/corrective-rag.ts +115 -0
  89. package/src/feedback.test.ts +227 -0
  90. package/src/feedback.ts +118 -0
  91. package/src/hybrid-search.test.ts +107 -0
  92. package/src/hybrid-search.ts +86 -0
  93. package/src/index.ts +57 -0
  94. package/src/knowledge-graph.test.ts +170 -0
  95. package/src/knowledge-graph.ts +182 -0
  96. package/src/llm-grader.ts +69 -0
  97. package/src/metrics.ts +121 -0
  98. package/src/optimizer.test.ts +232 -0
  99. package/src/optimizer.ts +307 -0
  100. package/src/self-improving.test.ts +341 -0
  101. package/src/self-improving.ts +239 -0
  102. package/src/types.ts +139 -0
  103. package/tsconfig.json +9 -0
@@ -0,0 +1,341 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import { SelfImprovingRag } from "./self-improving.js";
3
+ import { InMemoryFeedbackStorage } from "./feedback.js";
4
+ import type { RagStrategyConfig } from "./ab-testing.js";
5
+
6
+ describe("SelfImprovingRag", () => {
7
+ let selfImproving: SelfImprovingRag;
8
+ let storage: InMemoryFeedbackStorage;
9
+
10
+ beforeEach(() => {
11
+ storage = new InMemoryFeedbackStorage();
12
+ selfImproving = new SelfImprovingRag(
13
+ {
14
+ minFeedbackForOptimization: 10,
15
+ minConfidenceForSuggestion: 0.7,
16
+ minSamplesForABTest: 15,
17
+ autoApplySuggestions: false,
18
+ },
19
+ storage
20
+ );
21
+ });
22
+
23
+ it("should register strategies with parameters", () => {
24
+ const config: RagStrategyConfig = {
25
+ name: "strategy-a",
26
+ type: "corrective",
27
+ params: {},
28
+ };
29
+
30
+ const params = {
31
+ minScore: 0.5,
32
+ topK: 10,
33
+ };
34
+
35
+ selfImproving.registerStrategy(config, params);
36
+
37
+ const retrievedParams = selfImproving.getParams("strategy-a");
38
+ expect(retrievedParams).toEqual(params);
39
+ });
40
+
41
+ it("should select best strategy based on metrics", async () => {
42
+ const configA: RagStrategyConfig = {
43
+ name: "strategy-a",
44
+ type: "corrective",
45
+ params: {},
46
+ };
47
+
48
+ const configB: RagStrategyConfig = {
49
+ name: "strategy-b",
50
+ type: "hybrid",
51
+ params: {},
52
+ };
53
+
54
+ selfImproving.registerStrategy(configA, { minScore: 0.5 });
55
+ selfImproving.registerStrategy(configB, { semanticWeight: 0.6 });
56
+
57
+ // Add feedback for strategy A (lower quality)
58
+ for (let i = 0; i < 20; i++) {
59
+ await selfImproving.recordFeedback(
60
+ `query ${i}`,
61
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
62
+ {
63
+ rating: 3,
64
+ relevance: 0.6,
65
+ completeness: 0.5,
66
+ citationsQuality: 0.7,
67
+ },
68
+ "strategy-a"
69
+ );
70
+ }
71
+
72
+ // Add feedback for strategy B (higher quality)
73
+ for (let i = 0; i < 20; i++) {
74
+ await selfImproving.recordFeedback(
75
+ `query ${i}`,
76
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
77
+ {
78
+ rating: 5,
79
+ relevance: 0.9,
80
+ completeness: 0.85,
81
+ citationsQuality: 0.95,
82
+ },
83
+ "strategy-b"
84
+ );
85
+ }
86
+
87
+ const best = await selfImproving.selectBestStrategy();
88
+ expect(best).not.toBeNull();
89
+ expect(best?.strategy).toBe("strategy-b");
90
+ });
91
+
92
+ it("should record feedback and trigger optimization check", async () => {
93
+ const config: RagStrategyConfig = {
94
+ name: "strategy-a",
95
+ type: "corrective",
96
+ params: {},
97
+ };
98
+
99
+ selfImproving.registerStrategy(config, { minScore: 0.3 });
100
+
101
+ let optimizationTriggered = false;
102
+ selfImproving = new SelfImprovingRag(
103
+ {
104
+ minFeedbackForOptimization: 10,
105
+ onOptimization: () => {
106
+ optimizationTriggered = true;
107
+ },
108
+ },
109
+ storage
110
+ );
111
+ selfImproving.registerStrategy(config, { minScore: 0.3 });
112
+
113
+ // Add 15 feedback with low relevance to trigger optimization
114
+ for (let i = 0; i < 15; i++) {
115
+ await selfImproving.recordFeedback(
116
+ `query ${i}`,
117
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
118
+ {
119
+ rating: 3,
120
+ relevance: 0.5,
121
+ completeness: 0.6,
122
+ citationsQuality: 0.7,
123
+ },
124
+ "strategy-a"
125
+ );
126
+ }
127
+
128
+ expect(optimizationTriggered).toBe(true);
129
+ });
130
+
131
+ it("should auto-apply suggestions when configured", async () => {
132
+ const config: RagStrategyConfig = {
133
+ name: "strategy-a",
134
+ type: "corrective",
135
+ params: {},
136
+ };
137
+
138
+ selfImproving = new SelfImprovingRag(
139
+ {
140
+ minFeedbackForOptimization: 10,
141
+ autoApplySuggestions: true,
142
+ minConfidenceForSuggestion: 0.7,
143
+ },
144
+ storage
145
+ );
146
+ selfImproving.registerStrategy(config, { minScore: 0.3 });
147
+
148
+ // Add 15 feedback with low relevance
149
+ for (let i = 0; i < 15; i++) {
150
+ await selfImproving.recordFeedback(
151
+ `query ${i}`,
152
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
153
+ {
154
+ rating: 3,
155
+ relevance: 0.5,
156
+ completeness: 0.6,
157
+ citationsQuality: 0.7,
158
+ },
159
+ "strategy-a"
160
+ );
161
+ }
162
+
163
+ const params = selfImproving.getParams("strategy-a");
164
+ // Parameters should be updated if suggestions were applied
165
+ expect(params).toBeDefined();
166
+ });
167
+
168
+ it("should run A/B test", async () => {
169
+ const configA: RagStrategyConfig = {
170
+ name: "strategy-a",
171
+ type: "corrective",
172
+ params: {},
173
+ };
174
+
175
+ const configB: RagStrategyConfig = {
176
+ name: "strategy-b",
177
+ type: "hybrid",
178
+ params: {},
179
+ };
180
+
181
+ selfImproving.registerStrategy(configA, {});
182
+ selfImproving.registerStrategy(configB, {});
183
+
184
+ // Add sufficient samples
185
+ for (let i = 0; i < 20; i++) {
186
+ await selfImproving.recordFeedback(
187
+ `query ${i}`,
188
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
189
+ {
190
+ rating: 3,
191
+ relevance: 0.6,
192
+ completeness: 0.5,
193
+ citationsQuality: 0.7,
194
+ },
195
+ "strategy-a"
196
+ );
197
+
198
+ await selfImproving.recordFeedback(
199
+ `query ${i}`,
200
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
201
+ {
202
+ rating: 5,
203
+ relevance: 0.9,
204
+ completeness: 0.85,
205
+ citationsQuality: 0.95,
206
+ },
207
+ "strategy-b"
208
+ );
209
+ }
210
+
211
+ const result = await selfImproving.runABTest("strategy-a", "strategy-b");
212
+ expect(result).not.toBeNull();
213
+ expect(result.winner).toBe("B");
214
+ });
215
+
216
+ it("should update parameters manually", () => {
217
+ const config: RagStrategyConfig = {
218
+ name: "strategy-a",
219
+ type: "corrective",
220
+ params: {},
221
+ };
222
+
223
+ selfImproving.registerStrategy(config, { minScore: 0.5 });
224
+
225
+ selfImproving.updateParams("strategy-a", { minScore: 0.7, topK: 15 });
226
+
227
+ const params = selfImproving.getParams("strategy-a");
228
+ expect(params?.minScore).toBe(0.7);
229
+ expect(params?.topK).toBe(15);
230
+ });
231
+
232
+ it("should get metrics for strategy", async () => {
233
+ const config: RagStrategyConfig = {
234
+ name: "strategy-a",
235
+ type: "corrective",
236
+ params: {},
237
+ };
238
+
239
+ selfImproving.registerStrategy(config, {});
240
+
241
+ for (let i = 0; i < 5; i++) {
242
+ await selfImproving.recordFeedback(
243
+ `query ${i}`,
244
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
245
+ {
246
+ rating: 4,
247
+ relevance: 0.8,
248
+ completeness: 0.7,
249
+ citationsQuality: 0.9,
250
+ },
251
+ "strategy-a"
252
+ );
253
+ }
254
+
255
+ const metrics = await selfImproving.getMetrics("strategy-a");
256
+ expect(metrics).not.toBeNull();
257
+ expect(metrics?.totalQueries).toBe(5);
258
+ });
259
+
260
+ it("should generate report", async () => {
261
+ const config: RagStrategyConfig = {
262
+ name: "strategy-a",
263
+ type: "corrective",
264
+ params: {},
265
+ };
266
+
267
+ selfImproving.registerStrategy(config, { minScore: 0.5 });
268
+
269
+ for (let i = 0; i < 10; i++) {
270
+ await selfImproving.recordFeedback(
271
+ `query ${i}`,
272
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
273
+ {
274
+ rating: 4,
275
+ relevance: 0.7,
276
+ completeness: 0.6,
277
+ citationsQuality: 0.8,
278
+ },
279
+ "strategy-a"
280
+ );
281
+ }
282
+
283
+ const report = await selfImproving.generateReport("strategy-a");
284
+ expect(report).toContain("Report Ottimizzazione: strategy-a");
285
+ expect(report).toContain("Metriche Attuali");
286
+ });
287
+
288
+ it("should get suggestions", async () => {
289
+ const config: RagStrategyConfig = {
290
+ name: "strategy-a",
291
+ type: "corrective",
292
+ params: {},
293
+ };
294
+
295
+ selfImproving.registerStrategy(config, { minScore: 0.3 });
296
+
297
+ for (let i = 0; i < 15; i++) {
298
+ await selfImproving.recordFeedback(
299
+ `query ${i}`,
300
+ { text: `answer ${i}`, citations: [], steps: [], rewrites: 0 },
301
+ {
302
+ rating: 3,
303
+ relevance: 0.5,
304
+ completeness: 0.6,
305
+ citationsQuality: 0.7,
306
+ },
307
+ "strategy-a"
308
+ );
309
+ }
310
+
311
+ const suggestions = await selfImproving.getSuggestions("strategy-a");
312
+ expect(suggestions.length).toBeGreaterThan(0);
313
+ });
314
+
315
+ it("should reset feedback", async () => {
316
+ const config: RagStrategyConfig = {
317
+ name: "strategy-a",
318
+ type: "corrective",
319
+ params: {},
320
+ };
321
+
322
+ selfImproving.registerStrategy(config, {});
323
+
324
+ await selfImproving.recordFeedback(
325
+ "query",
326
+ { text: "answer", citations: [], steps: [], rewrites: 0 },
327
+ {
328
+ rating: 4,
329
+ relevance: 0.8,
330
+ completeness: 0.7,
331
+ citationsQuality: 0.9,
332
+ },
333
+ "strategy-a"
334
+ );
335
+
336
+ await selfImproving.reset("strategy-a");
337
+
338
+ const metrics = await selfImproving.getMetrics("strategy-a");
339
+ expect(metrics).toBeNull();
340
+ });
341
+ });
@@ -0,0 +1,239 @@
1
+ import type { RagAnswer } from "./types.js";
2
+ import type { FeedbackStorage, OptimizationSuggestion } from "./feedback.js";
3
+ import { InMemoryFeedbackStorage } from "./feedback.js";
4
+ import { ABTestFramework, type RagStrategyConfig } from "./ab-testing.js";
5
+ import { ParameterOptimizer, type OptimizableParams } from "./optimizer.js";
6
+
7
+ /**
8
+ * Configurazione per il sistema self-improving
9
+ */
10
+ export interface SelfImprovingConfig {
11
+ // Soglie per attivazione ottimizzazione
12
+ minFeedbackForOptimization: number;
13
+ minConfidenceForSuggestion: number;
14
+
15
+ // Soglie per A/B testing
16
+ minSamplesForABTest: number;
17
+
18
+ // Auto-apply suggestions
19
+ autoApplySuggestions: boolean;
20
+
21
+ // Callback per notifiche
22
+ onOptimization?: (suggestions: OptimizationSuggestion[]) => void;
23
+ onABTestComplete?: (result: any) => void;
24
+ }
25
+
26
+ /**
27
+ * Sistema self-improving per RAG
28
+ * Integra feedback collection, A/B testing e ottimizzazione automatica
29
+ */
30
+ export class SelfImprovingRag {
31
+ private storage: FeedbackStorage;
32
+ private abFramework: ABTestFramework;
33
+ private optimizer: ParameterOptimizer;
34
+ private config: Required<SelfImprovingConfig>;
35
+ private currentParams: Map<string, OptimizableParams> = new Map();
36
+
37
+ constructor(config?: Partial<SelfImprovingConfig>, storage?: FeedbackStorage) {
38
+ this.storage = storage || new InMemoryFeedbackStorage();
39
+ this.abFramework = new ABTestFramework(this.storage);
40
+ this.optimizer = new ParameterOptimizer(this.storage);
41
+
42
+ this.config = {
43
+ minFeedbackForOptimization: config?.minFeedbackForOptimization ?? 20,
44
+ minConfidenceForSuggestion: config?.minConfidenceForSuggestion ?? 0.7,
45
+ minSamplesForABTest: config?.minSamplesForABTest ?? 30,
46
+ autoApplySuggestions: config?.autoApplySuggestions ?? false,
47
+ onOptimization: config?.onOptimization ?? (() => {}),
48
+ onABTestComplete: config?.onABTestComplete ?? (() => {}),
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Registra una strategia RAG
54
+ */
55
+ registerStrategy(config: RagStrategyConfig, params: OptimizableParams): void {
56
+ this.abFramework.registerStrategy(config);
57
+ this.currentParams.set(config.name, params);
58
+ }
59
+
60
+ /**
61
+ * Seleziona la migliore strategia basata su metriche storiche
62
+ */
63
+ async selectBestStrategy(): Promise<{ strategy: string; params: OptimizableParams } | null> {
64
+ const allMetrics = await this.abFramework.getAllMetrics();
65
+
66
+ if (allMetrics.length === 0) {
67
+ // Nessuna metrica disponibile, usa prima strategia registrata
68
+ const strategies = Array.from(this.currentParams.keys());
69
+ if (strategies.length === 0) return null;
70
+
71
+ const strategy = strategies[0]!;
72
+ return {
73
+ strategy,
74
+ params: this.currentParams.get(strategy)!,
75
+ };
76
+ }
77
+
78
+ // Seleziona strategia con score più alto e confidence sufficiente
79
+ const validMetrics = allMetrics.filter(m => m.confidence >= 0.5);
80
+ if (validMetrics.length === 0) {
81
+ // Usa quella con più feedback
82
+ const best = allMetrics[0]!;
83
+ return {
84
+ strategy: best.strategy,
85
+ params: this.currentParams.get(best.strategy) || {},
86
+ };
87
+ }
88
+
89
+ const best = validMetrics[0]!;
90
+ return {
91
+ strategy: best.strategy,
92
+ params: this.currentParams.get(best.strategy) || {},
93
+ };
94
+ }
95
+
96
+ /**
97
+ * Registra feedback per una risposta
98
+ */
99
+ async recordFeedback(
100
+ query: string,
101
+ answer: RagAnswer,
102
+ feedback: {
103
+ rating: number;
104
+ relevance: number;
105
+ completeness: number;
106
+ citationsQuality: number;
107
+ comments?: string;
108
+ },
109
+ strategy: string
110
+ ): Promise<void> {
111
+ await this.abFramework.recordFeedback(
112
+ query,
113
+ answer,
114
+ feedback.rating,
115
+ feedback.relevance,
116
+ feedback.completeness,
117
+ feedback.citationsQuality,
118
+ strategy,
119
+ feedback.comments
120
+ );
121
+
122
+ // Controlla se è tempo di ottimizzare
123
+ await this.checkAndOptimize(strategy);
124
+ }
125
+
126
+ /**
127
+ * Controlla se è tempo di ottimizzare e applica suggerimenti
128
+ */
129
+ private async checkAndOptimize(strategy: string): Promise<void> {
130
+ const feedbacks = await this.storage.getFeedback(strategy);
131
+
132
+ if (feedbacks.length < this.config.minFeedbackForOptimization) {
133
+ return; // Non abbastanza feedback
134
+ }
135
+
136
+ const currentParams = this.currentParams.get(strategy);
137
+ if (!currentParams) return;
138
+
139
+ const suggestions = await this.optimizer.analyzeAndSuggest(strategy, currentParams);
140
+
141
+ if (suggestions.length > 0) {
142
+ // Notifica suggerimenti
143
+ this.config.onOptimization(suggestions);
144
+
145
+ // Auto-applica se configurato
146
+ if (this.config.autoApplySuggestions) {
147
+ const optimizedParams = this.optimizer.applySuggestions(
148
+ currentParams,
149
+ suggestions,
150
+ this.config.minConfidenceForSuggestion
151
+ );
152
+ this.currentParams.set(strategy, optimizedParams);
153
+ }
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Esegue A/B test tra due strategie
159
+ */
160
+ async runABTest(strategyA: string, strategyB: string): Promise<any> {
161
+ try {
162
+ const result = await this.abFramework.runABTest(
163
+ strategyA,
164
+ strategyB,
165
+ this.config.minSamplesForABTest
166
+ );
167
+
168
+ this.config.onABTestComplete(result);
169
+
170
+ // Se c'è un vincitore chiaro, aggiorna parametri
171
+ if (result.winner !== "tie" && result.statisticalSignificance > 0.8) {
172
+ const winnerStrategy = result.winner === "A" ? strategyA : strategyB;
173
+ const winnerMetrics = result.winner === "A" ? result.metricsA : result.metricsB;
174
+
175
+ // Log vittoria
176
+ console.log(
177
+ `A/B Test: ${winnerStrategy} vince con score ${winnerMetrics.overallScore.toFixed(3)} ` +
178
+ `(miglioramento: ${(result.improvement * 100).toFixed(1)}%)`
179
+ );
180
+ }
181
+
182
+ return result;
183
+ } catch (error) {
184
+ console.warn("A/B test non può essere eseguito:", (error as Error).message);
185
+ return null;
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Ottiene parametri correnti per una strategia
191
+ */
192
+ getParams(strategy: string): OptimizableParams | undefined {
193
+ return this.currentParams.get(strategy);
194
+ }
195
+
196
+ /**
197
+ * Aggiorna parametri per una strategia
198
+ */
199
+ updateParams(strategy: string, params: OptimizableParams): void {
200
+ this.currentParams.set(strategy, params);
201
+ }
202
+
203
+ /**
204
+ * Ottiene metriche per una strategia
205
+ */
206
+ async getMetrics(strategy: string) {
207
+ return this.abFramework.getStrategyMetrics(strategy);
208
+ }
209
+
210
+ /**
211
+ * Ottiene tutte le metriche
212
+ */
213
+ async getAllMetrics() {
214
+ return this.abFramework.getAllMetrics();
215
+ }
216
+
217
+ /**
218
+ * Genera report completo
219
+ */
220
+ async generateReport(strategy: string): Promise<string> {
221
+ const currentParams = this.currentParams.get(strategy) || {};
222
+ return this.optimizer.generateReport(strategy, currentParams);
223
+ }
224
+
225
+ /**
226
+ * Ottiene suggerimenti di ottimizzazione
227
+ */
228
+ async getSuggestions(strategy: string): Promise<OptimizationSuggestion[]> {
229
+ const currentParams = this.currentParams.get(strategy) || {};
230
+ return this.optimizer.analyzeAndSuggest(strategy, currentParams);
231
+ }
232
+
233
+ /**
234
+ * Resetta tutti i feedback (per testing)
235
+ */
236
+ async reset(strategy?: string): Promise<void> {
237
+ await this.storage.clearFeedback(strategy);
238
+ }
239
+ }
package/src/types.ts ADDED
@@ -0,0 +1,139 @@
1
+ import type { SearchHit } from "@eucode/indexer";
2
+
3
+ export interface Retriever {
4
+ search(query: string, topK: number): Promise<SearchHit[]>;
5
+ }
6
+
7
+ export interface KeywordRetriever {
8
+ search(query: string, topK: number): Promise<SearchHit[]>;
9
+ }
10
+
11
+ export interface GraderResult {
12
+ relevant: boolean;
13
+ score: number;
14
+ }
15
+
16
+ export interface Grader {
17
+ grade(query: string, hit: SearchHit): Promise<GraderResult>;
18
+ }
19
+
20
+ export interface QueryRewriter {
21
+ rewrite(query: string, context: string): Promise<string>;
22
+ }
23
+
24
+ export interface CorrectiveRagOptions {
25
+ retriever: Retriever;
26
+ grader: Grader;
27
+ rewriter: QueryRewriter;
28
+ maxRewrites?: number;
29
+ minGoodHits?: number;
30
+ minScore?: number;
31
+ webFallback?: (query: string) => Promise<SearchHit[]>;
32
+ }
33
+
34
+ export interface RagCitation {
35
+ path: string;
36
+ startLine: number;
37
+ endLine: number;
38
+ text: string;
39
+ }
40
+
41
+ export interface RagAnswer {
42
+ text: string;
43
+ citations: RagCitation[];
44
+ steps: string[];
45
+ rewrites: number;
46
+ }
47
+
48
+ // Hybrid Search Types
49
+ export interface HybridSearchOptions {
50
+ semanticRetriever: Retriever;
51
+ keywordRetriever: KeywordRetriever;
52
+ semanticWeight?: number;
53
+ keywordWeight?: number;
54
+ rrfK?: number;
55
+ topK?: number;
56
+ }
57
+
58
+ export interface HybridSearchResult {
59
+ hits: SearchHit[];
60
+ fusionMethod: "rrf" | "weighted";
61
+ semanticCount: number;
62
+ keywordCount: number;
63
+ }
64
+
65
+ // Knowledge Graph Types
66
+ export interface Entity {
67
+ id: string;
68
+ name: string;
69
+ type: string;
70
+ properties: Record<string, unknown>;
71
+ }
72
+
73
+ export interface Relation {
74
+ id: string;
75
+ source: string;
76
+ target: string;
77
+ type: string;
78
+ properties: Record<string, unknown>;
79
+ }
80
+
81
+ export interface KnowledgeGraph {
82
+ entities: Map<string, Entity>;
83
+ relations: Relation[];
84
+ addEntity(entity: Entity): void;
85
+ addRelation(relation: Relation): void;
86
+ getEntity(id: string): Entity | undefined;
87
+ getRelations(entityId: string): Relation[];
88
+ getConnectedEntities(entityId: string, depth?: number): Entity[];
89
+ }
90
+
91
+ export interface EntityExtractor {
92
+ extract(text: string): Promise<Entity[]>;
93
+ }
94
+
95
+ export interface RelationExtractor {
96
+ extract(text: string, entities: Entity[]): Promise<Relation[]>;
97
+ }
98
+
99
+ export interface KnowledgeGraphRagOptions {
100
+ retriever: Retriever;
101
+ entityExtractor: EntityExtractor;
102
+ relationExtractor: RelationExtractor;
103
+ graph: KnowledgeGraph;
104
+ topK?: number;
105
+ maxDepth?: number;
106
+ }
107
+
108
+ export interface KnowledgeGraphRagResult {
109
+ answer: string;
110
+ citations: RagCitation[];
111
+ entities: Entity[];
112
+ relations: Relation[];
113
+ graphContext: string;
114
+ }
115
+
116
+ // Agentic RAG Types
117
+ export interface ReasoningStep {
118
+ thought: string;
119
+ action: string;
120
+ observation: string;
121
+ }
122
+
123
+ export interface AgenticRagOptions {
124
+ retriever: Retriever;
125
+ grader: Grader;
126
+ rewriter: QueryRewriter;
127
+ maxIterations?: number;
128
+ enableSelfReflection?: boolean;
129
+ enableChainOfThought?: boolean;
130
+ }
131
+
132
+ export interface AgenticRagResult {
133
+ answer: string;
134
+ citations: RagCitation[];
135
+ reasoningSteps: ReasoningStep[];
136
+ selfReflection?: string;
137
+ iterations: number;
138
+ confidence: number;
139
+ }