@juspay/neurolink 9.36.1 → 9.38.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 +1105 -556
- package/dist/cli/commands/evaluate.d.ts +48 -0
- package/dist/cli/commands/evaluate.js +955 -0
- 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/processors/media/VideoProcessor.d.ts +8 -2
- package/dist/lib/processors/media/VideoProcessor.js +90 -41
- package/dist/lib/telemetry/telemetryService.d.ts +1 -1
- package/dist/lib/telemetry/telemetryService.js +27 -13
- 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/processors/media/VideoProcessor.d.ts +8 -2
- package/dist/processors/media/VideoProcessor.js +90 -41
- package/dist/telemetry/telemetryService.d.ts +1 -1
- package/dist/telemetry/telemetryService.js +27 -13
- 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 +7 -7
- package/dist/processors/media/ffprobe-static.d.ts +0 -4
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Scorer Builder
|
|
3
|
+
* Fluent builder API for creating custom scorers
|
|
4
|
+
*/
|
|
5
|
+
import { composeScorers, createFunctionScorer, } from "./customScorerUtils.js";
|
|
6
|
+
/**
|
|
7
|
+
* Fluent builder for creating custom scorers
|
|
8
|
+
*/
|
|
9
|
+
export class ScorerBuilder {
|
|
10
|
+
_id;
|
|
11
|
+
_name;
|
|
12
|
+
_description;
|
|
13
|
+
_type = "rule";
|
|
14
|
+
_category = "custom";
|
|
15
|
+
_version = "1.0.0";
|
|
16
|
+
_requiredInputs = ["response"];
|
|
17
|
+
_optionalInputs = [
|
|
18
|
+
"query",
|
|
19
|
+
"context",
|
|
20
|
+
"groundTruth",
|
|
21
|
+
];
|
|
22
|
+
_threshold = 0.7;
|
|
23
|
+
_weight = 1.0;
|
|
24
|
+
_timeout = 5000;
|
|
25
|
+
_retries = 0;
|
|
26
|
+
_scorerFn;
|
|
27
|
+
_rules = [];
|
|
28
|
+
_subScorers = [];
|
|
29
|
+
_aggregation = "average";
|
|
30
|
+
_subScorerWeights = [];
|
|
31
|
+
constructor(id, name) {
|
|
32
|
+
this._id = id;
|
|
33
|
+
this._name = name;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a new scorer builder
|
|
37
|
+
*/
|
|
38
|
+
static create(id, name) {
|
|
39
|
+
return new ScorerBuilder(id, name);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Set scorer description
|
|
43
|
+
*/
|
|
44
|
+
description(desc) {
|
|
45
|
+
this._description = desc;
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Set scorer type
|
|
50
|
+
*/
|
|
51
|
+
type(type) {
|
|
52
|
+
this._type = type;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Set scorer category
|
|
57
|
+
*/
|
|
58
|
+
category(category) {
|
|
59
|
+
this._category = category;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Set scorer version
|
|
64
|
+
*/
|
|
65
|
+
version(version) {
|
|
66
|
+
this._version = version;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set required inputs
|
|
71
|
+
*/
|
|
72
|
+
requireInputs(...inputs) {
|
|
73
|
+
this._requiredInputs = inputs;
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Set optional inputs
|
|
78
|
+
*/
|
|
79
|
+
optionalInputs(...inputs) {
|
|
80
|
+
this._optionalInputs = inputs;
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Set pass/fail threshold
|
|
85
|
+
*/
|
|
86
|
+
threshold(threshold) {
|
|
87
|
+
this._threshold = threshold;
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Set weight for aggregation
|
|
92
|
+
*/
|
|
93
|
+
weight(weight) {
|
|
94
|
+
this._weight = weight;
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Set execution timeout
|
|
99
|
+
*/
|
|
100
|
+
timeout(ms) {
|
|
101
|
+
this._timeout = ms;
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Set retry count
|
|
106
|
+
*/
|
|
107
|
+
retries(count) {
|
|
108
|
+
this._retries = count;
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Set the scoring function
|
|
113
|
+
*/
|
|
114
|
+
scoringFunction(fn) {
|
|
115
|
+
this._scorerFn = fn;
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Add a sub-scorer for composition
|
|
120
|
+
*/
|
|
121
|
+
addScorer(scorer, weight) {
|
|
122
|
+
this._subScorers.push(scorer);
|
|
123
|
+
this._subScorerWeights.push(weight ?? 1.0);
|
|
124
|
+
return this;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Set aggregation method for composed scorers
|
|
128
|
+
*/
|
|
129
|
+
aggregateWith(method) {
|
|
130
|
+
this._aggregation = method;
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Add a regex check rule
|
|
135
|
+
*/
|
|
136
|
+
matchesPattern(pattern, options) {
|
|
137
|
+
const patternStr = typeof pattern === "string" ? pattern : pattern.source;
|
|
138
|
+
const flags = typeof pattern === "string" ? "gi" : pattern.flags;
|
|
139
|
+
// Validate pattern safety (same guards as regex scorer utilities)
|
|
140
|
+
if (patternStr.length > 200) {
|
|
141
|
+
throw new Error("Regex pattern exceeds maximum length of 200 characters");
|
|
142
|
+
}
|
|
143
|
+
if (/(\+|\*|\{)\S*(\+|\*|\{)/.test(patternStr)) {
|
|
144
|
+
throw new Error("Regex pattern contains nested quantifiers which may cause catastrophic backtracking");
|
|
145
|
+
}
|
|
146
|
+
// Pre-compile to validate the pattern at build time
|
|
147
|
+
try {
|
|
148
|
+
new RegExp(patternStr, flags);
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
throw new Error(`Invalid regex pattern: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
|
|
152
|
+
}
|
|
153
|
+
this._rules.push({
|
|
154
|
+
id: options?.id ?? `regex-${this._rules.length}`,
|
|
155
|
+
description: `Match pattern: ${patternStr}`,
|
|
156
|
+
type: "regex",
|
|
157
|
+
params: {
|
|
158
|
+
pattern: patternStr,
|
|
159
|
+
flags,
|
|
160
|
+
},
|
|
161
|
+
weight: options?.weight ?? 1.0,
|
|
162
|
+
});
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Add a keyword check rule
|
|
167
|
+
*/
|
|
168
|
+
containsKeyword(keyword, options) {
|
|
169
|
+
this._rules.push({
|
|
170
|
+
id: options?.id ?? `keyword-${this._rules.length}`,
|
|
171
|
+
description: `Contains keyword: ${keyword}`,
|
|
172
|
+
type: "keyword",
|
|
173
|
+
params: {
|
|
174
|
+
keyword,
|
|
175
|
+
caseInsensitive: true,
|
|
176
|
+
},
|
|
177
|
+
weight: options?.weight ?? 1.0,
|
|
178
|
+
});
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Add a length check rule
|
|
183
|
+
*/
|
|
184
|
+
hasLength(options) {
|
|
185
|
+
this._rules.push({
|
|
186
|
+
id: options.id ?? `length-${this._rules.length}`,
|
|
187
|
+
description: "Length check",
|
|
188
|
+
type: "length",
|
|
189
|
+
params: {
|
|
190
|
+
minWords: options.minWords ?? null,
|
|
191
|
+
maxWords: options.maxWords ?? null,
|
|
192
|
+
minChars: options.minChars ?? null,
|
|
193
|
+
maxChars: options.maxChars ?? null,
|
|
194
|
+
},
|
|
195
|
+
weight: options.weight ?? 1.0,
|
|
196
|
+
});
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Add a custom rule
|
|
201
|
+
*/
|
|
202
|
+
customRule(rule) {
|
|
203
|
+
this._rules.push(rule);
|
|
204
|
+
return this;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Build the scorer
|
|
208
|
+
*/
|
|
209
|
+
build() {
|
|
210
|
+
// If we have sub-scorers, create a composed scorer
|
|
211
|
+
if (this._subScorers.length > 0) {
|
|
212
|
+
return composeScorers(this._id, this._name, this._subScorers, {
|
|
213
|
+
aggregation: this._aggregation,
|
|
214
|
+
weights: this._subScorerWeights,
|
|
215
|
+
description: this._description,
|
|
216
|
+
config: this._buildConfig(),
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
// If we have a scoring function, use it
|
|
220
|
+
if (this._scorerFn) {
|
|
221
|
+
return createFunctionScorer(this._id, this._name, this._scorerFn, {
|
|
222
|
+
type: this._type,
|
|
223
|
+
version: this._version,
|
|
224
|
+
requiredInputs: this._requiredInputs,
|
|
225
|
+
optionalInputs: this._optionalInputs,
|
|
226
|
+
description: this._description,
|
|
227
|
+
category: this._category,
|
|
228
|
+
config: this._buildConfig(),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
// If we have rules, create a rule-based scorer
|
|
232
|
+
if (this._rules.length > 0) {
|
|
233
|
+
return this._buildRuleScorer();
|
|
234
|
+
}
|
|
235
|
+
// Default: return a pass-through scorer
|
|
236
|
+
return createFunctionScorer(this._id, this._name, async () => ({
|
|
237
|
+
score: 10,
|
|
238
|
+
reasoning: "No scoring logic defined - passing by default",
|
|
239
|
+
}), {
|
|
240
|
+
type: this._type,
|
|
241
|
+
version: this._version,
|
|
242
|
+
requiredInputs: this._requiredInputs,
|
|
243
|
+
optionalInputs: this._optionalInputs,
|
|
244
|
+
description: this._description,
|
|
245
|
+
category: this._category,
|
|
246
|
+
config: this._buildConfig(),
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Build configuration object
|
|
251
|
+
*/
|
|
252
|
+
_buildConfig() {
|
|
253
|
+
return {
|
|
254
|
+
enabled: true,
|
|
255
|
+
threshold: this._threshold,
|
|
256
|
+
weight: this._weight,
|
|
257
|
+
timeout: this._timeout,
|
|
258
|
+
retries: this._retries,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Build a rule-based scorer from accumulated rules
|
|
263
|
+
*/
|
|
264
|
+
_buildRuleScorer() {
|
|
265
|
+
const rules = this._rules;
|
|
266
|
+
const config = this._buildConfig();
|
|
267
|
+
return createFunctionScorer(this._id, this._name, async (input) => {
|
|
268
|
+
const results = [];
|
|
269
|
+
for (const rule of rules) {
|
|
270
|
+
const result = this._evaluateRule(rule, input);
|
|
271
|
+
results.push({ rule, ...result });
|
|
272
|
+
}
|
|
273
|
+
// Calculate weighted score
|
|
274
|
+
let totalWeight = 0;
|
|
275
|
+
let weightedScore = 0;
|
|
276
|
+
for (const result of results) {
|
|
277
|
+
const weight = result.rule.weight ?? 1.0;
|
|
278
|
+
totalWeight += weight;
|
|
279
|
+
weightedScore += result.score * weight;
|
|
280
|
+
}
|
|
281
|
+
const finalScore = totalWeight > 0 ? (weightedScore / totalWeight) * 10 : 10;
|
|
282
|
+
const passedCount = results.filter((r) => r.passed).length;
|
|
283
|
+
return {
|
|
284
|
+
score: finalScore,
|
|
285
|
+
reasoning: `${passedCount}/${rules.length} rules passed`,
|
|
286
|
+
metadata: {
|
|
287
|
+
ruleResults: results.map((r) => ({
|
|
288
|
+
ruleId: r.rule.id,
|
|
289
|
+
passed: r.passed,
|
|
290
|
+
score: r.score,
|
|
291
|
+
})),
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
}, {
|
|
295
|
+
type: this._type,
|
|
296
|
+
version: this._version,
|
|
297
|
+
requiredInputs: this._requiredInputs,
|
|
298
|
+
optionalInputs: this._optionalInputs,
|
|
299
|
+
description: this._description,
|
|
300
|
+
category: this._category,
|
|
301
|
+
config,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Evaluate a single rule
|
|
306
|
+
*/
|
|
307
|
+
_evaluateRule(rule, input) {
|
|
308
|
+
switch (rule.type) {
|
|
309
|
+
case "regex": {
|
|
310
|
+
let regex;
|
|
311
|
+
try {
|
|
312
|
+
regex = new RegExp(rule.params.pattern, rule.params.flags ?? "i");
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return { passed: false, score: 0.0 };
|
|
316
|
+
}
|
|
317
|
+
if (regex.global) {
|
|
318
|
+
regex.lastIndex = 0;
|
|
319
|
+
}
|
|
320
|
+
const matches = regex.test(input.response);
|
|
321
|
+
return { passed: matches, score: matches ? 1.0 : 0.0 };
|
|
322
|
+
}
|
|
323
|
+
case "keyword": {
|
|
324
|
+
const keyword = rule.params.keyword;
|
|
325
|
+
const caseInsensitive = rule.params.caseInsensitive;
|
|
326
|
+
const text = caseInsensitive
|
|
327
|
+
? input.response.toLowerCase()
|
|
328
|
+
: input.response;
|
|
329
|
+
const search = caseInsensitive ? keyword.toLowerCase() : keyword;
|
|
330
|
+
const found = text.includes(search);
|
|
331
|
+
return { passed: found, score: found ? 1.0 : 0.0 };
|
|
332
|
+
}
|
|
333
|
+
case "length": {
|
|
334
|
+
const wordCount = input.response
|
|
335
|
+
.trim()
|
|
336
|
+
.split(/\s+/)
|
|
337
|
+
.filter((w) => w.length > 0).length;
|
|
338
|
+
const charCount = input.response.length;
|
|
339
|
+
const minWords = rule.params.minWords;
|
|
340
|
+
const maxWords = rule.params.maxWords;
|
|
341
|
+
const minChars = rule.params.minChars;
|
|
342
|
+
const maxChars = rule.params.maxChars;
|
|
343
|
+
let passed = true;
|
|
344
|
+
if (minWords !== null && wordCount < minWords) {
|
|
345
|
+
passed = false;
|
|
346
|
+
}
|
|
347
|
+
if (maxWords !== null && wordCount > maxWords) {
|
|
348
|
+
passed = false;
|
|
349
|
+
}
|
|
350
|
+
if (minChars !== null && charCount < minChars) {
|
|
351
|
+
passed = false;
|
|
352
|
+
}
|
|
353
|
+
if (maxChars !== null && charCount > maxChars) {
|
|
354
|
+
passed = false;
|
|
355
|
+
}
|
|
356
|
+
return { passed, score: passed ? 1.0 : 0.0 };
|
|
357
|
+
}
|
|
358
|
+
case "custom": {
|
|
359
|
+
// Execute custom evaluator if provided
|
|
360
|
+
if (rule.params?.evaluate &&
|
|
361
|
+
typeof rule.params.evaluate === "function") {
|
|
362
|
+
try {
|
|
363
|
+
const customResult = rule.params.evaluate(input);
|
|
364
|
+
if (typeof customResult?.passed === "boolean" &&
|
|
365
|
+
typeof customResult?.score === "number") {
|
|
366
|
+
return customResult;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
return { passed: false, score: 0.0 };
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// No evaluator provided - pass by default with warning
|
|
374
|
+
return { passed: true, score: 1.0 };
|
|
375
|
+
}
|
|
376
|
+
default:
|
|
377
|
+
return { passed: true, score: 1.0 };
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Quick builder factory functions
|
|
383
|
+
*/
|
|
384
|
+
export const Scorers = {
|
|
385
|
+
/**
|
|
386
|
+
* Create a new scorer builder
|
|
387
|
+
*/
|
|
388
|
+
create: (id, name) => ScorerBuilder.create(id, name),
|
|
389
|
+
/**
|
|
390
|
+
* Create a simple pass/fail scorer based on a condition
|
|
391
|
+
*/
|
|
392
|
+
passIf: (id, name, condition) => ScorerBuilder.create(id, name).scoringFunction(async (input) => ({
|
|
393
|
+
score: condition(input) ? 10 : 0,
|
|
394
|
+
reasoning: condition(input) ? "Condition passed" : "Condition failed",
|
|
395
|
+
})),
|
|
396
|
+
/**
|
|
397
|
+
* Create a scorer that checks for required content
|
|
398
|
+
*/
|
|
399
|
+
requiresContent: (id, name, keywords) => {
|
|
400
|
+
const builder = ScorerBuilder.create(id, name).category("quality");
|
|
401
|
+
for (const keyword of keywords) {
|
|
402
|
+
builder.containsKeyword(keyword);
|
|
403
|
+
}
|
|
404
|
+
return builder;
|
|
405
|
+
},
|
|
406
|
+
/**
|
|
407
|
+
* Create a scorer with length constraints
|
|
408
|
+
*/
|
|
409
|
+
withLength: (id, name, options) => ScorerBuilder.create(id, name).category("quality").hasLength(options),
|
|
410
|
+
/**
|
|
411
|
+
* Create a scorer that combines multiple scorers
|
|
412
|
+
*/
|
|
413
|
+
combine: (id, name, scorers) => {
|
|
414
|
+
const builder = ScorerBuilder.create(id, name).category("custom");
|
|
415
|
+
for (const scorer of scorers) {
|
|
416
|
+
builder.addScorer(scorer);
|
|
417
|
+
}
|
|
418
|
+
return builder;
|
|
419
|
+
},
|
|
420
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Scorer registry for managing scorer registration and discovery
|
|
3
|
+
* Follows NeuroLink's factory + registry pattern with dynamic imports
|
|
4
|
+
*/
|
|
5
|
+
import type { Scorer, ScorerCategory, ScorerConfig, ScorerFactory, ScorerMetadata, ScorerRegistryEntry, ScorerType } from "../../types/scorerTypes.js";
|
|
6
|
+
/**
|
|
7
|
+
* Central registry for all scorers
|
|
8
|
+
* Manages registration, discovery, and instantiation
|
|
9
|
+
*/
|
|
10
|
+
export declare class ScorerRegistry {
|
|
11
|
+
private static scorers;
|
|
12
|
+
private static initialized;
|
|
13
|
+
private static initPromise;
|
|
14
|
+
/**
|
|
15
|
+
* Register a scorer with the registry
|
|
16
|
+
*/
|
|
17
|
+
static register(entry: ScorerRegistryEntry): void;
|
|
18
|
+
/**
|
|
19
|
+
* Register a scorer using a simple configuration
|
|
20
|
+
*/
|
|
21
|
+
static registerScorer(metadata: ScorerMetadata, factory: ScorerFactory, aliases?: string[]): void;
|
|
22
|
+
/**
|
|
23
|
+
* Register built-in scorers using dynamic imports
|
|
24
|
+
*/
|
|
25
|
+
static registerBuiltInScorers(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Get a scorer instance by ID
|
|
28
|
+
*/
|
|
29
|
+
static getScorer(scorerId: string, config?: ScorerConfig): Promise<Scorer | undefined>;
|
|
30
|
+
/**
|
|
31
|
+
* Get scorers by category
|
|
32
|
+
*/
|
|
33
|
+
static getScorersByCategory(category: ScorerCategory): ScorerRegistryEntry[];
|
|
34
|
+
/**
|
|
35
|
+
* Get scorers by type
|
|
36
|
+
*/
|
|
37
|
+
static getScorersByType(type: ScorerType): ScorerRegistryEntry[];
|
|
38
|
+
/**
|
|
39
|
+
* List all registered scorer metadata
|
|
40
|
+
*/
|
|
41
|
+
static list(): ScorerMetadata[];
|
|
42
|
+
/**
|
|
43
|
+
* Check if a scorer is registered
|
|
44
|
+
*/
|
|
45
|
+
static has(scorerId: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Unregister a scorer
|
|
48
|
+
*/
|
|
49
|
+
static unregister(scorerId: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Clear all registered scorers
|
|
52
|
+
*/
|
|
53
|
+
static clear(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Ensure built-in scorers are initialized
|
|
56
|
+
*/
|
|
57
|
+
private static ensureInitialized;
|
|
58
|
+
/**
|
|
59
|
+
* Get the number of registered scorers (excluding aliases)
|
|
60
|
+
*/
|
|
61
|
+
static get size(): number;
|
|
62
|
+
}
|