@devilsdev/rag-pipeline-utils 2.6.1 → 2.7.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 (90) hide show
  1. package/BENCHMARKS.md +7 -1
  2. package/CHANGELOG.md +135 -0
  3. package/README.md +37 -24
  4. package/dist/index.cjs +4164 -1825
  5. package/dist/index.d.ts +265 -256
  6. package/dist/index.mjs +1 -1
  7. package/dist/types/cache/memory-cache.d.ts +4 -1
  8. package/dist/types/cache/redis-cache.d.ts +4 -1
  9. package/dist/types/cli/services/instrument.d.ts +14 -0
  10. package/dist/types/cli/services/rag-service.d.ts +140 -0
  11. package/dist/types/cli/shared/config-context.d.ts +9 -0
  12. package/dist/types/config/component-factory.d.ts +57 -0
  13. package/dist/types/config/enhanced-ragrc-schema.d.ts +648 -0
  14. package/dist/types/config/load-config.d.ts +18 -0
  15. package/dist/types/config/normalize-config.d.ts +9 -0
  16. package/dist/types/core/observability/event-logger.d.ts +211 -0
  17. package/dist/types/core/observability/metrics.d.ts +585 -0
  18. package/dist/types/core/performance/parallel-processor.d.ts +92 -0
  19. package/dist/types/core/plugin-registry.d.ts +5 -0
  20. package/dist/types/dag/core/execution-scheduler.d.ts +3 -1
  21. package/dist/types/dag/dag-engine.d.ts +15 -2
  22. package/dist/types/dev/dev-server.d.ts +136 -0
  23. package/dist/types/dev/hot-reload.d.ts +226 -0
  24. package/dist/types/ecosystem/plugin-analytics-dashboard.d.ts +141 -0
  25. package/dist/types/ecosystem/plugin-hub.d.ts +161 -0
  26. package/dist/types/ecosystem/plugin-installer.d.ts +40 -0
  27. package/dist/types/ecosystem/plugin-probe.d.ts +21 -0
  28. package/dist/types/ecosystem/plugin-scanner.d.ts +30 -0
  29. package/dist/types/ecosystem/tar-extract.d.ts +24 -0
  30. package/dist/types/enterprise/audit-logging.d.ts +217 -0
  31. package/dist/types/evaluate/compare.d.ts +140 -0
  32. package/dist/types/evaluate/dataset.d.ts +43 -0
  33. package/dist/types/evaluate/evaluator.d.ts +14 -0
  34. package/dist/types/evaluate/report.d.ts +56 -0
  35. package/dist/types/evaluate/synthetic.d.ts +64 -0
  36. package/dist/types/loader/csv-loader.d.ts +10 -0
  37. package/dist/types/loader/document-reader.d.ts +18 -0
  38. package/dist/types/loader/html-loader.d.ts +21 -0
  39. package/dist/types/loader/markdown-loader.d.ts +21 -0
  40. package/dist/types/retrieval/bm25-search.d.ts +4 -0
  41. package/dist/types/retrieval/file-vector-store.d.ts +4 -1
  42. package/dist/types/retrieval/hybrid-retriever.d.ts +4 -0
  43. package/dist/types/retrieval/pgvector-retriever.d.ts +123 -0
  44. package/dist/types/retrieval/qdrant-retriever.d.ts +106 -0
  45. package/dist/types/security/validator.d.ts +11 -1
  46. package/dist/types/testing.d.ts +2 -0
  47. package/dist/types/utils/batch-processor.d.ts +205 -0
  48. package/dist/types/utils/connection-pool.d.ts +158 -0
  49. package/dist/types/utils/error-formatter.d.ts +312 -0
  50. package/dist/types/utils/logger.d.ts +29 -4
  51. package/dist/types/utils/rate-limiter.d.ts +13 -8
  52. package/dist/types/utils/retry.d.ts +10 -0
  53. package/package.json +13 -3
  54. package/src/cache/memory-cache.js +4 -1
  55. package/src/cache/redis-cache.js +4 -1
  56. package/src/cli/enhanced-cli-commands.js +79 -0
  57. package/src/cli/handlers/ai-handler.js +2 -2
  58. package/src/cli/handlers/eval-handler.js +201 -0
  59. package/src/cli/handlers/generate-handler.js +103 -0
  60. package/src/cli/services/benchmark.js +2 -2
  61. package/src/cli/services/rag-service.js +59 -10
  62. package/src/cli/shared/cli-utils.js +40 -1
  63. package/src/config/component-factory.js +32 -0
  64. package/src/connectors/local-embedder.js +20 -13
  65. package/src/core/observability/event-logger.js +135 -1
  66. package/src/core/observability/metrics.js +223 -5
  67. package/src/core/performance/parallel-processor.js +2 -0
  68. package/src/core/plugin-registry.js +5 -1
  69. package/src/dag/core/execution-scheduler.js +2 -0
  70. package/src/dag/dag-engine.js +13 -0
  71. package/src/dev/dev-server.js +6 -0
  72. package/src/ecosystem/plugin-hub.js +4 -0
  73. package/src/enterprise/audit-logging.js +5 -0
  74. package/src/evaluate/compare.js +395 -0
  75. package/src/evaluate/dataset.js +207 -0
  76. package/src/evaluate/report.js +350 -0
  77. package/src/evaluate/synthetic.js +246 -0
  78. package/src/index.js +17 -0
  79. package/src/retrieval/bm25-search.js +4 -0
  80. package/src/retrieval/file-vector-store.js +4 -1
  81. package/src/retrieval/hybrid-retriever.js +4 -0
  82. package/src/retrieval/pgvector-retriever.js +420 -0
  83. package/src/retrieval/qdrant-retriever.js +361 -0
  84. package/src/security/validator.js +8 -0
  85. package/src/testing.js +2 -0
  86. package/src/utils/batch-processor.js +7 -3
  87. package/src/utils/error-formatter.js +48 -20
  88. package/src/utils/logger.js +31 -1
  89. package/src/utils/rate-limiter.js +9 -4
  90. package/src/utils/retry.js +10 -1
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @param {object} params
3
+ * @param {string} params.source - Registry id, path, .tgz, .js or "npm:<spec>"
4
+ * @param {string} params.configPath - .ragrc.json to register the plugin in
5
+ * @param {string} [params.stage] - Overrides package.json "ragPipeline.stage"
6
+ * @param {string} [params.name] - Overrides package.json "ragPipeline.name"
7
+ * @param {boolean} [params.force] - Replace an installed plugin with the same stage/name
8
+ * @param {boolean} [params.allowRisky] - Install despite high-risk scan findings
9
+ * @param {object} [params.hub] - PluginHub, required for registry ids
10
+ * @param {string} [params.version] - Registry version (default "latest")
11
+ * @param {function} [params.onProgress] - Called with a stage label
12
+ * @returns {Promise<object>} Installation summary
13
+ */
14
+ export function installPlugin(params: {
15
+ source: string;
16
+ configPath: string;
17
+ stage?: string;
18
+ name?: string;
19
+ force?: boolean;
20
+ allowRisky?: boolean;
21
+ hub?: object;
22
+ version?: string;
23
+ onProgress?: Function;
24
+ }): Promise<object>;
25
+ /**
26
+ * Plugins registered under `plugins` in a config, with the installed
27
+ * package's version when it lives in .rag/plugins.
28
+ *
29
+ * @param {string} configPath
30
+ * @returns {Array<{stage: string, name: string, entry: string, version: string|null, installed: boolean, inPipeline: boolean, exists: boolean}>}
31
+ */
32
+ export function listInstalledPlugins(configPath: string): Array<{
33
+ stage: string;
34
+ name: string;
35
+ entry: string;
36
+ version: string | null;
37
+ installed: boolean;
38
+ inPipeline: boolean;
39
+ exists: boolean;
40
+ }>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @param {string} modulePath - Plugin entry file
3
+ * @param {string} stage - loader | embedder | retriever | llm | reranker
4
+ * @param {{timeoutMs?: number}} [options]
5
+ * @returns {Promise<{ok: boolean, missing: string[], methods: string[], error?: string}>}
6
+ */
7
+ export function probeContract(modulePath: string, stage: string, options?: {
8
+ timeoutMs?: number;
9
+ }): Promise<{
10
+ ok: boolean;
11
+ missing: string[];
12
+ methods: string[];
13
+ error?: string;
14
+ }>;
15
+ export namespace STAGE_METHODS {
16
+ let loader: string[];
17
+ let embedder: string[];
18
+ let retriever: string[];
19
+ let llm: string[];
20
+ let reranker: string[];
21
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @param {string} pluginPath - Plugin directory or single .js file
3
+ * @returns {{
4
+ * findings: Array<{severity: string, rule: string, message: string, file: string, line?: number}>,
5
+ * counts: {high: number, medium: number, low: number},
6
+ * filesScanned: number
7
+ * }}
8
+ */
9
+ export function scanPlugin(pluginPath: string): {
10
+ findings: Array<{
11
+ severity: string;
12
+ rule: string;
13
+ message: string;
14
+ file: string;
15
+ line?: number;
16
+ }>;
17
+ counts: {
18
+ high: number;
19
+ medium: number;
20
+ low: number;
21
+ };
22
+ filesScanned: number;
23
+ };
24
+ /** severity: high blocks installation unless explicitly allowed */
25
+ export const RULES: {
26
+ id: string;
27
+ severity: string;
28
+ pattern: RegExp;
29
+ message: string;
30
+ }[];
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Extract a gzipped tarball into destDir.
3
+ *
4
+ * @param {Buffer} archive - .tgz contents
5
+ * @param {string} destDir - Target directory (created if missing)
6
+ * @param {object} [options]
7
+ * @param {number} [options.strip=0] - Leading path components to drop (npm packs use "package/")
8
+ * @param {number} [options.maxBytes=50MB] - Refuse archives that expand beyond this
9
+ * @returns {{files: string[], skipped: string[]}}
10
+ */
11
+ export function extractTarGz(archive: Buffer, destDir: string, options?: {
12
+ strip?: number;
13
+ maxBytes?: number;
14
+ }): {
15
+ files: string[];
16
+ skipped: string[];
17
+ };
18
+ /** Separator-agnostic "child is root or inside it" (paths already resolved). */
19
+ export function isWithin(root: any, child: any): any;
20
+ /**
21
+ * Path of `child` relative to `root` with "/" separators, or null when it is
22
+ * not inside root. Separator-agnostic like isWithin.
23
+ */
24
+ export function relativeWithin(root: any, child: any): any;
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Records authentication, data access, data change and other audit events
3
+ * in hash-chained logs, with querying, compliance reports and an integrity
4
+ * check.
5
+ */
6
+ export class AuditLogger extends EventEmitter<[never]> {
7
+ constructor(_options?: {});
8
+ _config: {
9
+ logDir: any;
10
+ retention: {
11
+ days: any;
12
+ maxSizeMB: any;
13
+ compressionEnabled: boolean;
14
+ };
15
+ compliance: {
16
+ standards: any;
17
+ immutable: boolean;
18
+ encryption: boolean;
19
+ digitalSigning: boolean;
20
+ };
21
+ realtime: {
22
+ enabled: boolean;
23
+ batchSize: any;
24
+ flushInterval: any;
25
+ webhookUrl: any;
26
+ };
27
+ categories: {
28
+ authentication: {
29
+ level: string;
30
+ retention: number;
31
+ };
32
+ authorization: {
33
+ level: string;
34
+ retention: number;
35
+ };
36
+ dataAccess: {
37
+ level: string;
38
+ retention: number;
39
+ };
40
+ dataModification: {
41
+ level: string;
42
+ retention: number;
43
+ };
44
+ systemChanges: {
45
+ level: string;
46
+ retention: number;
47
+ };
48
+ userActivity: {
49
+ level: string;
50
+ retention: number;
51
+ };
52
+ apiAccess: {
53
+ level: string;
54
+ retention: number;
55
+ };
56
+ pluginActivity: {
57
+ level: string;
58
+ retention: number;
59
+ };
60
+ complianceEvents: {
61
+ level: string;
62
+ retention: number;
63
+ };
64
+ };
65
+ };
66
+ logBuffer: any[];
67
+ encryptionKey: string | Buffer<ArrayBufferLike>;
68
+ signingKey: any;
69
+ sequenceNumber: number;
70
+ /**
71
+ * Initialize audit logging system
72
+ */
73
+ _initializeAuditSystem(): Promise<void>;
74
+ flushTimer: NodeJS.Timeout;
75
+ /**
76
+ * Log authentication events
77
+ */
78
+ logAuthentication(event: any): Promise<any>;
79
+ /**
80
+ * Log authorization events
81
+ */
82
+ logAuthorization(event: any): Promise<any>;
83
+ /**
84
+ * Log data access events
85
+ */
86
+ logDataAccess(event: any): Promise<any>;
87
+ /**
88
+ * Log data modification events
89
+ */
90
+ logDataModification(event: any): Promise<any>;
91
+ /**
92
+ * Log system configuration changes
93
+ */
94
+ logSystemChanges(event: any): Promise<any>;
95
+ /**
96
+ * Log API access events
97
+ */
98
+ logAPIAccess(event: any): Promise<any>;
99
+ /**
100
+ * Log compliance events
101
+ */
102
+ logComplianceEvent(event: any): Promise<any>;
103
+ /**
104
+ * Write audit log with integrity protection
105
+ */
106
+ _writeAuditLog(auditEvent: any): Promise<any>;
107
+ /**
108
+ * Flush logs to persistent storage
109
+ */
110
+ _flushLogs(): Promise<void>;
111
+ /**
112
+ * Query audit logs
113
+ */
114
+ queryLogs(query: any): Promise<{
115
+ results: any[];
116
+ total: number;
117
+ hasMore: boolean;
118
+ }>;
119
+ /**
120
+ * Generate compliance report
121
+ */
122
+ generateComplianceReport(_options: any): Promise<{
123
+ metadata: {
124
+ _tenantId: any;
125
+ standard: any;
126
+ period: {
127
+ startDate: any;
128
+ endDate: any;
129
+ };
130
+ generatedAt: string;
131
+ totalEvents: number;
132
+ };
133
+ summary: {
134
+ authenticationEvents: number;
135
+ authorizationEvents: number;
136
+ dataAccessEvents: number;
137
+ dataModificationEvents: number;
138
+ systemChangeEvents: number;
139
+ complianceEvents: number;
140
+ criticalEvents: number;
141
+ failedEvents: number;
142
+ };
143
+ compliance: {
144
+ requirements: any[];
145
+ violations: any[];
146
+ recommendations: any[];
147
+ };
148
+ evidence: any[];
149
+ }>;
150
+ /**
151
+ * Verify log integrity
152
+ */
153
+ verifyIntegrity(_options?: {}): Promise<{
154
+ verified: boolean;
155
+ totalLogs: number;
156
+ verifiedLogs: number;
157
+ tamperedLogs: any[];
158
+ missingLogs: any[];
159
+ integrityBreaks: any[];
160
+ }>;
161
+ _calculateIntegrityHash(auditEvent: any): Promise<string>;
162
+ _encryptSensitiveFields(auditEvent: any): Promise<any>;
163
+ _decryptAuditEvent(auditEvent: any): Promise<any>;
164
+ _calculateSeverity(_category: any, _action: any, result: any): any;
165
+ _sanitizeQuery(query: any): any;
166
+ _sanitizeValue(value: any): any;
167
+ _sanitizeParameters(params: any): any;
168
+ _hashApiKey(apiKey: any): string;
169
+ /**
170
+ * Resolve the field-encryption key.
171
+ *
172
+ * Order: the `encryptionKey` option, then the RAG_AUDIT_ENCRYPTION_KEY
173
+ * environment variable (used as a passphrase, like a string option). A
174
+ * random per-process key is never generated: records written with it
175
+ * could not be decrypted after a restart.
176
+ *
177
+ * If encryption is enabled but no key is configured, encryption is
178
+ * disabled for this instance with a loud warning (an `encryption_disabled`
179
+ * event is also emitted on the next tick). Pass `requireEncryption: true`
180
+ * to throw instead.
181
+ *
182
+ * @param {Object} _options - Constructor options
183
+ * @returns {Buffer|string|null} Key material, or null when unavailable
184
+ * @private
185
+ */
186
+ private _resolveEncryptionKey;
187
+ /**
188
+ * AES-256 needs exactly 32 key bytes. A 32-byte Buffer is used as-is; any
189
+ * other key (e.g. a passphrase string) is reduced with SHA-256.
190
+ */
191
+ _getCipherKey(): Buffer<ArrayBufferLike>;
192
+ _createDecipher(encryptedField: any): crypto.DecipherGCM;
193
+ _generateSigningKey(): Buffer<ArrayBufferLike>;
194
+ _initializeIntegrityChain(): Promise<void>;
195
+ _updateIntegrityChain(logs: any): Promise<void>;
196
+ _signAuditEvent(auditEvent: any): Promise<string>;
197
+ _verifySignature(auditEvent: any): Promise<boolean>;
198
+ _getLogFilesInRange(startDate: any, endDate: any): Promise<string[]>;
199
+ _readLogFile(filepath: any): Promise<any[]>;
200
+ _matchesQuery(log: any, query: any): boolean;
201
+ _checkCompliance(log: any, standard: any): {
202
+ requirement: any;
203
+ violation: boolean;
204
+ evidence: any;
205
+ };
206
+ _sendToWebhook(logs: any): Promise<void>;
207
+ /**
208
+ * Cleanup old logs based on retention policy
209
+ */
210
+ cleanupOldLogs(): Promise<{
211
+ filesRemoved: number;
212
+ bytesFreed: number;
213
+ errors: any[];
214
+ }>;
215
+ }
216
+ import { EventEmitter } from "events";
217
+ import crypto = require("crypto");
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Runs every case of a dataset through a pipeline and scores it.
3
+ *
4
+ * Each case runs with citations and evaluation on, and its expected answer
5
+ * as the reference. A case that fails is recorded with its error, not
6
+ * thrown. Throws a DatasetError (`code: 'RAG_INVALID_DATASET'`, `errors`
7
+ * from validateDataset) when the dataset is invalid.
8
+ *
9
+ * @param {Array<Object>|{cases: Array<Object>}} dataset - See validateDataset
10
+ * @param {{ run: Function }} pipeline - A createRagPipeline() pipeline
11
+ * @param {Object} [options]
12
+ * @param {number} [options.concurrency=1] - Cases run at the same time
13
+ * @param {number} [options.timeout] - Per-case timeout in milliseconds
14
+ * @param {AbortSignal} [options.signal] - Stops the run; unstarted cases are not run
15
+ * @param {Object} [options.runOptions] - Extra `run()` options for every case
16
+ * @param {(caseResult: Object, index: number) => void} [options.onCase] - Called as each case finishes
17
+ * @returns {Promise<{
18
+ * version: number,
19
+ * libraryVersion: string,
20
+ * createdAt: string,
21
+ * summary: { cases: number, succeeded: number, failed: number, metrics: Object<string, { mean: number, count: number }> },
22
+ * cases: Array<{ id: string, prompt: string, success: boolean, error?: string, answer: string|null, retrievedIds: string[], scores: Object<string, number>, durationMs: number }>
23
+ * }>} A JSON-serialisable report
24
+ */
25
+ export function runEvaluation(dataset: Array<any> | {
26
+ cases: Array<any>;
27
+ }, pipeline: {
28
+ run: Function;
29
+ }, options?: {
30
+ concurrency?: number;
31
+ timeout?: number;
32
+ signal?: AbortSignal;
33
+ runOptions?: any;
34
+ onCase?: (caseResult: any, index: number) => void;
35
+ }): Promise<{
36
+ version: number;
37
+ libraryVersion: string;
38
+ createdAt: string;
39
+ summary: {
40
+ cases: number;
41
+ succeeded: number;
42
+ failed: number;
43
+ metrics: {
44
+ [x: string]: {
45
+ mean: number;
46
+ count: number;
47
+ };
48
+ };
49
+ };
50
+ cases: Array<{
51
+ id: string;
52
+ prompt: string;
53
+ success: boolean;
54
+ error?: string;
55
+ answer: string | null;
56
+ retrievedIds: string[];
57
+ scores: {
58
+ [x: string]: number;
59
+ };
60
+ durationMs: number;
61
+ }>;
62
+ }>;
63
+ /**
64
+ * Compares two configurations on the same dataset and reports what got
65
+ * worse. Each side is a pipeline (run now) or a saved runEvaluation()
66
+ * report, so CI can compare against the base branch's saved report.
67
+ *
68
+ * A metric has regressed when its mean drops by more than `tolerance`.
69
+ * A case has regressed when it now fails, or a metric drops by more than
70
+ * `caseTolerance`; those cases are listed but don't set `regressed` on
71
+ * their own, except failures. Scores from LLM answers vary between runs,
72
+ * so keep the tolerances above the noise you see on repeated runs.
73
+ *
74
+ * @param {Array<Object>|{cases: Array<Object>}|null} dataset - Needed when either side is a pipeline
75
+ * @param {Object} options
76
+ * @param {Object} options.baseline - Pipeline or report
77
+ * @param {Object} options.candidate - Pipeline or report
78
+ * @param {number} [options.tolerance=0.02] - Allowed drop in a metric's mean
79
+ * @param {number} [options.caseTolerance=0.1] - Drop in one case's metric that lists the case
80
+ * @param {string[]} [options.metrics] - Metrics to compare (default: all both runs have)
81
+ * @param {Object} [options.runOptions] - Options for runEvaluation when a side is a pipeline
82
+ * @returns {Promise<{
83
+ * regressed: boolean,
84
+ * metrics: Object<string, { baseline: number, candidate: number, delta: number, regressed: boolean }>,
85
+ * regressions: Array<{ id: string, prompt: string, reason: string, metric?: string, baseline?: number, candidate?: number, delta?: number }>,
86
+ * improvements: Array<{ id: string, prompt: string, reason: string, metric?: string, baseline?: number, candidate?: number, delta?: number }>,
87
+ * warnings: string[],
88
+ * baseline: Object,
89
+ * candidate: Object
90
+ * }>}
91
+ */
92
+ export function compareConfigurations(dataset: Array<any> | {
93
+ cases: Array<any>;
94
+ } | null, options?: {
95
+ baseline: any;
96
+ candidate: any;
97
+ tolerance?: number;
98
+ caseTolerance?: number;
99
+ metrics?: string[];
100
+ runOptions?: any;
101
+ }): Promise<{
102
+ regressed: boolean;
103
+ metrics: {
104
+ [x: string]: {
105
+ baseline: number;
106
+ candidate: number;
107
+ delta: number;
108
+ regressed: boolean;
109
+ };
110
+ };
111
+ regressions: Array<{
112
+ id: string;
113
+ prompt: string;
114
+ reason: string;
115
+ metric?: string;
116
+ baseline?: number;
117
+ candidate?: number;
118
+ delta?: number;
119
+ }>;
120
+ improvements: Array<{
121
+ id: string;
122
+ prompt: string;
123
+ reason: string;
124
+ metric?: string;
125
+ baseline?: number;
126
+ candidate?: number;
127
+ delta?: number;
128
+ }>;
129
+ warnings: string[];
130
+ baseline: any;
131
+ candidate: any;
132
+ }>;
133
+ export class DatasetError extends Error {
134
+ constructor(errors: any);
135
+ code: string;
136
+ errors: any;
137
+ }
138
+ /** Metrics a report can hold; higher is better for all of them. */
139
+ declare const METRICS: string[];
140
+ export { METRICS as EVALUATION_METRICS };
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Checks an evaluation dataset before anything runs. It never throws: every
3
+ * problem is reported, with the case it is in.
4
+ *
5
+ * @param {Array<Object>|{cases: Array<Object>}} dataset - Cases, or an object with `cases`
6
+ * @param {Object} [options]
7
+ * @param {boolean} [options.requireExpected=false] - Every case needs `expected`
8
+ * @param {boolean} [options.requireSourceIds=false] - Every case needs `sourceIds`
9
+ * @returns {{
10
+ * valid: boolean,
11
+ * errors: Array<{ index: number|null, id: string|null, field: string|null, message: string }>,
12
+ * warnings: Array<{ index: number|null, id: string|null, field: string|null, message: string }>,
13
+ * cases: Array<{ id: string, prompt: string, expected?: string, sourceIds?: string[], tags?: string[] }>
14
+ * }} `cases` holds the normalised cases (aliases resolved, ids filled in)
15
+ * when `valid` is true, and is empty otherwise
16
+ */
17
+ export function validateDataset(dataset: Array<any> | {
18
+ cases: Array<any>;
19
+ }, options?: {
20
+ requireExpected?: boolean;
21
+ requireSourceIds?: boolean;
22
+ }): {
23
+ valid: boolean;
24
+ errors: Array<{
25
+ index: number | null;
26
+ id: string | null;
27
+ field: string | null;
28
+ message: string;
29
+ }>;
30
+ warnings: Array<{
31
+ index: number | null;
32
+ id: string | null;
33
+ field: string | null;
34
+ message: string;
35
+ }>;
36
+ cases: Array<{
37
+ id: string;
38
+ prompt: string;
39
+ expected?: string;
40
+ sourceIds?: string[];
41
+ tags?: string[];
42
+ }>;
43
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Evaluate a list of prompt/answer pairs using the RAG pipeline and compute scores
3
+ * @param {string} datasetPath - Path to JSON file with { prompt, expected }[]
4
+ * @param {object} _config - RAG plugin _config (loader optional)
5
+ * @returns {Promise<Array<{ prompt: string, expected: string, actual: string, success: boolean, scores: object }>>}
6
+ */
7
+ export function evaluateRagDataset(_datasetPath: any, _config: object): Promise<Array<{
8
+ prompt: string;
9
+ expected: string;
10
+ actual: string;
11
+ success: boolean;
12
+ scores: object;
13
+ }>>;
14
+ export function normalizeText(txt: any): any;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Decides whether a run passes: no case failed, every metric in `min` is at
3
+ * or above its minimum, and the comparison (if any) found no regression.
4
+ *
5
+ * @param {Object} input
6
+ * @param {Object} input.report - A runEvaluation() report
7
+ * @param {Object} [input.comparison] - A compareConfigurations() result
8
+ * @param {Object<string, number>} [input.min] - Minimum mean per metric, e.g. `{ faithfulness: 0.8 }`
9
+ * @returns {{
10
+ * passed: boolean,
11
+ * reasons: string[],
12
+ * thresholds: Array<{ metric: string, min: number, actual: number|null, passed: boolean }>
13
+ * }}
14
+ */
15
+ export function evaluationVerdict({ report, comparison, min }?: {
16
+ report: any;
17
+ comparison?: any;
18
+ min?: {
19
+ [x: string]: number;
20
+ };
21
+ }): {
22
+ passed: boolean;
23
+ reasons: string[];
24
+ thresholds: Array<{
25
+ metric: string;
26
+ min: number;
27
+ actual: number | null;
28
+ passed: boolean;
29
+ }>;
30
+ };
31
+ /**
32
+ * Renders an evaluation run, and its comparison with a baseline if given,
33
+ * as Markdown (for a pull request comment) or a standalone HTML page.
34
+ *
35
+ * @param {Object} input
36
+ * @param {Object} input.report - A runEvaluation() report
37
+ * @param {Object} [input.comparison] - A compareConfigurations() result
38
+ * @param {Object<string, number>} [input.min] - Minimum mean per metric
39
+ * @param {Object} [options]
40
+ * @param {'markdown'|'html'} [options.format='markdown']
41
+ * @param {string} [options.title='RAG evaluation']
42
+ * @returns {string}
43
+ */
44
+ export function renderEvaluationReport(input: {
45
+ report: any;
46
+ comparison?: any;
47
+ min?: {
48
+ [x: string]: number;
49
+ };
50
+ }, options?: {
51
+ format?: "markdown" | "html";
52
+ title?: string;
53
+ }): string;
54
+ /** Marks the comment so the Action can find and update it. */
55
+ declare const MARKER: "<!-- rag-eval-report -->";
56
+ export { MARKER as REPORT_MARKER };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Generates question and answer pairs from documents with an LLM.
3
+ *
4
+ * Each document gets its own request, with that document as the only
5
+ * context, so every case knows its source. Generated answers are checked
6
+ * against the document with computeFaithfulness, and pairs whose answer the
7
+ * document doesn't support, malformed pairs and repeated questions are
8
+ * dropped and listed in `skipped`.
9
+ *
10
+ * @param {Array<{id?: string, content: string, metadata?: Object}|string>} documents - The corpus, e.g. the chunks you index
11
+ * @param {Object} options
12
+ * @param {{ generate: Function }} options.llm - Any llm stage: `generate(query, docs, options)` returning a string
13
+ * @param {number} [options.count=20] - Cases to generate at most
14
+ * @param {number} [options.perDocument=1] - Questions to ask per document
15
+ * @param {number} [options.minFaithfulness=1] - Share of an answer's sentences the document must support
16
+ * @param {number} [options.minLength=80] - Documents shorter than this many characters are skipped
17
+ * @param {string} [options.prompt] - Replaces the instruction; `{count}` is replaced by perDocument
18
+ * @param {number} [options.concurrency=1] - Documents processed at the same time
19
+ * @param {Object} [options.generateOptions] - Extra options for every `llm.generate()` call, e.g. `{ temperature: 0.7 }`
20
+ * @param {AbortSignal} [options.signal]
21
+ * @param {(testCase: Object) => void} [options.onCase] - Called for each case kept
22
+ * @returns {Promise<{
23
+ * cases: Array<{ id: string, prompt: string, expected: string, sourceIds: string[], tags: string[], reviewed: boolean }>,
24
+ * skipped: Array<{ sourceId: string, reason: string, question?: string }>
25
+ * }>} A dataset (`{ cases }`) plus what was dropped and why
26
+ */
27
+ export function generateSyntheticDataset(documents: Array<{
28
+ id?: string;
29
+ content: string;
30
+ metadata?: any;
31
+ } | string>, options?: {
32
+ llm: {
33
+ generate: Function;
34
+ };
35
+ count?: number;
36
+ perDocument?: number;
37
+ minFaithfulness?: number;
38
+ minLength?: number;
39
+ prompt?: string;
40
+ concurrency?: number;
41
+ generateOptions?: any;
42
+ signal?: AbortSignal;
43
+ onCase?: (testCase: any) => void;
44
+ }): Promise<{
45
+ cases: Array<{
46
+ id: string;
47
+ prompt: string;
48
+ expected: string;
49
+ sourceIds: string[];
50
+ tags: string[];
51
+ reviewed: boolean;
52
+ }>;
53
+ skipped: Array<{
54
+ sourceId: string;
55
+ reason: string;
56
+ question?: string;
57
+ }>;
58
+ }>;
59
+ /**
60
+ * Pulls the JSON array of pairs out of a model reply. Accepts a bare array,
61
+ * one inside a ```json fence, or one surrounded by prose; returns null when
62
+ * there is none.
63
+ */
64
+ export function parsePairs(reply: any): any;
@@ -0,0 +1,10 @@
1
+ export class CSVLoader {
2
+ /**
3
+ * Load and parse a CSV file into chunks
4
+ * @param {string} filePath
5
+ * @returns {Promise<Array<{ chunk(): string[] }>>}
6
+ */
7
+ load(filePath: string): Promise<Array<{
8
+ chunk(): string[];
9
+ }>>;
10
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Read a file or every supported file under a directory and return its
3
+ * chunks together with the file they came from. Unlike DirectoryLoader this
4
+ * keeps the source path, which ingestion needs for stable chunk ids,
5
+ * re-ingestion and citations.
6
+ *
7
+ * @param {string} inputPath - File or directory
8
+ * @param {object} [options]
9
+ * @param {string} [options.baseDir=process.cwd()] - Sources are reported relative to this
10
+ * @returns {Promise<Array<{source: string, chunks: string[]}>>}
11
+ */
12
+ export function readDocuments(inputPath: string, options?: {
13
+ baseDir?: string;
14
+ }): Promise<Array<{
15
+ source: string;
16
+ chunks: string[];
17
+ }>>;
18
+ export const SUPPORTED_EXTENSIONS: string[];