@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,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Length Scorer
|
|
3
|
+
* Evaluates response length against configured constraints
|
|
4
|
+
*/
|
|
5
|
+
import { BaseRuleScorer, DEFAULT_RULE_SCORER_CONFIG, } from "./baseRuleScorer.js";
|
|
6
|
+
/**
|
|
7
|
+
* Scorer metadata for length
|
|
8
|
+
*/
|
|
9
|
+
const LENGTH_METADATA = {
|
|
10
|
+
id: "length",
|
|
11
|
+
name: "Length Validator",
|
|
12
|
+
description: "Evaluates response length against configured constraints (words, characters, sentences)",
|
|
13
|
+
type: "rule",
|
|
14
|
+
category: "quality",
|
|
15
|
+
version: "1.0.0",
|
|
16
|
+
defaultConfig: {
|
|
17
|
+
...DEFAULT_RULE_SCORER_CONFIG,
|
|
18
|
+
threshold: 0.8,
|
|
19
|
+
},
|
|
20
|
+
requiredInputs: ["response"],
|
|
21
|
+
optionalInputs: ["query", "context"],
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* LengthScorer evaluates response length against configurable constraints
|
|
25
|
+
*/
|
|
26
|
+
export class LengthScorer extends BaseRuleScorer {
|
|
27
|
+
_lengthConfig;
|
|
28
|
+
constructor(config) {
|
|
29
|
+
super(LENGTH_METADATA, config);
|
|
30
|
+
this._lengthConfig = {
|
|
31
|
+
unit: "words",
|
|
32
|
+
constraintType: "range",
|
|
33
|
+
minLength: 10,
|
|
34
|
+
maxLength: 500,
|
|
35
|
+
tolerance: 0.1, // 10% tolerance for exact match
|
|
36
|
+
scoringMode: "proportional",
|
|
37
|
+
...config,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get length-specific configuration
|
|
42
|
+
*/
|
|
43
|
+
get lengthConfig() {
|
|
44
|
+
return this._lengthConfig;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get rules for this scorer
|
|
48
|
+
*/
|
|
49
|
+
getRules() {
|
|
50
|
+
const rules = [];
|
|
51
|
+
const constraintType = this._lengthConfig.constraintType ?? "range";
|
|
52
|
+
switch (constraintType) {
|
|
53
|
+
case "minimum":
|
|
54
|
+
rules.push({
|
|
55
|
+
id: "length-minimum",
|
|
56
|
+
description: `Minimum ${this._lengthConfig.unit} check`,
|
|
57
|
+
type: "length",
|
|
58
|
+
params: {
|
|
59
|
+
check: "minimum",
|
|
60
|
+
value: this._lengthConfig.minLength ?? 10,
|
|
61
|
+
unit: this._lengthConfig.unit ?? "words",
|
|
62
|
+
},
|
|
63
|
+
weight: 1.0,
|
|
64
|
+
});
|
|
65
|
+
break;
|
|
66
|
+
case "maximum":
|
|
67
|
+
rules.push({
|
|
68
|
+
id: "length-maximum",
|
|
69
|
+
description: `Maximum ${this._lengthConfig.unit} check`,
|
|
70
|
+
type: "length",
|
|
71
|
+
params: {
|
|
72
|
+
check: "maximum",
|
|
73
|
+
value: this._lengthConfig.maxLength ?? 500,
|
|
74
|
+
unit: this._lengthConfig.unit ?? "words",
|
|
75
|
+
},
|
|
76
|
+
weight: 1.0,
|
|
77
|
+
});
|
|
78
|
+
break;
|
|
79
|
+
case "exact":
|
|
80
|
+
rules.push({
|
|
81
|
+
id: "length-exact",
|
|
82
|
+
description: `Exact ${this._lengthConfig.unit} check`,
|
|
83
|
+
type: "length",
|
|
84
|
+
params: {
|
|
85
|
+
check: "exact",
|
|
86
|
+
value: this._lengthConfig.exactLength ?? 100,
|
|
87
|
+
tolerance: this._lengthConfig.tolerance ?? 0.1,
|
|
88
|
+
unit: this._lengthConfig.unit ?? "words",
|
|
89
|
+
},
|
|
90
|
+
weight: 1.0,
|
|
91
|
+
});
|
|
92
|
+
break;
|
|
93
|
+
case "ratio":
|
|
94
|
+
rules.push({
|
|
95
|
+
id: "length-ratio",
|
|
96
|
+
description: `Length ratio check against ${this._lengthConfig.ratioReference}`,
|
|
97
|
+
type: "length",
|
|
98
|
+
params: {
|
|
99
|
+
check: "ratio",
|
|
100
|
+
target: this._lengthConfig.ratioTarget ?? 1.0,
|
|
101
|
+
reference: this._lengthConfig.ratioReference ?? "query",
|
|
102
|
+
unit: this._lengthConfig.unit ?? "words",
|
|
103
|
+
},
|
|
104
|
+
weight: 1.0,
|
|
105
|
+
});
|
|
106
|
+
break;
|
|
107
|
+
case "range":
|
|
108
|
+
default:
|
|
109
|
+
rules.push({
|
|
110
|
+
id: "length-minimum",
|
|
111
|
+
description: `Minimum ${this._lengthConfig.unit} check`,
|
|
112
|
+
type: "length",
|
|
113
|
+
params: {
|
|
114
|
+
check: "minimum",
|
|
115
|
+
value: this._lengthConfig.minLength ?? 10,
|
|
116
|
+
unit: this._lengthConfig.unit ?? "words",
|
|
117
|
+
},
|
|
118
|
+
weight: 0.5,
|
|
119
|
+
});
|
|
120
|
+
rules.push({
|
|
121
|
+
id: "length-maximum",
|
|
122
|
+
description: `Maximum ${this._lengthConfig.unit} check`,
|
|
123
|
+
type: "length",
|
|
124
|
+
params: {
|
|
125
|
+
check: "maximum",
|
|
126
|
+
value: this._lengthConfig.maxLength ?? 500,
|
|
127
|
+
unit: this._lengthConfig.unit ?? "words",
|
|
128
|
+
},
|
|
129
|
+
weight: 0.5,
|
|
130
|
+
});
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
return rules;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Measure text length in various units
|
|
137
|
+
*/
|
|
138
|
+
_measureLength(text) {
|
|
139
|
+
return {
|
|
140
|
+
words: this.getWordCount(text),
|
|
141
|
+
characters: this.getCharacterCount(text),
|
|
142
|
+
sentences: this._countSentences(text),
|
|
143
|
+
paragraphs: this._countParagraphs(text),
|
|
144
|
+
estimatedTokens: this._estimateTokens(text),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get length in the configured unit
|
|
149
|
+
*/
|
|
150
|
+
_getLengthInUnit(text, unit) {
|
|
151
|
+
const measurement = this._measureLength(text);
|
|
152
|
+
switch (unit) {
|
|
153
|
+
case "words":
|
|
154
|
+
return measurement.words;
|
|
155
|
+
case "characters":
|
|
156
|
+
return measurement.characters;
|
|
157
|
+
case "sentences":
|
|
158
|
+
return measurement.sentences;
|
|
159
|
+
case "paragraphs":
|
|
160
|
+
return measurement.paragraphs;
|
|
161
|
+
case "tokens":
|
|
162
|
+
return measurement.estimatedTokens;
|
|
163
|
+
default:
|
|
164
|
+
return measurement.words;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Count sentences in text
|
|
169
|
+
*/
|
|
170
|
+
_countSentences(text) {
|
|
171
|
+
// Match sentence-ending punctuation followed by space or end of string
|
|
172
|
+
const sentences = text
|
|
173
|
+
.split(/(?<=[.!?])\s+/)
|
|
174
|
+
.filter((s) => s.trim().length > 0);
|
|
175
|
+
return sentences.length;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Count paragraphs in text
|
|
179
|
+
*/
|
|
180
|
+
_countParagraphs(text) {
|
|
181
|
+
// Split by double newlines or paragraph markers
|
|
182
|
+
const paragraphs = text.split(/\n\s*\n/).filter((p) => p.trim().length > 0);
|
|
183
|
+
return Math.max(paragraphs.length, 1); // At least 1 paragraph if there's text
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Estimate token count (rough approximation)
|
|
187
|
+
* GPT-style: ~4 characters per token on average
|
|
188
|
+
*/
|
|
189
|
+
_estimateTokens(text) {
|
|
190
|
+
return Math.ceil(text.length / 4);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Evaluate a single length rule
|
|
194
|
+
*/
|
|
195
|
+
evaluateRule(rule, input) {
|
|
196
|
+
const check = rule.params.check;
|
|
197
|
+
const unit = rule.params.unit ?? "words";
|
|
198
|
+
const responseLength = this._getLengthInUnit(input.response, unit);
|
|
199
|
+
switch (check) {
|
|
200
|
+
case "minimum": {
|
|
201
|
+
const minValue = rule.params.value;
|
|
202
|
+
if (responseLength >= minValue) {
|
|
203
|
+
return { passed: true, score: 1.0 };
|
|
204
|
+
}
|
|
205
|
+
// Proportional scoring
|
|
206
|
+
if (this._lengthConfig.scoringMode === "proportional" && minValue > 0) {
|
|
207
|
+
return {
|
|
208
|
+
passed: false,
|
|
209
|
+
score: Math.min(responseLength / minValue, 1.0),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return { passed: false, score: 0.0 };
|
|
213
|
+
}
|
|
214
|
+
case "maximum": {
|
|
215
|
+
const maxValue = rule.params.value;
|
|
216
|
+
if (responseLength <= maxValue) {
|
|
217
|
+
return { passed: true, score: 1.0 };
|
|
218
|
+
}
|
|
219
|
+
// Proportional scoring (inverse)
|
|
220
|
+
if (this._lengthConfig.scoringMode === "proportional" &&
|
|
221
|
+
responseLength > 0) {
|
|
222
|
+
return {
|
|
223
|
+
passed: false,
|
|
224
|
+
score: Math.max(0, maxValue / responseLength),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
return { passed: false, score: 0.0 };
|
|
228
|
+
}
|
|
229
|
+
case "exact": {
|
|
230
|
+
const exactValue = rule.params.value;
|
|
231
|
+
const tolerance = rule.params.tolerance ?? 0.1;
|
|
232
|
+
const lowerBound = exactValue * (1 - tolerance);
|
|
233
|
+
const upperBound = exactValue * (1 + tolerance);
|
|
234
|
+
if (responseLength >= lowerBound && responseLength <= upperBound) {
|
|
235
|
+
return { passed: true, score: 1.0 };
|
|
236
|
+
}
|
|
237
|
+
// Proportional scoring based on distance from target
|
|
238
|
+
if (this._lengthConfig.scoringMode === "proportional" &&
|
|
239
|
+
exactValue > 0) {
|
|
240
|
+
const distance = Math.abs(responseLength - exactValue) / exactValue;
|
|
241
|
+
return { passed: false, score: Math.max(0, 1 - distance) };
|
|
242
|
+
}
|
|
243
|
+
return { passed: false, score: 0.0 };
|
|
244
|
+
}
|
|
245
|
+
case "ratio": {
|
|
246
|
+
const target = rule.params.target;
|
|
247
|
+
const reference = rule.params.reference;
|
|
248
|
+
let referenceText = "";
|
|
249
|
+
if (reference === "query") {
|
|
250
|
+
referenceText = input.query;
|
|
251
|
+
}
|
|
252
|
+
else if (reference === "context" && input.context) {
|
|
253
|
+
referenceText = input.context.join(" ");
|
|
254
|
+
}
|
|
255
|
+
if (!referenceText) {
|
|
256
|
+
return { passed: true, score: 1.0 }; // No reference, pass by default
|
|
257
|
+
}
|
|
258
|
+
const referenceLength = this._getLengthInUnit(referenceText, unit);
|
|
259
|
+
if (referenceLength === 0) {
|
|
260
|
+
return { passed: true, score: 1.0 };
|
|
261
|
+
}
|
|
262
|
+
const actualRatio = responseLength / referenceLength;
|
|
263
|
+
const tolerance = this._lengthConfig.tolerance ?? 0.2;
|
|
264
|
+
if (actualRatio >= target * (1 - tolerance) &&
|
|
265
|
+
actualRatio <= target * (1 + tolerance)) {
|
|
266
|
+
return { passed: true, score: 1.0 };
|
|
267
|
+
}
|
|
268
|
+
// Proportional scoring
|
|
269
|
+
if (this._lengthConfig.scoringMode === "proportional" && target > 0) {
|
|
270
|
+
const ratioDistance = Math.abs(actualRatio - target) / target;
|
|
271
|
+
return { passed: false, score: Math.max(0, 1 - ratioDistance) };
|
|
272
|
+
}
|
|
273
|
+
return { passed: false, score: 0.0 };
|
|
274
|
+
}
|
|
275
|
+
default:
|
|
276
|
+
return { passed: true, score: 1.0 };
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Override score to add detailed length metrics
|
|
281
|
+
*/
|
|
282
|
+
async score(input) {
|
|
283
|
+
const result = await super.score(input);
|
|
284
|
+
// Add detailed measurements
|
|
285
|
+
const measurement = this._measureLength(input.response);
|
|
286
|
+
const unit = this._lengthConfig.unit ?? "words";
|
|
287
|
+
return {
|
|
288
|
+
...result,
|
|
289
|
+
metadata: {
|
|
290
|
+
...result.metadata,
|
|
291
|
+
lengthMeasurement: measurement,
|
|
292
|
+
configuredUnit: unit,
|
|
293
|
+
configuredConstraint: this._lengthConfig.constraintType ?? "range",
|
|
294
|
+
actualLength: this._getLengthInUnit(input.response, unit),
|
|
295
|
+
minLength: this._lengthConfig.minLength ?? null,
|
|
296
|
+
maxLength: this._lengthConfig.maxLength ?? null,
|
|
297
|
+
exactLength: this._lengthConfig.exactLength ?? null,
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Factory function for creating LengthScorer instances
|
|
304
|
+
*/
|
|
305
|
+
export async function createLengthScorer(config) {
|
|
306
|
+
return new LengthScorer(config);
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Pre-configured length scorer presets
|
|
310
|
+
*/
|
|
311
|
+
export const LengthScorerPresets = {
|
|
312
|
+
/** Short response (50-150 words) */
|
|
313
|
+
short: () => new LengthScorer({
|
|
314
|
+
unit: "words",
|
|
315
|
+
constraintType: "range",
|
|
316
|
+
minLength: 50,
|
|
317
|
+
maxLength: 150,
|
|
318
|
+
}),
|
|
319
|
+
/** Medium response (100-300 words) */
|
|
320
|
+
medium: () => new LengthScorer({
|
|
321
|
+
unit: "words",
|
|
322
|
+
constraintType: "range",
|
|
323
|
+
minLength: 100,
|
|
324
|
+
maxLength: 300,
|
|
325
|
+
}),
|
|
326
|
+
/** Long response (200-500 words) */
|
|
327
|
+
long: () => new LengthScorer({
|
|
328
|
+
unit: "words",
|
|
329
|
+
constraintType: "range",
|
|
330
|
+
minLength: 200,
|
|
331
|
+
maxLength: 500,
|
|
332
|
+
}),
|
|
333
|
+
/** Concise response (max 100 words) */
|
|
334
|
+
concise: () => new LengthScorer({
|
|
335
|
+
unit: "words",
|
|
336
|
+
constraintType: "maximum",
|
|
337
|
+
maxLength: 100,
|
|
338
|
+
}),
|
|
339
|
+
/** Detailed response (min 300 words) */
|
|
340
|
+
detailed: () => new LengthScorer({
|
|
341
|
+
unit: "words",
|
|
342
|
+
constraintType: "minimum",
|
|
343
|
+
minLength: 300,
|
|
344
|
+
}),
|
|
345
|
+
/** Tweet-length (max 280 characters) */
|
|
346
|
+
tweet: () => new LengthScorer({
|
|
347
|
+
unit: "characters",
|
|
348
|
+
constraintType: "maximum",
|
|
349
|
+
maxLength: 280,
|
|
350
|
+
}),
|
|
351
|
+
};
|
|
352
|
+
//# sourceMappingURL=lengthScorer.js.map
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Scorer Builder
|
|
3
|
+
* Fluent builder API for creating custom scorers
|
|
4
|
+
*/
|
|
5
|
+
import type { ScorerCategory, ScorerInput, ScorerRule, ScorerType } from "../../types/scorerTypes.js";
|
|
6
|
+
import type { BaseScorer } from "./baseScorer.js";
|
|
7
|
+
import { type ScorerFunction } from "./customScorerUtils.js";
|
|
8
|
+
/**
|
|
9
|
+
* Fluent builder for creating custom scorers
|
|
10
|
+
*/
|
|
11
|
+
export declare class ScorerBuilder {
|
|
12
|
+
private _id;
|
|
13
|
+
private _name;
|
|
14
|
+
private _description?;
|
|
15
|
+
private _type;
|
|
16
|
+
private _category;
|
|
17
|
+
private _version;
|
|
18
|
+
private _requiredInputs;
|
|
19
|
+
private _optionalInputs;
|
|
20
|
+
private _threshold;
|
|
21
|
+
private _weight;
|
|
22
|
+
private _timeout;
|
|
23
|
+
private _retries;
|
|
24
|
+
private _scorerFn?;
|
|
25
|
+
private _rules;
|
|
26
|
+
private _subScorers;
|
|
27
|
+
private _aggregation;
|
|
28
|
+
private _subScorerWeights;
|
|
29
|
+
constructor(id: string, name: string);
|
|
30
|
+
/**
|
|
31
|
+
* Create a new scorer builder
|
|
32
|
+
*/
|
|
33
|
+
static create(id: string, name: string): ScorerBuilder;
|
|
34
|
+
/**
|
|
35
|
+
* Set scorer description
|
|
36
|
+
*/
|
|
37
|
+
description(desc: string): this;
|
|
38
|
+
/**
|
|
39
|
+
* Set scorer type
|
|
40
|
+
*/
|
|
41
|
+
type(type: ScorerType): this;
|
|
42
|
+
/**
|
|
43
|
+
* Set scorer category
|
|
44
|
+
*/
|
|
45
|
+
category(category: ScorerCategory): this;
|
|
46
|
+
/**
|
|
47
|
+
* Set scorer version
|
|
48
|
+
*/
|
|
49
|
+
version(version: string): this;
|
|
50
|
+
/**
|
|
51
|
+
* Set required inputs
|
|
52
|
+
*/
|
|
53
|
+
requireInputs(...inputs: (keyof ScorerInput)[]): this;
|
|
54
|
+
/**
|
|
55
|
+
* Set optional inputs
|
|
56
|
+
*/
|
|
57
|
+
optionalInputs(...inputs: (keyof ScorerInput)[]): this;
|
|
58
|
+
/**
|
|
59
|
+
* Set pass/fail threshold
|
|
60
|
+
*/
|
|
61
|
+
threshold(threshold: number): this;
|
|
62
|
+
/**
|
|
63
|
+
* Set weight for aggregation
|
|
64
|
+
*/
|
|
65
|
+
weight(weight: number): this;
|
|
66
|
+
/**
|
|
67
|
+
* Set execution timeout
|
|
68
|
+
*/
|
|
69
|
+
timeout(ms: number): this;
|
|
70
|
+
/**
|
|
71
|
+
* Set retry count
|
|
72
|
+
*/
|
|
73
|
+
retries(count: number): this;
|
|
74
|
+
/**
|
|
75
|
+
* Set the scoring function
|
|
76
|
+
*/
|
|
77
|
+
scoringFunction(fn: ScorerFunction): this;
|
|
78
|
+
/**
|
|
79
|
+
* Add a sub-scorer for composition
|
|
80
|
+
*/
|
|
81
|
+
addScorer(scorer: BaseScorer, weight?: number): this;
|
|
82
|
+
/**
|
|
83
|
+
* Set aggregation method for composed scorers
|
|
84
|
+
*/
|
|
85
|
+
aggregateWith(method: "average" | "min" | "max" | "weighted"): this;
|
|
86
|
+
/**
|
|
87
|
+
* Add a regex check rule
|
|
88
|
+
*/
|
|
89
|
+
matchesPattern(pattern: string | RegExp, options?: {
|
|
90
|
+
id?: string;
|
|
91
|
+
weight?: number;
|
|
92
|
+
}): this;
|
|
93
|
+
/**
|
|
94
|
+
* Add a keyword check rule
|
|
95
|
+
*/
|
|
96
|
+
containsKeyword(keyword: string, options?: {
|
|
97
|
+
id?: string;
|
|
98
|
+
weight?: number;
|
|
99
|
+
}): this;
|
|
100
|
+
/**
|
|
101
|
+
* Add a length check rule
|
|
102
|
+
*/
|
|
103
|
+
hasLength(options: {
|
|
104
|
+
minWords?: number;
|
|
105
|
+
maxWords?: number;
|
|
106
|
+
minChars?: number;
|
|
107
|
+
maxChars?: number;
|
|
108
|
+
id?: string;
|
|
109
|
+
weight?: number;
|
|
110
|
+
}): this;
|
|
111
|
+
/**
|
|
112
|
+
* Add a custom rule
|
|
113
|
+
*/
|
|
114
|
+
customRule(rule: ScorerRule): this;
|
|
115
|
+
/**
|
|
116
|
+
* Build the scorer
|
|
117
|
+
*/
|
|
118
|
+
build(): BaseScorer;
|
|
119
|
+
/**
|
|
120
|
+
* Build configuration object
|
|
121
|
+
*/
|
|
122
|
+
private _buildConfig;
|
|
123
|
+
/**
|
|
124
|
+
* Build a rule-based scorer from accumulated rules
|
|
125
|
+
*/
|
|
126
|
+
private _buildRuleScorer;
|
|
127
|
+
/**
|
|
128
|
+
* Evaluate a single rule
|
|
129
|
+
*/
|
|
130
|
+
private _evaluateRule;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Quick builder factory functions
|
|
134
|
+
*/
|
|
135
|
+
export declare const Scorers: {
|
|
136
|
+
/**
|
|
137
|
+
* Create a new scorer builder
|
|
138
|
+
*/
|
|
139
|
+
create: (id: string, name: string) => ScorerBuilder;
|
|
140
|
+
/**
|
|
141
|
+
* Create a simple pass/fail scorer based on a condition
|
|
142
|
+
*/
|
|
143
|
+
passIf: (id: string, name: string, condition: (input: ScorerInput) => boolean) => ScorerBuilder;
|
|
144
|
+
/**
|
|
145
|
+
* Create a scorer that checks for required content
|
|
146
|
+
*/
|
|
147
|
+
requiresContent: (id: string, name: string, keywords: string[]) => ScorerBuilder;
|
|
148
|
+
/**
|
|
149
|
+
* Create a scorer with length constraints
|
|
150
|
+
*/
|
|
151
|
+
withLength: (id: string, name: string, options: {
|
|
152
|
+
minWords?: number;
|
|
153
|
+
maxWords?: number;
|
|
154
|
+
minChars?: number;
|
|
155
|
+
maxChars?: number;
|
|
156
|
+
}) => ScorerBuilder;
|
|
157
|
+
/**
|
|
158
|
+
* Create a scorer that combines multiple scorers
|
|
159
|
+
*/
|
|
160
|
+
combine: (id: string, name: string, scorers: BaseScorer[]) => ScorerBuilder;
|
|
161
|
+
};
|