@juspay/neurolink 9.36.0 → 9.37.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/CHANGELOG.md +12 -0
- package/dist/auth/errors.d.ts +1 -1
- package/dist/auth/middleware/AuthMiddleware.d.ts +1 -1
- package/dist/auth/providers/BaseAuthProvider.d.ts +1 -1
- package/dist/browser/neurolink.min.js +921 -423
- package/dist/cli/commands/evaluate.d.ts +48 -0
- package/dist/cli/commands/evaluate.js +955 -0
- package/dist/cli/commands/proxy.js +6 -6
- package/dist/cli/parser.js +4 -1
- package/dist/evaluation/BatchEvaluator.d.ts +163 -0
- package/dist/evaluation/BatchEvaluator.js +267 -0
- package/dist/evaluation/EvaluationAggregator.d.ts +272 -0
- package/dist/evaluation/EvaluationAggregator.js +377 -0
- package/dist/evaluation/EvaluatorFactory.d.ts +113 -0
- package/dist/evaluation/EvaluatorFactory.js +280 -0
- package/dist/evaluation/EvaluatorRegistry.d.ts +160 -0
- package/dist/evaluation/EvaluatorRegistry.js +184 -0
- package/dist/evaluation/errors/EvaluationError.d.ts +189 -0
- package/dist/evaluation/errors/EvaluationError.js +206 -0
- package/dist/evaluation/errors/index.d.ts +4 -0
- package/dist/evaluation/errors/index.js +4 -0
- package/dist/evaluation/hooks/index.d.ts +6 -0
- package/dist/evaluation/hooks/index.js +6 -0
- package/dist/evaluation/hooks/langfuseAdapter.d.ts +99 -0
- package/dist/evaluation/hooks/langfuseAdapter.js +172 -0
- package/dist/evaluation/hooks/observabilityHooks.d.ts +129 -0
- package/dist/evaluation/hooks/observabilityHooks.js +181 -0
- package/dist/evaluation/index.d.ts +11 -2
- package/dist/evaluation/index.js +15 -0
- package/dist/evaluation/pipeline/evaluationPipeline.d.ts +114 -0
- package/dist/evaluation/pipeline/evaluationPipeline.js +381 -0
- package/dist/evaluation/pipeline/index.d.ts +8 -0
- package/dist/evaluation/pipeline/index.js +8 -0
- package/dist/evaluation/pipeline/pipelineBuilder.d.ts +126 -0
- package/dist/evaluation/pipeline/pipelineBuilder.js +260 -0
- package/dist/evaluation/pipeline/presets.d.ts +66 -0
- package/dist/evaluation/pipeline/presets.js +224 -0
- package/dist/evaluation/pipeline/strategies/batchStrategy.d.ts +99 -0
- package/dist/evaluation/pipeline/strategies/batchStrategy.js +238 -0
- package/dist/evaluation/pipeline/strategies/index.d.ts +6 -0
- package/dist/evaluation/pipeline/strategies/index.js +6 -0
- package/dist/evaluation/pipeline/strategies/samplingStrategy.d.ts +76 -0
- package/dist/evaluation/pipeline/strategies/samplingStrategy.js +238 -0
- package/dist/evaluation/reporting/index.d.ts +6 -0
- package/dist/evaluation/reporting/index.js +6 -0
- package/dist/evaluation/reporting/metricsCollector.d.ts +147 -0
- package/dist/evaluation/reporting/metricsCollector.js +285 -0
- package/dist/evaluation/reporting/reportGenerator.d.ts +90 -0
- package/dist/evaluation/reporting/reportGenerator.js +374 -0
- package/dist/evaluation/scorers/baseScorer.d.ts +83 -0
- package/dist/evaluation/scorers/baseScorer.js +232 -0
- package/dist/evaluation/scorers/customScorerUtils.d.ts +95 -0
- package/dist/evaluation/scorers/customScorerUtils.js +381 -0
- package/dist/evaluation/scorers/index.d.ts +10 -0
- package/dist/evaluation/scorers/index.js +16 -0
- package/dist/evaluation/scorers/llm/answerRelevancyScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/answerRelevancyScorer.js +99 -0
- package/dist/evaluation/scorers/llm/baseLLMScorer.d.ts +71 -0
- package/dist/evaluation/scorers/llm/baseLLMScorer.js +281 -0
- package/dist/evaluation/scorers/llm/biasDetectionScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/biasDetectionScorer.js +127 -0
- package/dist/evaluation/scorers/llm/contextPrecisionScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/contextPrecisionScorer.js +92 -0
- package/dist/evaluation/scorers/llm/contextRelevancyScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/contextRelevancyScorer.js +107 -0
- package/dist/evaluation/scorers/llm/faithfulnessScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/faithfulnessScorer.js +121 -0
- package/dist/evaluation/scorers/llm/hallucinationScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/hallucinationScorer.js +140 -0
- package/dist/evaluation/scorers/llm/index.d.ts +15 -0
- package/dist/evaluation/scorers/llm/index.js +16 -0
- package/dist/evaluation/scorers/llm/promptAlignmentScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/promptAlignmentScorer.js +106 -0
- package/dist/evaluation/scorers/llm/summarizationScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/summarizationScorer.js +114 -0
- package/dist/evaluation/scorers/llm/toneConsistencyScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/toneConsistencyScorer.js +106 -0
- package/dist/evaluation/scorers/llm/toxicityScorer.d.ts +12 -0
- package/dist/evaluation/scorers/llm/toxicityScorer.js +121 -0
- package/dist/evaluation/scorers/rule/baseRuleScorer.d.ts +77 -0
- package/dist/evaluation/scorers/rule/baseRuleScorer.js +233 -0
- package/dist/evaluation/scorers/rule/contentSimilarityScorer.d.ts +108 -0
- package/dist/evaluation/scorers/rule/contentSimilarityScorer.js +350 -0
- package/dist/evaluation/scorers/rule/formatScorer.d.ts +147 -0
- package/dist/evaluation/scorers/rule/formatScorer.js +470 -0
- package/dist/evaluation/scorers/rule/index.d.ts +9 -0
- package/dist/evaluation/scorers/rule/index.js +10 -0
- package/dist/evaluation/scorers/rule/keywordCoverageScorer.d.ts +83 -0
- package/dist/evaluation/scorers/rule/keywordCoverageScorer.js +347 -0
- package/dist/evaluation/scorers/rule/lengthScorer.d.ts +105 -0
- package/dist/evaluation/scorers/rule/lengthScorer.js +351 -0
- package/dist/evaluation/scorers/scorerBuilder.d.ts +161 -0
- package/dist/evaluation/scorers/scorerBuilder.js +420 -0
- package/dist/evaluation/scorers/scorerRegistry.d.ts +62 -0
- package/dist/evaluation/scorers/scorerRegistry.js +467 -0
- package/dist/index.d.ts +37 -25
- package/dist/index.js +65 -26
- package/dist/lib/auth/providers/BaseAuthProvider.d.ts +1 -1
- package/dist/lib/evaluation/BatchEvaluator.d.ts +163 -0
- package/dist/lib/evaluation/BatchEvaluator.js +268 -0
- package/dist/lib/evaluation/EvaluationAggregator.d.ts +272 -0
- package/dist/lib/evaluation/EvaluationAggregator.js +378 -0
- package/dist/lib/evaluation/EvaluatorFactory.d.ts +113 -0
- package/dist/lib/evaluation/EvaluatorFactory.js +281 -0
- package/dist/lib/evaluation/EvaluatorRegistry.d.ts +160 -0
- package/dist/lib/evaluation/EvaluatorRegistry.js +185 -0
- package/dist/lib/evaluation/errors/EvaluationError.d.ts +189 -0
- package/dist/lib/evaluation/errors/EvaluationError.js +207 -0
- package/dist/lib/evaluation/errors/index.d.ts +4 -0
- package/dist/lib/evaluation/errors/index.js +5 -0
- package/dist/lib/evaluation/hooks/index.d.ts +6 -0
- package/dist/lib/evaluation/hooks/index.js +7 -0
- package/dist/lib/evaluation/hooks/langfuseAdapter.d.ts +99 -0
- package/dist/lib/evaluation/hooks/langfuseAdapter.js +173 -0
- package/dist/lib/evaluation/hooks/observabilityHooks.d.ts +129 -0
- package/dist/lib/evaluation/hooks/observabilityHooks.js +182 -0
- package/dist/lib/evaluation/index.d.ts +11 -2
- package/dist/lib/evaluation/index.js +15 -0
- package/dist/lib/evaluation/pipeline/evaluationPipeline.d.ts +114 -0
- package/dist/lib/evaluation/pipeline/evaluationPipeline.js +382 -0
- package/dist/lib/evaluation/pipeline/index.d.ts +8 -0
- package/dist/lib/evaluation/pipeline/index.js +9 -0
- package/dist/lib/evaluation/pipeline/pipelineBuilder.d.ts +126 -0
- package/dist/lib/evaluation/pipeline/pipelineBuilder.js +261 -0
- package/dist/lib/evaluation/pipeline/presets.d.ts +66 -0
- package/dist/lib/evaluation/pipeline/presets.js +225 -0
- package/dist/lib/evaluation/pipeline/strategies/batchStrategy.d.ts +99 -0
- package/dist/lib/evaluation/pipeline/strategies/batchStrategy.js +239 -0
- package/dist/lib/evaluation/pipeline/strategies/index.d.ts +6 -0
- package/dist/lib/evaluation/pipeline/strategies/index.js +7 -0
- package/dist/lib/evaluation/pipeline/strategies/samplingStrategy.d.ts +76 -0
- package/dist/lib/evaluation/pipeline/strategies/samplingStrategy.js +239 -0
- package/dist/lib/evaluation/reporting/index.d.ts +6 -0
- package/dist/lib/evaluation/reporting/index.js +7 -0
- package/dist/lib/evaluation/reporting/metricsCollector.d.ts +147 -0
- package/dist/lib/evaluation/reporting/metricsCollector.js +286 -0
- package/dist/lib/evaluation/reporting/reportGenerator.d.ts +90 -0
- package/dist/lib/evaluation/reporting/reportGenerator.js +375 -0
- package/dist/lib/evaluation/scorers/baseScorer.d.ts +83 -0
- package/dist/lib/evaluation/scorers/baseScorer.js +233 -0
- package/dist/lib/evaluation/scorers/customScorerUtils.d.ts +95 -0
- package/dist/lib/evaluation/scorers/customScorerUtils.js +382 -0
- package/dist/lib/evaluation/scorers/index.d.ts +10 -0
- package/dist/lib/evaluation/scorers/index.js +17 -0
- package/dist/lib/evaluation/scorers/llm/answerRelevancyScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/answerRelevancyScorer.js +100 -0
- package/dist/lib/evaluation/scorers/llm/baseLLMScorer.d.ts +71 -0
- package/dist/lib/evaluation/scorers/llm/baseLLMScorer.js +282 -0
- package/dist/lib/evaluation/scorers/llm/biasDetectionScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/biasDetectionScorer.js +128 -0
- package/dist/lib/evaluation/scorers/llm/contextPrecisionScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/contextPrecisionScorer.js +93 -0
- package/dist/lib/evaluation/scorers/llm/contextRelevancyScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/contextRelevancyScorer.js +108 -0
- package/dist/lib/evaluation/scorers/llm/faithfulnessScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/faithfulnessScorer.js +122 -0
- package/dist/lib/evaluation/scorers/llm/hallucinationScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/hallucinationScorer.js +141 -0
- package/dist/lib/evaluation/scorers/llm/index.d.ts +15 -0
- package/dist/lib/evaluation/scorers/llm/index.js +17 -0
- package/dist/lib/evaluation/scorers/llm/promptAlignmentScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/promptAlignmentScorer.js +107 -0
- package/dist/lib/evaluation/scorers/llm/summarizationScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/summarizationScorer.js +115 -0
- package/dist/lib/evaluation/scorers/llm/toneConsistencyScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/toneConsistencyScorer.js +107 -0
- package/dist/lib/evaluation/scorers/llm/toxicityScorer.d.ts +12 -0
- package/dist/lib/evaluation/scorers/llm/toxicityScorer.js +122 -0
- package/dist/lib/evaluation/scorers/rule/baseRuleScorer.d.ts +77 -0
- package/dist/lib/evaluation/scorers/rule/baseRuleScorer.js +234 -0
- package/dist/lib/evaluation/scorers/rule/contentSimilarityScorer.d.ts +108 -0
- package/dist/lib/evaluation/scorers/rule/contentSimilarityScorer.js +351 -0
- package/dist/lib/evaluation/scorers/rule/formatScorer.d.ts +147 -0
- package/dist/lib/evaluation/scorers/rule/formatScorer.js +471 -0
- package/dist/lib/evaluation/scorers/rule/index.d.ts +9 -0
- package/dist/lib/evaluation/scorers/rule/index.js +11 -0
- package/dist/lib/evaluation/scorers/rule/keywordCoverageScorer.d.ts +83 -0
- package/dist/lib/evaluation/scorers/rule/keywordCoverageScorer.js +348 -0
- package/dist/lib/evaluation/scorers/rule/lengthScorer.d.ts +105 -0
- package/dist/lib/evaluation/scorers/rule/lengthScorer.js +352 -0
- package/dist/lib/evaluation/scorers/scorerBuilder.d.ts +161 -0
- package/dist/lib/evaluation/scorers/scorerBuilder.js +421 -0
- package/dist/lib/evaluation/scorers/scorerRegistry.d.ts +62 -0
- package/dist/lib/evaluation/scorers/scorerRegistry.js +468 -0
- package/dist/lib/index.d.ts +37 -25
- package/dist/lib/index.js +65 -26
- package/dist/lib/neurolink.d.ts +204 -0
- package/dist/lib/neurolink.js +296 -0
- package/dist/lib/types/index.d.ts +3 -1
- package/dist/lib/types/index.js +3 -2
- package/dist/lib/types/scorerTypes.d.ts +423 -0
- package/dist/lib/types/scorerTypes.js +6 -0
- package/dist/lib/utils/errorHandling.d.ts +20 -0
- package/dist/lib/utils/errorHandling.js +60 -0
- package/dist/neurolink.d.ts +204 -0
- package/dist/neurolink.js +296 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.js +3 -2
- package/dist/types/scorerTypes.d.ts +423 -0
- package/dist/types/scorerTypes.js +5 -0
- package/dist/utils/errorHandling.d.ts +20 -0
- package/dist/utils/errorHandling.js +60 -0
- package/package.json +1 -1
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Batch Strategy
|
|
3
|
+
* Batch processing for evaluation pipelines
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Default batch configuration
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULT_BATCH_CONFIG = {
|
|
9
|
+
concurrency: 5,
|
|
10
|
+
batchDelay: 0,
|
|
11
|
+
continueOnError: true,
|
|
12
|
+
onProgress: () => { },
|
|
13
|
+
onResult: () => { },
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Batch evaluation strategy
|
|
17
|
+
*/
|
|
18
|
+
export class BatchStrategy {
|
|
19
|
+
_pipeline;
|
|
20
|
+
_config;
|
|
21
|
+
constructor(pipeline, config) {
|
|
22
|
+
this._pipeline = pipeline;
|
|
23
|
+
this._config = { ...DEFAULT_BATCH_CONFIG, ...config };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Evaluate a batch of inputs
|
|
27
|
+
*/
|
|
28
|
+
async evaluate(inputs, options) {
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
const results = [];
|
|
31
|
+
const durations = [];
|
|
32
|
+
// Process in batches based on concurrency
|
|
33
|
+
for (let i = 0; i < inputs.length; i += this._config.concurrency) {
|
|
34
|
+
const batch = inputs.slice(i, i + this._config.concurrency);
|
|
35
|
+
// Execute batch in parallel
|
|
36
|
+
const batchPromises = batch.map((input, batchIndex) => {
|
|
37
|
+
const globalIndex = i + batchIndex;
|
|
38
|
+
return this._evaluateItem(input, globalIndex, options);
|
|
39
|
+
});
|
|
40
|
+
const batchResults = await Promise.all(batchPromises);
|
|
41
|
+
// Record results
|
|
42
|
+
for (const result of batchResults) {
|
|
43
|
+
results.push(result);
|
|
44
|
+
durations.push(result.duration);
|
|
45
|
+
// Notify of individual result
|
|
46
|
+
this._config.onResult(result);
|
|
47
|
+
// Check for fatal error
|
|
48
|
+
if (result.error && !this._config.continueOnError) {
|
|
49
|
+
throw new Error(`Batch evaluation failed at index ${result.index}: ${result.error}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Report progress
|
|
53
|
+
this._config.onProgress({
|
|
54
|
+
total: inputs.length,
|
|
55
|
+
completed: results.length,
|
|
56
|
+
failed: results.filter((r) => r.error).length,
|
|
57
|
+
remaining: inputs.length - results.length,
|
|
58
|
+
percentComplete: (results.length / inputs.length) * 100,
|
|
59
|
+
estimatedTimeRemaining: this._estimateRemainingTime(durations, inputs.length - results.length),
|
|
60
|
+
});
|
|
61
|
+
// Apply batch delay if configured
|
|
62
|
+
if (this._config.batchDelay > 0 &&
|
|
63
|
+
i + this._config.concurrency < inputs.length) {
|
|
64
|
+
await this._delay(this._config.batchDelay);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Calculate summary
|
|
68
|
+
const totalDuration = Date.now() - startTime;
|
|
69
|
+
const successfulResults = results.filter((r) => !r.error && r.result);
|
|
70
|
+
const scores = successfulResults.map((r) => r.result.overallScore);
|
|
71
|
+
const passed = successfulResults.filter((r) => r.result.passed);
|
|
72
|
+
return {
|
|
73
|
+
results,
|
|
74
|
+
summary: {
|
|
75
|
+
total: inputs.length,
|
|
76
|
+
successful: successfulResults.length,
|
|
77
|
+
failed: results.length - successfulResults.length,
|
|
78
|
+
averageScore: scores.length > 0
|
|
79
|
+
? scores.reduce((a, b) => a + b, 0) / scores.length
|
|
80
|
+
: 0,
|
|
81
|
+
passRate: successfulResults.length > 0
|
|
82
|
+
? passed.length / successfulResults.length
|
|
83
|
+
: 0,
|
|
84
|
+
totalDuration,
|
|
85
|
+
averageDuration: durations.length > 0
|
|
86
|
+
? durations.reduce((a, b) => a + b, 0) / durations.length
|
|
87
|
+
: 0,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Evaluate a single item
|
|
93
|
+
*/
|
|
94
|
+
async _evaluateItem(input, index, options) {
|
|
95
|
+
const startTime = Date.now();
|
|
96
|
+
try {
|
|
97
|
+
const result = await this._pipeline.execute(input, {
|
|
98
|
+
...options,
|
|
99
|
+
correlationId: options?.correlationId
|
|
100
|
+
? `${options.correlationId}-${index}`
|
|
101
|
+
: `batch-${index}`,
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
index,
|
|
105
|
+
input,
|
|
106
|
+
result,
|
|
107
|
+
duration: Date.now() - startTime,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
return {
|
|
112
|
+
index,
|
|
113
|
+
input,
|
|
114
|
+
error: error instanceof Error ? error.message : String(error),
|
|
115
|
+
duration: Date.now() - startTime,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Estimate remaining time based on average duration
|
|
121
|
+
*/
|
|
122
|
+
_estimateRemainingTime(durations, remaining) {
|
|
123
|
+
if (durations.length === 0 || remaining === 0) {
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
const avgDuration = durations.reduce((a, b) => a + b, 0) / durations.length;
|
|
127
|
+
const batches = Math.ceil(remaining / this._config.concurrency);
|
|
128
|
+
return avgDuration * batches + this._config.batchDelay * (batches - 1);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Delay helper
|
|
132
|
+
*/
|
|
133
|
+
_delay(ms) {
|
|
134
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Update configuration
|
|
138
|
+
*/
|
|
139
|
+
configure(config) {
|
|
140
|
+
this._config = { ...this._config, ...config };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Create a batch strategy for a pipeline
|
|
145
|
+
*/
|
|
146
|
+
export function createBatchStrategy(pipeline, config) {
|
|
147
|
+
return new BatchStrategy(pipeline, config);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Evaluate a batch of inputs using a pipeline
|
|
151
|
+
*/
|
|
152
|
+
export async function evaluateBatch(pipeline, inputs, config) {
|
|
153
|
+
const strategy = new BatchStrategy(pipeline, config);
|
|
154
|
+
return strategy.evaluate(inputs);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Stream batch evaluation results
|
|
158
|
+
*/
|
|
159
|
+
export async function* streamBatchEvaluation(pipeline, inputs, config) {
|
|
160
|
+
const results = [];
|
|
161
|
+
const durations = [];
|
|
162
|
+
const startTime = Date.now();
|
|
163
|
+
const batchConfig = { ...DEFAULT_BATCH_CONFIG, ...config };
|
|
164
|
+
for (let i = 0; i < inputs.length; i += batchConfig.concurrency) {
|
|
165
|
+
const batch = inputs.slice(i, i + batchConfig.concurrency);
|
|
166
|
+
const batchPromises = batch.map(async (input, batchIndex) => {
|
|
167
|
+
const globalIndex = i + batchIndex;
|
|
168
|
+
const itemStart = Date.now();
|
|
169
|
+
try {
|
|
170
|
+
const result = await pipeline.execute(input, {
|
|
171
|
+
correlationId: `stream-batch-${globalIndex}`,
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
index: globalIndex,
|
|
175
|
+
input,
|
|
176
|
+
result,
|
|
177
|
+
duration: Date.now() - itemStart,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
return {
|
|
182
|
+
index: globalIndex,
|
|
183
|
+
input,
|
|
184
|
+
error: error instanceof Error ? error.message : String(error),
|
|
185
|
+
duration: Date.now() - itemStart,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
const batchResults = await Promise.all(batchPromises);
|
|
190
|
+
for (const result of batchResults) {
|
|
191
|
+
results.push(result);
|
|
192
|
+
durations.push(result.duration);
|
|
193
|
+
// If continueOnError is false and this result has an error, abort and return summary
|
|
194
|
+
if (result.error && batchConfig.continueOnError === false) {
|
|
195
|
+
const successfulResults = results.filter((r) => !r.error && r.result);
|
|
196
|
+
const earlyScores = successfulResults.map((r) => r.result.overallScore);
|
|
197
|
+
const earlyPassed = successfulResults.filter((r) => r.result.passed);
|
|
198
|
+
return {
|
|
199
|
+
total: inputs.length,
|
|
200
|
+
successful: successfulResults.length,
|
|
201
|
+
failed: results.length - successfulResults.length,
|
|
202
|
+
averageScore: earlyScores.length > 0
|
|
203
|
+
? earlyScores.reduce((a, b) => a + b, 0) / earlyScores.length
|
|
204
|
+
: 0,
|
|
205
|
+
passRate: successfulResults.length > 0
|
|
206
|
+
? earlyPassed.length / successfulResults.length
|
|
207
|
+
: 0,
|
|
208
|
+
totalDuration: Date.now() - startTime,
|
|
209
|
+
averageDuration: durations.length > 0
|
|
210
|
+
? durations.reduce((a, b) => a + b, 0) / durations.length
|
|
211
|
+
: 0,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
yield result;
|
|
215
|
+
}
|
|
216
|
+
if (batchConfig.batchDelay > 0 &&
|
|
217
|
+
i + batchConfig.concurrency < inputs.length) {
|
|
218
|
+
await new Promise((resolve) => setTimeout(resolve, batchConfig.batchDelay));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Return summary
|
|
222
|
+
const successfulResults = results.filter((r) => !r.error && r.result);
|
|
223
|
+
const scores = successfulResults.map((r) => r.result.overallScore);
|
|
224
|
+
const passed = successfulResults.filter((r) => r.result.passed);
|
|
225
|
+
return {
|
|
226
|
+
total: inputs.length,
|
|
227
|
+
successful: successfulResults.length,
|
|
228
|
+
failed: results.length - successfulResults.length,
|
|
229
|
+
averageScore: scores.length > 0 ? scores.reduce((a, b) => a + b, 0) / scores.length : 0,
|
|
230
|
+
passRate: successfulResults.length > 0
|
|
231
|
+
? passed.length / successfulResults.length
|
|
232
|
+
: 0,
|
|
233
|
+
totalDuration: Date.now() - startTime,
|
|
234
|
+
averageDuration: durations.length > 0
|
|
235
|
+
? durations.reduce((a, b) => a + b, 0) / durations.length
|
|
236
|
+
: 0,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pipeline Strategies Index
|
|
3
|
+
* Export all pipeline strategies
|
|
4
|
+
*/
|
|
5
|
+
export { type BatchConfig, type BatchItemResult, type BatchProgress, type BatchResult, BatchStrategy, createBatchStrategy, evaluateBatch, streamBatchEvaluation, } from "./batchStrategy.js";
|
|
6
|
+
export { createSamplingStrategy, DEFAULT_SAMPLING_CONFIG, SamplingStrategies, SamplingStrategy, } from "./samplingStrategy.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pipeline Strategies Index
|
|
3
|
+
* Export all pipeline strategies
|
|
4
|
+
*/
|
|
5
|
+
export { BatchStrategy, createBatchStrategy, evaluateBatch, streamBatchEvaluation, } from "./batchStrategy.js";
|
|
6
|
+
export { createSamplingStrategy, DEFAULT_SAMPLING_CONFIG, SamplingStrategies, SamplingStrategy, } from "./samplingStrategy.js";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Sampling Strategy
|
|
3
|
+
* Configurable sampling for cost-efficient evaluation
|
|
4
|
+
*/
|
|
5
|
+
import type { SamplingConfig, SamplingContext, SamplingDecision } from "../../../types/scorerTypes.js";
|
|
6
|
+
/**
|
|
7
|
+
* Default sampling configuration
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_SAMPLING_CONFIG: SamplingConfig;
|
|
10
|
+
/**
|
|
11
|
+
* Sampling strategy for evaluation
|
|
12
|
+
*/
|
|
13
|
+
export declare class SamplingStrategy {
|
|
14
|
+
private _config;
|
|
15
|
+
private _recentScores;
|
|
16
|
+
private _currentRate;
|
|
17
|
+
private _maxRecentScores;
|
|
18
|
+
constructor(config?: Partial<SamplingConfig>);
|
|
19
|
+
/**
|
|
20
|
+
* Get current sampling configuration
|
|
21
|
+
*/
|
|
22
|
+
get config(): SamplingConfig;
|
|
23
|
+
/**
|
|
24
|
+
* Get current sampling rate
|
|
25
|
+
*/
|
|
26
|
+
get currentRate(): number;
|
|
27
|
+
/**
|
|
28
|
+
* Decide whether to sample a request
|
|
29
|
+
*/
|
|
30
|
+
shouldSample(context?: SamplingContext): SamplingDecision;
|
|
31
|
+
/**
|
|
32
|
+
* Record a score for adaptive sampling
|
|
33
|
+
*/
|
|
34
|
+
recordScore(score: number): void;
|
|
35
|
+
/**
|
|
36
|
+
* Update sampling rate based on recent quality
|
|
37
|
+
*/
|
|
38
|
+
private _updateAdaptiveRate;
|
|
39
|
+
/**
|
|
40
|
+
* Reset sampling state
|
|
41
|
+
*/
|
|
42
|
+
reset(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Update sampling configuration
|
|
45
|
+
*/
|
|
46
|
+
configure(config: Partial<SamplingConfig>): void;
|
|
47
|
+
/**
|
|
48
|
+
* Get sampling statistics
|
|
49
|
+
*/
|
|
50
|
+
getStats(): {
|
|
51
|
+
currentRate: number;
|
|
52
|
+
recentScoresCount: number;
|
|
53
|
+
averageScore: number | null;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create a sampling strategy
|
|
58
|
+
*/
|
|
59
|
+
export declare function createSamplingStrategy(config?: Partial<SamplingConfig>): SamplingStrategy;
|
|
60
|
+
/**
|
|
61
|
+
* Pre-configured sampling strategies
|
|
62
|
+
*/
|
|
63
|
+
export declare const SamplingStrategies: {
|
|
64
|
+
/** Evaluate everything (default) */
|
|
65
|
+
readonly all: () => SamplingStrategy;
|
|
66
|
+
/** Evaluate 50% of requests */
|
|
67
|
+
readonly half: () => SamplingStrategy;
|
|
68
|
+
/** Evaluate 10% of requests */
|
|
69
|
+
readonly light: () => SamplingStrategy;
|
|
70
|
+
/** Adaptive sampling based on quality */
|
|
71
|
+
readonly adaptive: () => SamplingStrategy;
|
|
72
|
+
/** Only evaluate errors and specific conditions */
|
|
73
|
+
readonly errorsOnly: () => SamplingStrategy;
|
|
74
|
+
/** VIP users always evaluated */
|
|
75
|
+
readonly vipUsers: (users: string[]) => SamplingStrategy;
|
|
76
|
+
};
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Sampling Strategy
|
|
3
|
+
* Configurable sampling for cost-efficient evaluation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Default sampling configuration
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_SAMPLING_CONFIG = {
|
|
9
|
+
rate: 1.0, // 100% sampling by default
|
|
10
|
+
alwaysEvaluate: {
|
|
11
|
+
errors: true,
|
|
12
|
+
},
|
|
13
|
+
adaptive: {
|
|
14
|
+
enabled: false,
|
|
15
|
+
qualityThreshold: 0.7,
|
|
16
|
+
minRate: 0.1,
|
|
17
|
+
maxRate: 1.0,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Sampling strategy for evaluation
|
|
22
|
+
*/
|
|
23
|
+
export class SamplingStrategy {
|
|
24
|
+
_config;
|
|
25
|
+
_recentScores = [];
|
|
26
|
+
_currentRate;
|
|
27
|
+
_maxRecentScores = 100;
|
|
28
|
+
constructor(config = {}) {
|
|
29
|
+
const clamp01 = (v) => Math.max(0, Math.min(1, v));
|
|
30
|
+
const rawRate = config.rate ?? DEFAULT_SAMPLING_CONFIG.rate;
|
|
31
|
+
const rawMinRate = config.adaptive?.minRate ?? DEFAULT_SAMPLING_CONFIG.adaptive.minRate;
|
|
32
|
+
const rawMaxRate = config.adaptive?.maxRate ?? DEFAULT_SAMPLING_CONFIG.adaptive.maxRate;
|
|
33
|
+
const minRate = clamp01(Math.min(rawMinRate, rawMaxRate));
|
|
34
|
+
const maxRate = clamp01(Math.max(rawMinRate, rawMaxRate));
|
|
35
|
+
this._config = {
|
|
36
|
+
...DEFAULT_SAMPLING_CONFIG,
|
|
37
|
+
...config,
|
|
38
|
+
rate: clamp01(rawRate),
|
|
39
|
+
alwaysEvaluate: {
|
|
40
|
+
...DEFAULT_SAMPLING_CONFIG.alwaysEvaluate,
|
|
41
|
+
...(config.alwaysEvaluate ?? {}),
|
|
42
|
+
},
|
|
43
|
+
adaptive: {
|
|
44
|
+
enabled: config.adaptive?.enabled ?? DEFAULT_SAMPLING_CONFIG.adaptive.enabled,
|
|
45
|
+
qualityThreshold: clamp01(config.adaptive?.qualityThreshold ??
|
|
46
|
+
DEFAULT_SAMPLING_CONFIG.adaptive.qualityThreshold),
|
|
47
|
+
minRate,
|
|
48
|
+
maxRate,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
this._currentRate = this._config.rate;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get current sampling configuration
|
|
55
|
+
*/
|
|
56
|
+
get config() {
|
|
57
|
+
return this._config;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get current sampling rate
|
|
61
|
+
*/
|
|
62
|
+
get currentRate() {
|
|
63
|
+
return this._currentRate;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Decide whether to sample a request
|
|
67
|
+
*/
|
|
68
|
+
shouldSample(context) {
|
|
69
|
+
// Always evaluate errors
|
|
70
|
+
if (context?.hasError && this._config.alwaysEvaluate?.errors) {
|
|
71
|
+
return {
|
|
72
|
+
shouldSample: true,
|
|
73
|
+
reason: "Always evaluate errors",
|
|
74
|
+
currentRate: this._currentRate,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Always evaluate specific users
|
|
78
|
+
if (context?.userId &&
|
|
79
|
+
this._config.alwaysEvaluate?.users?.includes(context.userId)) {
|
|
80
|
+
return {
|
|
81
|
+
shouldSample: true,
|
|
82
|
+
reason: `Always evaluate user: ${context.userId}`,
|
|
83
|
+
currentRate: this._currentRate,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Always evaluate specific tags
|
|
87
|
+
if (context?.tags && this._config.alwaysEvaluate?.tags) {
|
|
88
|
+
const matchingTags = context.tags.filter((tag) => this._config.alwaysEvaluate?.tags?.includes(tag));
|
|
89
|
+
if (matchingTags.length > 0) {
|
|
90
|
+
return {
|
|
91
|
+
shouldSample: true,
|
|
92
|
+
reason: `Always evaluate tags: ${matchingTags.join(", ")}`,
|
|
93
|
+
currentRate: this._currentRate,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Random sampling based on current rate
|
|
98
|
+
const random = Math.random();
|
|
99
|
+
const shouldSample = random < this._currentRate;
|
|
100
|
+
return {
|
|
101
|
+
shouldSample,
|
|
102
|
+
reason: shouldSample
|
|
103
|
+
? `Sampled at ${(this._currentRate * 100).toFixed(1)}% rate`
|
|
104
|
+
: `Not sampled (rate: ${(this._currentRate * 100).toFixed(1)}%)`,
|
|
105
|
+
currentRate: this._currentRate,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Record a score for adaptive sampling
|
|
110
|
+
*/
|
|
111
|
+
recordScore(score) {
|
|
112
|
+
if (!Number.isFinite(score)) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const boundedScore = Math.max(0, Math.min(10, score));
|
|
116
|
+
this._recentScores.push(boundedScore);
|
|
117
|
+
// Keep only recent scores
|
|
118
|
+
if (this._recentScores.length > this._maxRecentScores) {
|
|
119
|
+
this._recentScores.shift();
|
|
120
|
+
}
|
|
121
|
+
// Update adaptive rate if enabled
|
|
122
|
+
if (this._config.adaptive?.enabled) {
|
|
123
|
+
this._updateAdaptiveRate();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Update sampling rate based on recent quality
|
|
128
|
+
*/
|
|
129
|
+
_updateAdaptiveRate() {
|
|
130
|
+
if (!this._config.adaptive?.enabled || this._recentScores.length < 10) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const adaptive = this._config.adaptive;
|
|
134
|
+
const avgScore = this._recentScores.reduce((sum, s) => sum + s, 0) /
|
|
135
|
+
this._recentScores.length;
|
|
136
|
+
// Normalize to 0-1 scale (assuming 0-10 scores)
|
|
137
|
+
const normalizedAvg = avgScore / 10;
|
|
138
|
+
if (normalizedAvg < adaptive.qualityThreshold) {
|
|
139
|
+
// Low quality - increase sampling rate
|
|
140
|
+
this._currentRate = Math.min(adaptive.maxRate, this._currentRate * 1.2);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// High quality - can decrease sampling rate
|
|
144
|
+
this._currentRate = Math.max(adaptive.minRate, this._currentRate * 0.9);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Reset sampling state
|
|
149
|
+
*/
|
|
150
|
+
reset() {
|
|
151
|
+
this._recentScores = [];
|
|
152
|
+
this._currentRate = this._config.rate;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Update sampling configuration
|
|
156
|
+
*/
|
|
157
|
+
configure(config) {
|
|
158
|
+
const clamp01 = (v) => Math.max(0, Math.min(1, v));
|
|
159
|
+
const rawRate = config.rate ?? this._config.rate;
|
|
160
|
+
const rawMinRate = config.adaptive?.minRate ?? this._config.adaptive.minRate;
|
|
161
|
+
const rawMaxRate = config.adaptive?.maxRate ?? this._config.adaptive.maxRate;
|
|
162
|
+
const minRate = clamp01(Math.min(rawMinRate, rawMaxRate));
|
|
163
|
+
const maxRate = clamp01(Math.max(rawMinRate, rawMaxRate));
|
|
164
|
+
this._config = {
|
|
165
|
+
...this._config,
|
|
166
|
+
...config,
|
|
167
|
+
rate: clamp01(rawRate),
|
|
168
|
+
alwaysEvaluate: {
|
|
169
|
+
...this._config.alwaysEvaluate,
|
|
170
|
+
...(config.alwaysEvaluate ?? {}),
|
|
171
|
+
},
|
|
172
|
+
adaptive: {
|
|
173
|
+
enabled: config.adaptive?.enabled ?? this._config.adaptive.enabled,
|
|
174
|
+
qualityThreshold: clamp01(config.adaptive?.qualityThreshold ??
|
|
175
|
+
this._config.adaptive.qualityThreshold),
|
|
176
|
+
minRate,
|
|
177
|
+
maxRate,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
this._currentRate = this._config.rate;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get sampling statistics
|
|
184
|
+
*/
|
|
185
|
+
getStats() {
|
|
186
|
+
const avgScore = this._recentScores.length > 0
|
|
187
|
+
? this._recentScores.reduce((sum, s) => sum + s, 0) /
|
|
188
|
+
this._recentScores.length
|
|
189
|
+
: null;
|
|
190
|
+
return {
|
|
191
|
+
currentRate: this._currentRate,
|
|
192
|
+
recentScoresCount: this._recentScores.length,
|
|
193
|
+
averageScore: avgScore,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Create a sampling strategy
|
|
199
|
+
*/
|
|
200
|
+
export function createSamplingStrategy(config) {
|
|
201
|
+
return new SamplingStrategy(config);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Pre-configured sampling strategies
|
|
205
|
+
*/
|
|
206
|
+
export const SamplingStrategies = {
|
|
207
|
+
/** Evaluate everything (default) */
|
|
208
|
+
all: () => new SamplingStrategy({ rate: 1.0 }),
|
|
209
|
+
/** Evaluate 50% of requests */
|
|
210
|
+
half: () => new SamplingStrategy({ rate: 0.5 }),
|
|
211
|
+
/** Evaluate 10% of requests */
|
|
212
|
+
light: () => new SamplingStrategy({ rate: 0.1 }),
|
|
213
|
+
/** Adaptive sampling based on quality */
|
|
214
|
+
adaptive: () => new SamplingStrategy({
|
|
215
|
+
rate: 0.5,
|
|
216
|
+
adaptive: {
|
|
217
|
+
enabled: true,
|
|
218
|
+
qualityThreshold: 0.7,
|
|
219
|
+
minRate: 0.1,
|
|
220
|
+
maxRate: 1.0,
|
|
221
|
+
},
|
|
222
|
+
}),
|
|
223
|
+
/** Only evaluate errors and specific conditions */
|
|
224
|
+
errorsOnly: () => new SamplingStrategy({
|
|
225
|
+
rate: 0.0,
|
|
226
|
+
alwaysEvaluate: {
|
|
227
|
+
errors: true,
|
|
228
|
+
},
|
|
229
|
+
}),
|
|
230
|
+
/** VIP users always evaluated */
|
|
231
|
+
vipUsers: (users) => new SamplingStrategy({
|
|
232
|
+
rate: 0.1,
|
|
233
|
+
alwaysEvaluate: {
|
|
234
|
+
errors: true,
|
|
235
|
+
users,
|
|
236
|
+
},
|
|
237
|
+
}),
|
|
238
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Reporting Index
|
|
3
|
+
* Export all reporting components
|
|
4
|
+
*/
|
|
5
|
+
export { type AggregatedMetrics, createMetricsCollector, globalMetricsCollector, MetricsCollector, type PipelineMetrics, type ScorerMetrics, } from "./metricsCollector.js";
|
|
6
|
+
export { createReportGenerator, type GeneratedReport, type ReportData, ReportGenerator, Reports, } from "./reportGenerator.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Reporting Index
|
|
3
|
+
* Export all reporting components
|
|
4
|
+
*/
|
|
5
|
+
export { createMetricsCollector, globalMetricsCollector, MetricsCollector, } from "./metricsCollector.js";
|
|
6
|
+
export { createReportGenerator, ReportGenerator, Reports, } from "./reportGenerator.js";
|