@juspay/neurolink 9.36.1 → 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.
Files changed (202) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/auth/errors.d.ts +1 -1
  3. package/dist/auth/middleware/AuthMiddleware.d.ts +1 -1
  4. package/dist/auth/providers/BaseAuthProvider.d.ts +1 -1
  5. package/dist/browser/neurolink.min.js +921 -423
  6. package/dist/cli/commands/evaluate.d.ts +48 -0
  7. package/dist/cli/commands/evaluate.js +955 -0
  8. package/dist/cli/parser.js +4 -1
  9. package/dist/evaluation/BatchEvaluator.d.ts +163 -0
  10. package/dist/evaluation/BatchEvaluator.js +267 -0
  11. package/dist/evaluation/EvaluationAggregator.d.ts +272 -0
  12. package/dist/evaluation/EvaluationAggregator.js +377 -0
  13. package/dist/evaluation/EvaluatorFactory.d.ts +113 -0
  14. package/dist/evaluation/EvaluatorFactory.js +280 -0
  15. package/dist/evaluation/EvaluatorRegistry.d.ts +160 -0
  16. package/dist/evaluation/EvaluatorRegistry.js +184 -0
  17. package/dist/evaluation/errors/EvaluationError.d.ts +189 -0
  18. package/dist/evaluation/errors/EvaluationError.js +206 -0
  19. package/dist/evaluation/errors/index.d.ts +4 -0
  20. package/dist/evaluation/errors/index.js +4 -0
  21. package/dist/evaluation/hooks/index.d.ts +6 -0
  22. package/dist/evaluation/hooks/index.js +6 -0
  23. package/dist/evaluation/hooks/langfuseAdapter.d.ts +99 -0
  24. package/dist/evaluation/hooks/langfuseAdapter.js +172 -0
  25. package/dist/evaluation/hooks/observabilityHooks.d.ts +129 -0
  26. package/dist/evaluation/hooks/observabilityHooks.js +181 -0
  27. package/dist/evaluation/index.d.ts +11 -2
  28. package/dist/evaluation/index.js +15 -0
  29. package/dist/evaluation/pipeline/evaluationPipeline.d.ts +114 -0
  30. package/dist/evaluation/pipeline/evaluationPipeline.js +381 -0
  31. package/dist/evaluation/pipeline/index.d.ts +8 -0
  32. package/dist/evaluation/pipeline/index.js +8 -0
  33. package/dist/evaluation/pipeline/pipelineBuilder.d.ts +126 -0
  34. package/dist/evaluation/pipeline/pipelineBuilder.js +260 -0
  35. package/dist/evaluation/pipeline/presets.d.ts +66 -0
  36. package/dist/evaluation/pipeline/presets.js +224 -0
  37. package/dist/evaluation/pipeline/strategies/batchStrategy.d.ts +99 -0
  38. package/dist/evaluation/pipeline/strategies/batchStrategy.js +238 -0
  39. package/dist/evaluation/pipeline/strategies/index.d.ts +6 -0
  40. package/dist/evaluation/pipeline/strategies/index.js +6 -0
  41. package/dist/evaluation/pipeline/strategies/samplingStrategy.d.ts +76 -0
  42. package/dist/evaluation/pipeline/strategies/samplingStrategy.js +238 -0
  43. package/dist/evaluation/reporting/index.d.ts +6 -0
  44. package/dist/evaluation/reporting/index.js +6 -0
  45. package/dist/evaluation/reporting/metricsCollector.d.ts +147 -0
  46. package/dist/evaluation/reporting/metricsCollector.js +285 -0
  47. package/dist/evaluation/reporting/reportGenerator.d.ts +90 -0
  48. package/dist/evaluation/reporting/reportGenerator.js +374 -0
  49. package/dist/evaluation/scorers/baseScorer.d.ts +83 -0
  50. package/dist/evaluation/scorers/baseScorer.js +232 -0
  51. package/dist/evaluation/scorers/customScorerUtils.d.ts +95 -0
  52. package/dist/evaluation/scorers/customScorerUtils.js +381 -0
  53. package/dist/evaluation/scorers/index.d.ts +10 -0
  54. package/dist/evaluation/scorers/index.js +16 -0
  55. package/dist/evaluation/scorers/llm/answerRelevancyScorer.d.ts +12 -0
  56. package/dist/evaluation/scorers/llm/answerRelevancyScorer.js +99 -0
  57. package/dist/evaluation/scorers/llm/baseLLMScorer.d.ts +71 -0
  58. package/dist/evaluation/scorers/llm/baseLLMScorer.js +281 -0
  59. package/dist/evaluation/scorers/llm/biasDetectionScorer.d.ts +12 -0
  60. package/dist/evaluation/scorers/llm/biasDetectionScorer.js +127 -0
  61. package/dist/evaluation/scorers/llm/contextPrecisionScorer.d.ts +12 -0
  62. package/dist/evaluation/scorers/llm/contextPrecisionScorer.js +92 -0
  63. package/dist/evaluation/scorers/llm/contextRelevancyScorer.d.ts +12 -0
  64. package/dist/evaluation/scorers/llm/contextRelevancyScorer.js +107 -0
  65. package/dist/evaluation/scorers/llm/faithfulnessScorer.d.ts +12 -0
  66. package/dist/evaluation/scorers/llm/faithfulnessScorer.js +121 -0
  67. package/dist/evaluation/scorers/llm/hallucinationScorer.d.ts +12 -0
  68. package/dist/evaluation/scorers/llm/hallucinationScorer.js +140 -0
  69. package/dist/evaluation/scorers/llm/index.d.ts +15 -0
  70. package/dist/evaluation/scorers/llm/index.js +16 -0
  71. package/dist/evaluation/scorers/llm/promptAlignmentScorer.d.ts +12 -0
  72. package/dist/evaluation/scorers/llm/promptAlignmentScorer.js +106 -0
  73. package/dist/evaluation/scorers/llm/summarizationScorer.d.ts +12 -0
  74. package/dist/evaluation/scorers/llm/summarizationScorer.js +114 -0
  75. package/dist/evaluation/scorers/llm/toneConsistencyScorer.d.ts +12 -0
  76. package/dist/evaluation/scorers/llm/toneConsistencyScorer.js +106 -0
  77. package/dist/evaluation/scorers/llm/toxicityScorer.d.ts +12 -0
  78. package/dist/evaluation/scorers/llm/toxicityScorer.js +121 -0
  79. package/dist/evaluation/scorers/rule/baseRuleScorer.d.ts +77 -0
  80. package/dist/evaluation/scorers/rule/baseRuleScorer.js +233 -0
  81. package/dist/evaluation/scorers/rule/contentSimilarityScorer.d.ts +108 -0
  82. package/dist/evaluation/scorers/rule/contentSimilarityScorer.js +350 -0
  83. package/dist/evaluation/scorers/rule/formatScorer.d.ts +147 -0
  84. package/dist/evaluation/scorers/rule/formatScorer.js +470 -0
  85. package/dist/evaluation/scorers/rule/index.d.ts +9 -0
  86. package/dist/evaluation/scorers/rule/index.js +10 -0
  87. package/dist/evaluation/scorers/rule/keywordCoverageScorer.d.ts +83 -0
  88. package/dist/evaluation/scorers/rule/keywordCoverageScorer.js +347 -0
  89. package/dist/evaluation/scorers/rule/lengthScorer.d.ts +105 -0
  90. package/dist/evaluation/scorers/rule/lengthScorer.js +351 -0
  91. package/dist/evaluation/scorers/scorerBuilder.d.ts +161 -0
  92. package/dist/evaluation/scorers/scorerBuilder.js +420 -0
  93. package/dist/evaluation/scorers/scorerRegistry.d.ts +62 -0
  94. package/dist/evaluation/scorers/scorerRegistry.js +467 -0
  95. package/dist/index.d.ts +37 -25
  96. package/dist/index.js +65 -26
  97. package/dist/lib/auth/providers/BaseAuthProvider.d.ts +1 -1
  98. package/dist/lib/evaluation/BatchEvaluator.d.ts +163 -0
  99. package/dist/lib/evaluation/BatchEvaluator.js +268 -0
  100. package/dist/lib/evaluation/EvaluationAggregator.d.ts +272 -0
  101. package/dist/lib/evaluation/EvaluationAggregator.js +378 -0
  102. package/dist/lib/evaluation/EvaluatorFactory.d.ts +113 -0
  103. package/dist/lib/evaluation/EvaluatorFactory.js +281 -0
  104. package/dist/lib/evaluation/EvaluatorRegistry.d.ts +160 -0
  105. package/dist/lib/evaluation/EvaluatorRegistry.js +185 -0
  106. package/dist/lib/evaluation/errors/EvaluationError.d.ts +189 -0
  107. package/dist/lib/evaluation/errors/EvaluationError.js +207 -0
  108. package/dist/lib/evaluation/errors/index.d.ts +4 -0
  109. package/dist/lib/evaluation/errors/index.js +5 -0
  110. package/dist/lib/evaluation/hooks/index.d.ts +6 -0
  111. package/dist/lib/evaluation/hooks/index.js +7 -0
  112. package/dist/lib/evaluation/hooks/langfuseAdapter.d.ts +99 -0
  113. package/dist/lib/evaluation/hooks/langfuseAdapter.js +173 -0
  114. package/dist/lib/evaluation/hooks/observabilityHooks.d.ts +129 -0
  115. package/dist/lib/evaluation/hooks/observabilityHooks.js +182 -0
  116. package/dist/lib/evaluation/index.d.ts +11 -2
  117. package/dist/lib/evaluation/index.js +15 -0
  118. package/dist/lib/evaluation/pipeline/evaluationPipeline.d.ts +114 -0
  119. package/dist/lib/evaluation/pipeline/evaluationPipeline.js +382 -0
  120. package/dist/lib/evaluation/pipeline/index.d.ts +8 -0
  121. package/dist/lib/evaluation/pipeline/index.js +9 -0
  122. package/dist/lib/evaluation/pipeline/pipelineBuilder.d.ts +126 -0
  123. package/dist/lib/evaluation/pipeline/pipelineBuilder.js +261 -0
  124. package/dist/lib/evaluation/pipeline/presets.d.ts +66 -0
  125. package/dist/lib/evaluation/pipeline/presets.js +225 -0
  126. package/dist/lib/evaluation/pipeline/strategies/batchStrategy.d.ts +99 -0
  127. package/dist/lib/evaluation/pipeline/strategies/batchStrategy.js +239 -0
  128. package/dist/lib/evaluation/pipeline/strategies/index.d.ts +6 -0
  129. package/dist/lib/evaluation/pipeline/strategies/index.js +7 -0
  130. package/dist/lib/evaluation/pipeline/strategies/samplingStrategy.d.ts +76 -0
  131. package/dist/lib/evaluation/pipeline/strategies/samplingStrategy.js +239 -0
  132. package/dist/lib/evaluation/reporting/index.d.ts +6 -0
  133. package/dist/lib/evaluation/reporting/index.js +7 -0
  134. package/dist/lib/evaluation/reporting/metricsCollector.d.ts +147 -0
  135. package/dist/lib/evaluation/reporting/metricsCollector.js +286 -0
  136. package/dist/lib/evaluation/reporting/reportGenerator.d.ts +90 -0
  137. package/dist/lib/evaluation/reporting/reportGenerator.js +375 -0
  138. package/dist/lib/evaluation/scorers/baseScorer.d.ts +83 -0
  139. package/dist/lib/evaluation/scorers/baseScorer.js +233 -0
  140. package/dist/lib/evaluation/scorers/customScorerUtils.d.ts +95 -0
  141. package/dist/lib/evaluation/scorers/customScorerUtils.js +382 -0
  142. package/dist/lib/evaluation/scorers/index.d.ts +10 -0
  143. package/dist/lib/evaluation/scorers/index.js +17 -0
  144. package/dist/lib/evaluation/scorers/llm/answerRelevancyScorer.d.ts +12 -0
  145. package/dist/lib/evaluation/scorers/llm/answerRelevancyScorer.js +100 -0
  146. package/dist/lib/evaluation/scorers/llm/baseLLMScorer.d.ts +71 -0
  147. package/dist/lib/evaluation/scorers/llm/baseLLMScorer.js +282 -0
  148. package/dist/lib/evaluation/scorers/llm/biasDetectionScorer.d.ts +12 -0
  149. package/dist/lib/evaluation/scorers/llm/biasDetectionScorer.js +128 -0
  150. package/dist/lib/evaluation/scorers/llm/contextPrecisionScorer.d.ts +12 -0
  151. package/dist/lib/evaluation/scorers/llm/contextPrecisionScorer.js +93 -0
  152. package/dist/lib/evaluation/scorers/llm/contextRelevancyScorer.d.ts +12 -0
  153. package/dist/lib/evaluation/scorers/llm/contextRelevancyScorer.js +108 -0
  154. package/dist/lib/evaluation/scorers/llm/faithfulnessScorer.d.ts +12 -0
  155. package/dist/lib/evaluation/scorers/llm/faithfulnessScorer.js +122 -0
  156. package/dist/lib/evaluation/scorers/llm/hallucinationScorer.d.ts +12 -0
  157. package/dist/lib/evaluation/scorers/llm/hallucinationScorer.js +141 -0
  158. package/dist/lib/evaluation/scorers/llm/index.d.ts +15 -0
  159. package/dist/lib/evaluation/scorers/llm/index.js +17 -0
  160. package/dist/lib/evaluation/scorers/llm/promptAlignmentScorer.d.ts +12 -0
  161. package/dist/lib/evaluation/scorers/llm/promptAlignmentScorer.js +107 -0
  162. package/dist/lib/evaluation/scorers/llm/summarizationScorer.d.ts +12 -0
  163. package/dist/lib/evaluation/scorers/llm/summarizationScorer.js +115 -0
  164. package/dist/lib/evaluation/scorers/llm/toneConsistencyScorer.d.ts +12 -0
  165. package/dist/lib/evaluation/scorers/llm/toneConsistencyScorer.js +107 -0
  166. package/dist/lib/evaluation/scorers/llm/toxicityScorer.d.ts +12 -0
  167. package/dist/lib/evaluation/scorers/llm/toxicityScorer.js +122 -0
  168. package/dist/lib/evaluation/scorers/rule/baseRuleScorer.d.ts +77 -0
  169. package/dist/lib/evaluation/scorers/rule/baseRuleScorer.js +234 -0
  170. package/dist/lib/evaluation/scorers/rule/contentSimilarityScorer.d.ts +108 -0
  171. package/dist/lib/evaluation/scorers/rule/contentSimilarityScorer.js +351 -0
  172. package/dist/lib/evaluation/scorers/rule/formatScorer.d.ts +147 -0
  173. package/dist/lib/evaluation/scorers/rule/formatScorer.js +471 -0
  174. package/dist/lib/evaluation/scorers/rule/index.d.ts +9 -0
  175. package/dist/lib/evaluation/scorers/rule/index.js +11 -0
  176. package/dist/lib/evaluation/scorers/rule/keywordCoverageScorer.d.ts +83 -0
  177. package/dist/lib/evaluation/scorers/rule/keywordCoverageScorer.js +348 -0
  178. package/dist/lib/evaluation/scorers/rule/lengthScorer.d.ts +105 -0
  179. package/dist/lib/evaluation/scorers/rule/lengthScorer.js +352 -0
  180. package/dist/lib/evaluation/scorers/scorerBuilder.d.ts +161 -0
  181. package/dist/lib/evaluation/scorers/scorerBuilder.js +421 -0
  182. package/dist/lib/evaluation/scorers/scorerRegistry.d.ts +62 -0
  183. package/dist/lib/evaluation/scorers/scorerRegistry.js +468 -0
  184. package/dist/lib/index.d.ts +37 -25
  185. package/dist/lib/index.js +65 -26
  186. package/dist/lib/neurolink.d.ts +204 -0
  187. package/dist/lib/neurolink.js +296 -0
  188. package/dist/lib/types/index.d.ts +3 -1
  189. package/dist/lib/types/index.js +3 -2
  190. package/dist/lib/types/scorerTypes.d.ts +423 -0
  191. package/dist/lib/types/scorerTypes.js +6 -0
  192. package/dist/lib/utils/errorHandling.d.ts +20 -0
  193. package/dist/lib/utils/errorHandling.js +60 -0
  194. package/dist/neurolink.d.ts +204 -0
  195. package/dist/neurolink.js +296 -0
  196. package/dist/types/index.d.ts +3 -1
  197. package/dist/types/index.js +3 -2
  198. package/dist/types/scorerTypes.d.ts +423 -0
  199. package/dist/types/scorerTypes.js +5 -0
  200. package/dist/utils/errorHandling.d.ts +20 -0
  201. package/dist/utils/errorHandling.js +60 -0
  202. 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
+ };