peerbench 0.0.6 → 0.0.7
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/dist/{abstract-Dec9Sc5O.d.ts → abstract-BdgLjkNC.d.ts} +7 -1
- package/dist/aggregators/index.d.ts +3 -3
- package/dist/benchmarks/index.d.ts +22 -22
- package/dist/benchmarks/index.js +15 -15
- package/dist/{chunk-DNGT4SJC.js → chunk-3JHDJEY3.js} +16 -7
- package/dist/chunk-3JHDJEY3.js.map +1 -0
- package/dist/{chunk-3JF7SHLC.js → chunk-SMLNDQFX.js} +16 -7
- package/dist/chunk-SMLNDQFX.js.map +1 -0
- package/dist/{chunk-Q6GSOHOP.js → chunk-ZXTQJFGL.js} +4 -4
- package/dist/{index-BAioQhp2.d.ts → index-Cn20kPrz.d.ts} +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/{llm-BND163ns.d.ts → llm-8ecJmwKJ.d.ts} +1 -1
- package/dist/{llm-judge-BS_oNYUK.d.ts → llm-judge-BuF80-5-.d.ts} +12 -4
- package/dist/provider-DnEBdl1n.d.ts +16 -0
- package/dist/providers/index.d.ts +18 -6
- package/dist/providers/index.js +1 -1
- package/dist/schemas/index.d.ts +7 -7
- package/dist/schemas/llm/index.d.ts +5 -5
- package/dist/schemas/llm/index.js +2 -2
- package/dist/scorers/index.d.ts +11 -7
- package/dist/scorers/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3JF7SHLC.js.map +0 -1
- package/dist/chunk-DNGT4SJC.js.map +0 -1
- package/dist/provider-BDjGp2y-.d.ts +0 -10
- /package/dist/{chunk-Q6GSOHOP.js.map → chunk-ZXTQJFGL.js.map} +0 -0
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
declare abstract class AbstractScorer {
|
|
2
|
-
|
|
2
|
+
readonly kind: string;
|
|
3
|
+
constructor();
|
|
3
4
|
abstract score(params: any): Promise<BaseScorerResult | null>;
|
|
5
|
+
static withKind<TKind extends string, TThis extends abstract new (...args: any[]) => AbstractScorer>(this: TThis, kind: TKind): (new () => InstanceType<TThis> & {
|
|
6
|
+
readonly kind: TKind;
|
|
7
|
+
}) & {
|
|
8
|
+
readonly kind: TKind;
|
|
9
|
+
};
|
|
4
10
|
}
|
|
5
11
|
type BaseScorerResult = {
|
|
6
12
|
value: number;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BaseScoreV1, BaseTestCaseV1, BaseResponseV1 } from '../schemas/index.js';
|
|
2
|
-
import { a as InferExtension } from '../index-
|
|
2
|
+
import { a as InferExtension } from '../index-Cn20kPrz.js';
|
|
3
3
|
import z__default from 'zod';
|
|
4
|
-
import '../provider-
|
|
5
|
-
import '../abstract-
|
|
4
|
+
import '../provider-DnEBdl1n.js';
|
|
5
|
+
import '../abstract-BdgLjkNC.js';
|
|
6
6
|
|
|
7
7
|
declare abstract class AbstractAggregator {
|
|
8
8
|
abstract push(params: {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { I as IdGenerator } from '../index-
|
|
1
|
+
import { I as IdGenerator } from '../index-Cn20kPrz.js';
|
|
2
2
|
import z__default, { z } from 'zod';
|
|
3
|
-
import { A as AbstractLLMProvider } from '../llm-
|
|
4
|
-
import { a as MCQScorer, L as LLMAsAJudgeScorer } from '../llm-judge-
|
|
3
|
+
import { A as AbstractLLMProvider } from '../llm-8ecJmwKJ.js';
|
|
4
|
+
import { a as MCQScorer, L as LLMAsAJudgeScorer } from '../llm-judge-BuF80-5-.js';
|
|
5
5
|
import { J as JSONFileStorage } from '../json-file-Bgv9TLcX.js';
|
|
6
|
-
import '../provider-
|
|
7
|
-
import '../abstract-
|
|
6
|
+
import '../provider-DnEBdl1n.js';
|
|
7
|
+
import '../abstract-BdgLjkNC.js';
|
|
8
8
|
import 'openai/resources/shared';
|
|
9
9
|
import 'openai/resources/chat/completions';
|
|
10
10
|
import '../rate-limiter-CSmVIRsM.js';
|
|
@@ -54,7 +54,7 @@ declare const MCQTestCaseSchemaV1: z.ZodObject<Omit<{
|
|
|
54
54
|
kind: "llm/mcq.tc";
|
|
55
55
|
schemaVersion: 1;
|
|
56
56
|
metadata?: Record<string, unknown> | undefined;
|
|
57
|
-
}, "
|
|
57
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
58
58
|
id: string;
|
|
59
59
|
question: string;
|
|
60
60
|
options: Record<string, string>;
|
|
@@ -141,7 +141,7 @@ declare const MCQResponseSchemaV1: z.ZodObject<Omit<{
|
|
|
141
141
|
outputTokensUsed?: number | undefined;
|
|
142
142
|
inputCost?: string | undefined;
|
|
143
143
|
outputCost?: string | undefined;
|
|
144
|
-
}, "
|
|
144
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
145
145
|
startedAt: number;
|
|
146
146
|
completedAt: number;
|
|
147
147
|
id: string;
|
|
@@ -248,7 +248,7 @@ declare const MCQScoreSchemaV1: z.ZodObject<Omit<{
|
|
|
248
248
|
scorerAIOutputTokensUsed?: number | undefined;
|
|
249
249
|
scorerAIInputCost?: string | undefined;
|
|
250
250
|
scorerAIOutputCost?: string | undefined;
|
|
251
|
-
}, "
|
|
251
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
252
252
|
id: string;
|
|
253
253
|
value: number;
|
|
254
254
|
responseId: string;
|
|
@@ -335,7 +335,7 @@ declare const MultiTurnTestCaseSchemaV1: z.ZodObject<Omit<{
|
|
|
335
335
|
metadata?: Record<string, unknown> | undefined;
|
|
336
336
|
maxTurns?: number | undefined;
|
|
337
337
|
expectedOutcome?: string | undefined;
|
|
338
|
-
}, "
|
|
338
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
339
339
|
id: string;
|
|
340
340
|
messages: {
|
|
341
341
|
role: string;
|
|
@@ -467,7 +467,7 @@ declare const MultiTurnResponseSchemaV1: z.ZodObject<Omit<{
|
|
|
467
467
|
outputTokensUsed?: number | undefined;
|
|
468
468
|
inputCost?: string | undefined;
|
|
469
469
|
outputCost?: string | undefined;
|
|
470
|
-
}, "
|
|
470
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
471
471
|
startedAt: number;
|
|
472
472
|
completedAt: number;
|
|
473
473
|
id: string;
|
|
@@ -596,7 +596,7 @@ declare const MultiTurnScoreSchemaV1: z.ZodObject<Omit<{
|
|
|
596
596
|
scorerAIOutputTokensUsed?: number | undefined;
|
|
597
597
|
scorerAIInputCost?: string | undefined;
|
|
598
598
|
scorerAIOutputCost?: string | undefined;
|
|
599
|
-
}, "
|
|
599
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
600
600
|
id: string;
|
|
601
601
|
value: number;
|
|
602
602
|
responseId: string;
|
|
@@ -666,7 +666,7 @@ declare const QATestCaseSchemaV1: z.ZodObject<Omit<{
|
|
|
666
666
|
kind: "llm/qa.tc";
|
|
667
667
|
schemaVersion: 1;
|
|
668
668
|
metadata?: Record<string, unknown> | undefined;
|
|
669
|
-
}, "
|
|
669
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
670
670
|
id: string;
|
|
671
671
|
question: string;
|
|
672
672
|
goodAnswers: string[];
|
|
@@ -753,7 +753,7 @@ declare const QAResponseSchemaV1: z.ZodObject<Omit<{
|
|
|
753
753
|
outputTokensUsed?: number | undefined;
|
|
754
754
|
inputCost?: string | undefined;
|
|
755
755
|
outputCost?: string | undefined;
|
|
756
|
-
}, "
|
|
756
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
757
757
|
startedAt: number;
|
|
758
758
|
completedAt: number;
|
|
759
759
|
id: string;
|
|
@@ -856,7 +856,7 @@ declare const QAScoreSchemaV1: z.ZodObject<Omit<{
|
|
|
856
856
|
scorerAIOutputTokensUsed?: number | undefined;
|
|
857
857
|
scorerAIInputCost?: string | undefined;
|
|
858
858
|
scorerAIOutputCost?: string | undefined;
|
|
859
|
-
}, "
|
|
859
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
860
860
|
id: string;
|
|
861
861
|
value: number;
|
|
862
862
|
responseId: string;
|
|
@@ -1046,7 +1046,7 @@ declare const peerbenchRunner: ((params: {
|
|
|
1046
1046
|
kind: `${string}/simple.sys-prompt`;
|
|
1047
1047
|
schemaVersion: 1;
|
|
1048
1048
|
metadata?: Record<string, unknown> | undefined;
|
|
1049
|
-
}, "
|
|
1049
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
1050
1050
|
id: string;
|
|
1051
1051
|
version: number;
|
|
1052
1052
|
content: string;
|
|
@@ -1096,7 +1096,7 @@ declare const peerbenchRunner: ((params: {
|
|
|
1096
1096
|
kind: `${string}/simple.sys-prompt`;
|
|
1097
1097
|
schemaVersion: 1;
|
|
1098
1098
|
metadata?: Record<string, unknown> | undefined;
|
|
1099
|
-
}, "
|
|
1099
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
1100
1100
|
id: string;
|
|
1101
1101
|
version: number;
|
|
1102
1102
|
content: string;
|
|
@@ -1152,7 +1152,7 @@ declare const peerbenchRunner: ((params: {
|
|
|
1152
1152
|
kind: "llm/mcq.tc";
|
|
1153
1153
|
schemaVersion: 1;
|
|
1154
1154
|
metadata?: Record<string, unknown> | undefined;
|
|
1155
|
-
}, "
|
|
1155
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
1156
1156
|
id: string;
|
|
1157
1157
|
question: string;
|
|
1158
1158
|
options: Record<string, string>;
|
|
@@ -1238,7 +1238,7 @@ declare const peerbenchRunner: ((params: {
|
|
|
1238
1238
|
outputTokensUsed?: number | undefined;
|
|
1239
1239
|
inputCost?: string | undefined;
|
|
1240
1240
|
outputCost?: string | undefined;
|
|
1241
|
-
}, "
|
|
1241
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
1242
1242
|
startedAt: number;
|
|
1243
1243
|
completedAt: number;
|
|
1244
1244
|
id: string;
|
|
@@ -1344,7 +1344,7 @@ declare const peerbenchRunner: ((params: {
|
|
|
1344
1344
|
scorerAIOutputTokensUsed?: number | undefined;
|
|
1345
1345
|
scorerAIInputCost?: string | undefined;
|
|
1346
1346
|
scorerAIOutputCost?: string | undefined;
|
|
1347
|
-
}, "
|
|
1347
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
1348
1348
|
id: string;
|
|
1349
1349
|
value: number;
|
|
1350
1350
|
responseId: string;
|
|
@@ -1409,7 +1409,7 @@ declare const peerbenchRunner: ((params: {
|
|
|
1409
1409
|
kind: "llm/qa.tc";
|
|
1410
1410
|
schemaVersion: 1;
|
|
1411
1411
|
metadata?: Record<string, unknown> | undefined;
|
|
1412
|
-
}, "
|
|
1412
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
1413
1413
|
id: string;
|
|
1414
1414
|
question: string;
|
|
1415
1415
|
goodAnswers: string[];
|
|
@@ -1495,7 +1495,7 @@ declare const peerbenchRunner: ((params: {
|
|
|
1495
1495
|
outputTokensUsed?: number | undefined;
|
|
1496
1496
|
inputCost?: string | undefined;
|
|
1497
1497
|
outputCost?: string | undefined;
|
|
1498
|
-
}, "
|
|
1498
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
1499
1499
|
startedAt: number;
|
|
1500
1500
|
completedAt: number;
|
|
1501
1501
|
id: string;
|
|
@@ -1597,7 +1597,7 @@ declare const peerbenchRunner: ((params: {
|
|
|
1597
1597
|
scorerAIOutputTokensUsed?: number | undefined;
|
|
1598
1598
|
scorerAIInputCost?: string | undefined;
|
|
1599
1599
|
scorerAIOutputCost?: string | undefined;
|
|
1600
|
-
}, "
|
|
1600
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
1601
1601
|
id: string;
|
|
1602
1602
|
value: number;
|
|
1603
1603
|
responseId: string;
|
package/dist/benchmarks/index.js
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SimpleSystemPromptSchemaV1
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-ZXTQJFGL.js";
|
|
4
4
|
import {
|
|
5
5
|
defineRunner
|
|
6
6
|
} from "../chunk-RTEAK4II.js";
|
|
7
|
+
import {
|
|
8
|
+
LLMAsAJudgeScorer,
|
|
9
|
+
MCQScorer
|
|
10
|
+
} from "../chunk-3JHDJEY3.js";
|
|
7
11
|
import {
|
|
8
12
|
AbstractLLMProvider
|
|
9
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-SMLNDQFX.js";
|
|
14
|
+
import {
|
|
15
|
+
PEERBENCH_NAMESPACE
|
|
16
|
+
} from "../chunk-UHHHSYVE.js";
|
|
17
|
+
import {
|
|
18
|
+
JSONFileStorage
|
|
19
|
+
} from "../chunk-JFLUJLGT.js";
|
|
20
|
+
import {
|
|
21
|
+
idGeneratorUUIDv7
|
|
22
|
+
} from "../chunk-4UBK6452.js";
|
|
10
23
|
import {
|
|
11
24
|
BaseResponseSchemaV1,
|
|
12
25
|
BaseScoreSchemaV1,
|
|
@@ -19,19 +32,6 @@ import "../chunk-OQE6TQXZ.js";
|
|
|
19
32
|
import {
|
|
20
33
|
ScoringMethod
|
|
21
34
|
} from "../chunk-HMQYGCKI.js";
|
|
22
|
-
import {
|
|
23
|
-
LLMAsAJudgeScorer,
|
|
24
|
-
MCQScorer
|
|
25
|
-
} from "../chunk-DNGT4SJC.js";
|
|
26
|
-
import {
|
|
27
|
-
PEERBENCH_NAMESPACE
|
|
28
|
-
} from "../chunk-UHHHSYVE.js";
|
|
29
|
-
import {
|
|
30
|
-
JSONFileStorage
|
|
31
|
-
} from "../chunk-JFLUJLGT.js";
|
|
32
|
-
import {
|
|
33
|
-
idGeneratorUUIDv7
|
|
34
|
-
} from "../chunk-4UBK6452.js";
|
|
35
35
|
import {
|
|
36
36
|
ExtensionLLMAsAJudgeScoreFieldsV1,
|
|
37
37
|
ExtensionLLMResponseFieldsV1
|
|
@@ -7,11 +7,22 @@ import {
|
|
|
7
7
|
|
|
8
8
|
// src/scorers/abstract.ts
|
|
9
9
|
var AbstractScorer = class {
|
|
10
|
+
kind;
|
|
11
|
+
constructor() {
|
|
12
|
+
this.kind = this.constructor.kind;
|
|
13
|
+
if (!this.kind) throw new Error(`${this.constructor.name} must define "static readonly kind" as a constant property.`);
|
|
14
|
+
}
|
|
15
|
+
static withKind(kind) {
|
|
16
|
+
const base = this;
|
|
17
|
+
const derived = class extends base {
|
|
18
|
+
static kind = kind;
|
|
19
|
+
};
|
|
20
|
+
return derived;
|
|
21
|
+
}
|
|
10
22
|
};
|
|
11
23
|
|
|
12
24
|
// src/scorers/regex.ts
|
|
13
|
-
var RegexScorer = class extends AbstractScorer {
|
|
14
|
-
kind = `${PEERBENCH_NAMESPACE}/regex`;
|
|
25
|
+
var RegexScorer = class extends AbstractScorer.withKind(`${PEERBENCH_NAMESPACE}/regex`) {
|
|
15
26
|
async score(params) {
|
|
16
27
|
const allGroupNames = /* @__PURE__ */ new Set();
|
|
17
28
|
for (const pattern of params.patterns) {
|
|
@@ -119,8 +130,7 @@ var RegexScorer = class extends AbstractScorer {
|
|
|
119
130
|
};
|
|
120
131
|
|
|
121
132
|
// src/scorers/mcq.ts
|
|
122
|
-
var MCQScorer = class extends AbstractScorer {
|
|
123
|
-
kind = `${PEERBENCH_NAMESPACE}/mcq`;
|
|
133
|
+
var MCQScorer = class extends AbstractScorer.withKind(`${PEERBENCH_NAMESPACE}/mcq`) {
|
|
124
134
|
regexScorer = new RegexScorer();
|
|
125
135
|
async score(params) {
|
|
126
136
|
const { response, choices, correctAnswers } = params;
|
|
@@ -251,8 +261,7 @@ function escapeRegex(str) {
|
|
|
251
261
|
|
|
252
262
|
// src/scorers/llm-judge.ts
|
|
253
263
|
import z from "zod";
|
|
254
|
-
var LLMAsAJudgeScorer = class extends AbstractScorer {
|
|
255
|
-
kind = `${PEERBENCH_NAMESPACE}/llm-as-a-judge`;
|
|
264
|
+
var LLMAsAJudgeScorer = class extends AbstractScorer.withKind(`${PEERBENCH_NAMESPACE}/llm-as-a-judge`) {
|
|
256
265
|
provider;
|
|
257
266
|
constructor(config) {
|
|
258
267
|
super();
|
|
@@ -362,4 +371,4 @@ export {
|
|
|
362
371
|
MCQScorer,
|
|
363
372
|
LLMAsAJudgeScorer
|
|
364
373
|
};
|
|
365
|
-
//# sourceMappingURL=chunk-
|
|
374
|
+
//# sourceMappingURL=chunk-3JHDJEY3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scorers/abstract.ts","../src/scorers/regex.ts","../src/scorers/mcq.ts","../src/scorers/llm-judge.ts"],"sourcesContent":["export abstract class AbstractScorer {\n readonly kind: string;\n\n constructor() {\n this.kind = (this.constructor as any).kind;\n if (!this.kind) throw new Error(`${this.constructor.name} must define \"static readonly kind\" as a constant property.`);\n }\n\n abstract score(params: any): Promise<BaseScorerResult | null>;\n\n static withKind<\n TKind extends string,\n TThis extends abstract new (...args: any[]) => AbstractScorer\n >(this: TThis, kind: TKind) {\n const base = this as unknown as new (...args: any[]) => any;\n const derived = class extends base {\n static readonly kind: TKind = kind;\n declare readonly kind: TKind;\n };\n\n return derived as unknown as (new () => InstanceType<TThis> & { readonly kind: TKind }) & {\n readonly kind: TKind;\n };\n }\n}\n\nexport type BaseScorerResult = {\n value: number;\n explanation?: string;\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n};\n","import { PEERBENCH_NAMESPACE } from \"@/constants\";\nimport { AbstractScorer, BaseScorerResult } from \"./abstract\";\n\nexport type RegexPattern = {\n /**\n * The regex pattern to match against the response\n */\n regex: RegExp;\n\n /**\n * The index of the capture group to extract (1-based, like match[1])\n * If not provided, defaults to 1 (first capture group)\n */\n captureGroupIndex?: number;\n\n /**\n * Optional function to transform the extracted value before validation\n */\n transform?: (value: string) => string | undefined;\n};\n\nexport type RegexScorerParams = {\n /**\n * The input text to score\n */\n input: string;\n\n /**\n * Array of regex patterns to try (in order, first match wins)\n */\n patterns: RegexPattern[];\n\n /**\n * Expected value(s) to match against. Can be a record of expected values for named groups, or a validation function\n */\n expectedValue:\n | Record<string, string>\n | ((groupName: string, match: string) => boolean);\n\n /**\n * Optional: Which match to use when multiple matches are found\n * Defaults to \"last\" (uses the last match found)\n */\n matchPreference?: \"first\" | \"last\";\n\n /**\n * Optional: If true, allows partial scoring based on how many groups match\n * For example, if 2 groups are expected and only 1 matches, score would be 0.5\n * Defaults to false (all-or-nothing scoring)\n */\n allowPartialScoring?: boolean;\n};\n\n/**\n * Generic Regex scorer. It scores the given input against a set of regex patterns.\n */\nexport class RegexScorer extends AbstractScorer.withKind(`${PEERBENCH_NAMESPACE}/regex`) {\n override async score(params: RegexScorerParams) {\n // Collect all named group names from all patterns\n const allGroupNames = new Set<string>();\n for (const pattern of params.patterns) {\n const regexSource = pattern.regex.source;\n const namedGroupRegex = /\\(\\?<(\\w+)>/g;\n\n while (true) {\n const match = namedGroupRegex.exec(regexSource);\n if (match === null) {\n break;\n }\n\n if (match[1]) {\n allGroupNames.add(match[1]);\n }\n }\n }\n\n // Initialize result object with all group names set to null (aka not found yet)\n const extractedValues: Record<string, string | null> = {};\n for (const groupName of allGroupNames) {\n extractedValues[groupName] = null;\n }\n\n // Try regex patterns in order, stop at first successful match\n const matchPreference = params.matchPreference ?? \"last\";\n for (const pattern of params.patterns) {\n const matches = Array.from(params.input.matchAll(pattern.regex));\n const match = matchPreference === \"first\" ? matches[0] : matches.at(-1);\n\n if (match && match.groups) {\n // Extract all named groups from this match\n let hasExtractedValue = false;\n for (const [groupName, groupValue] of Object.entries(match.groups)) {\n if (groupValue !== undefined) {\n let value = groupValue;\n\n // Apply transformation if provided\n if (pattern.transform) {\n const transformed = pattern.transform(value);\n if (transformed === undefined) {\n continue;\n }\n value = transformed;\n }\n\n extractedValues[groupName] = value;\n hasExtractedValue = true;\n }\n }\n // If we extracted at least one value, stop processing further patterns\n if (hasExtractedValue) {\n break;\n }\n } else if (match) {\n // Fallback to captureGroupIndex if no named groups\n // For unnamed groups, we can't add to extractedValues by name\n // They are only used for scoring if no named groups are found\n const captureGroupIndex = pattern.captureGroupIndex ?? 1;\n const extractedValue = match[captureGroupIndex];\n\n if (extractedValue !== undefined) {\n // Apply transformation if provided\n if (pattern.transform) {\n const transformed = pattern.transform(extractedValue);\n if (transformed === undefined) {\n continue;\n }\n // For unnamed groups, we can't store in extractedValues\n // but we can use it for scoring if no named groups were found\n }\n // If we have an extracted value (even if unnamed), stop processing\n // Note: This is a fallback case, so we break here too\n break;\n }\n }\n }\n\n // Calculate score based on matched value\n const allowPartial = params.allowPartialScoring ?? false;\n let score = 0;\n\n if (typeof params.expectedValue === \"function\") {\n // To get proper type inference, cast it using \"as\"\n const validator = params.expectedValue as typeof params.expectedValue;\n const extractedEntries = Object.entries(extractedValues).filter(\n ([, value]) => value !== null\n );\n\n // If no values were extracted, score is 0\n if (extractedEntries.length === 0) {\n score = 0;\n } else {\n if (allowPartial) {\n // Count how many extracted values pass validation\n const passingCount = extractedEntries.filter(\n ([groupName, extractedValue]) =>\n validator(groupName, extractedValue as string)\n ).length;\n score = passingCount / extractedEntries.length;\n } else {\n // All extracted values must pass validation\n const allMatch = extractedEntries.every(\n ([groupName, extractedValue]) =>\n validator(groupName, extractedValue as string)\n );\n score = allMatch ? 1 : 0;\n }\n }\n } else {\n const expectedEntries = Object.entries(params.expectedValue);\n const totalExpected = expectedEntries.length;\n\n if (allowPartial) {\n // Count how many expected values match their extracted values\n const matchingCount = expectedEntries.filter(([key, expectedValue]) => {\n const extractedValue = extractedValues[key];\n return extractedValue !== null && extractedValue === expectedValue;\n }).length;\n score = totalExpected > 0 ? matchingCount / totalExpected : 0;\n } else {\n // All expected values must match\n const allMatch = expectedEntries.every(([key, expectedValue]) => {\n const extractedValue = extractedValues[key];\n return extractedValue !== null && extractedValue === expectedValue;\n });\n score = allMatch ? 1 : 0;\n }\n }\n\n return {\n value: score,\n extractedAnswers: Object.fromEntries(\n Object.entries(extractedValues).filter(\n (entry): entry is [string, string] => entry[1] !== null\n )\n ),\n } satisfies BaseScorerResult;\n }\n}\n","import { parseResponseAsJSON } from \"@/utils\";\nimport { AbstractScorer, BaseScorerResult } from \"./abstract\";\nimport { RegexScorer, RegexPattern, RegexScorerParams } from \"./regex\";\nimport { PEERBENCH_NAMESPACE } from \"@/constants\";\n\nexport type MCQScorerParams = {\n response: string;\n choices: Record<string, string>;\n correctAnswers: string[];\n};\n\nexport class MCQScorer extends AbstractScorer.withKind(`${PEERBENCH_NAMESPACE}/mcq`) {\n private regexScorer = new RegexScorer();\n\n async score(params: MCQScorerParams): Promise<\n BaseScorerResult & {\n extractedAnswers: string[];\n }\n > {\n const { response, choices, correctAnswers } = params;\n const normalizedCorrectAnswers = correctAnswers.map((ca) =>\n ca.toUpperCase()\n );\n\n // Direct answer comparison\n const normalizedResponse = response.trim().toUpperCase();\n if (normalizedCorrectAnswers.includes(normalizedResponse)) {\n return {\n value: 1,\n extractedAnswers: [normalizedResponse],\n };\n }\n\n // Try to parse the response as JSON (original behavior: returns early if parsed)\n const json = parseResponseAsJSON<{ answer: string }>(response);\n if (json !== undefined && typeof json === \"object\") {\n const extractedAnswer =\n json.answer !== undefined ? getFirstLetter(json.answer) : undefined;\n\n if (extractedAnswer !== undefined) {\n const normalizedExtracted = extractedAnswer.trim().toUpperCase();\n if (normalizedCorrectAnswers.includes(normalizedExtracted)) {\n return {\n value: 1,\n extractedAnswers: [extractedAnswer],\n };\n }\n\n // Response parsed as JSON but does not represent the correct answer\n return {\n value: 0,\n extractedAnswers:\n json.answer === undefined\n ? []\n : [extractedAnswer ?? String(json.answer)],\n };\n }\n }\n\n // Build patterns for all correctAnswers\n const patterns: RegexPattern[] = [];\n for (const answer of Object.values(params.choices)) {\n const answerPatterns = this.buildPatternsForAnswer(answer);\n patterns.push(...answerPatterns);\n }\n\n // Create validation function that handles choices matching\n // New RegexScorer API expects (groupName: string, match: string) => boolean\n const validateAnswer = (groupName: string, extracted: string): boolean => {\n const normalizedExtracted = extracted.trim().toUpperCase();\n\n // Check if extracted value is in correctAnswers\n if (normalizedCorrectAnswers.includes(normalizedExtracted)) {\n return true;\n }\n\n // Check if extracted text matches any choice value, and that choice key is correct\n // Note: When transform uppercases the value, we need to compare case-insensitively\n const answerOption = Object.entries(choices).find(\n ([, value]) =>\n value.trim().toUpperCase() === extracted.trim().toUpperCase()\n );\n\n if (\n answerOption &&\n normalizedCorrectAnswers.includes(answerOption[0].toUpperCase())\n ) {\n return true;\n }\n\n return false;\n };\n\n // Build regex scorer params\n const regexParams: RegexScorerParams = {\n input: response,\n patterns,\n expectedValue: validateAnswer,\n matchPreference: \"last\",\n };\n\n // Call regex scorer\n const result = await this.regexScorer.score(regexParams);\n\n return {\n value: result.value,\n extractedAnswers: Object.entries(result.extractedAnswers).map(\n ([, value]) => value\n ),\n };\n }\n\n private buildPatternsForAnswer(answerText: string): RegexPattern[] {\n const escapedAnswer = escapeRegex(answerText);\n\n return [\n {\n // \"<!NO ANSWER!>\" - This pattern matches but has no capture group, so it won't extract anything\n regex: /<!NO ANSWER!>/g,\n },\n // Specific patterns for the full answer text (checked first)\n {\n // \"Answer is $\\boxed{answer text}$\"\n regex: new RegExp(\n `[Aa]nswer is \\\\$\\\\\\\\boxed\\\\{(?<answer>${escapedAnswer})\\\\}\\\\$`,\n \"g\"\n ),\n transform: (value: string) => value.toUpperCase(),\n },\n {\n // \"Answer is answer text\"\n regex: new RegExp(`[Aa]nswer is\\\\s+(?<answer>${escapedAnswer})`, \"g\"),\n transform: (value: string) => value.toUpperCase(),\n },\n {\n // \"Answer is **answer text**\"\n regex: new RegExp(\n `[Aa]nswer is\\\\s+\\\\**(?<answer>${escapedAnswer})\\\\**`,\n \"g\"\n ),\n transform: (value: string) => value.toUpperCase(),\n },\n // Generic patterns (checked after specific patterns)\n {\n // \"Answer is $\\boxed{A}$.\"\n regex: /[Aa]nswer is \\$\\\\boxed\\{(?<answer>[A-Z])\\}\\$\\.?/g,\n },\n {\n // \"Answer is A\" - match single letter only when it's a complete standalone answer.\n // Pattern matches: \"Answer is\" + whitespace + single letter + end or punctuation\n regex: /[Aa]nswer is\\s+(?<answer>[A-Z])(?=\\s*$|[.,;:!?])/g,\n },\n {\n // \"Answer is **A**\"\n regex: /[Aa]nswer is\\s+\\**(?<answer>[A-Z])\\**/g,\n },\n {\n // \"A: answer text\"\n regex: /(?<answer>[A-Z]):.+/g,\n },\n {\n // \"A) answer text\"\n regex: /(?<answer>[A-Z])\\)\\s*.+/g,\n },\n {\n // \"A)\"\n regex: /(?<answer>[A-Z])\\)/g,\n },\n ];\n }\n}\n\nfunction getFirstLetter(text: string): string | undefined {\n const match = text.match(/[A-Za-z]/);\n return match ? match[0].toUpperCase() : undefined;\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { AbstractLLMProvider } from \"@/providers/abstract/llm\";\nimport { parseResponseAsJSON } from \"@/utils\";\nimport { RateLimiter } from \"@/utils/rate-limiter\";\nimport { AbstractScorer, BaseScorerResult } from \"./abstract\";\nimport { PEERBENCH_NAMESPACE } from \"@/constants\";\nimport z from \"zod\";\n\nexport class LLMAsAJudgeScorer extends AbstractScorer.withKind(`${PEERBENCH_NAMESPACE}/llm-as-a-judge`) {\n private provider: AbstractLLMProvider;\n\n constructor(config: {\n provider: AbstractLLMProvider;\n rateLimiter?: RateLimiter;\n }) {\n super();\n this.provider = config.provider;\n }\n\n override async score<T extends z.ZodRawShape>(\n params: LLMAsAJudgeScoreParams & { fieldsToExtract: T }\n ): Promise<ScorerResultWithExtractedFields<T> | null>;\n override async score(\n params: LLMAsAJudgeScoreParams & { fieldsToExtract?: never }\n ): Promise<ScorerResultWithoutExtractedFields | null>;\n override async score<T extends z.ZodRawShape>(\n params: LLMAsAJudgeScoreParams & { fieldsToExtract?: T }\n ): Promise<\n | ScorerResultWithoutExtractedFields\n | ScorerResultWithExtractedFields<T>\n | null\n > {\n const criteria = normalizeWeights(params.criteria);\n const systemPrompt = [];\n const responseSchema = z.object({\n results: z\n .array(\n z.object({\n id: z.string().describe(\"The id of the criterion\"),\n score: z.number().describe(\"The score of the criterion\"),\n explanation: z\n .string()\n .describe(\"The explanation of the criterion\"),\n })\n )\n .describe(\"The results of the evaluation per criterion\"),\n\n explanation: z\n .string()\n .describe(\n `The overall explanation for the score (less than ${params.maxExplanationLength ?? 200} characters)`\n ),\n\n ...(params.fieldsToExtract ?? {}),\n });\n\n if (params.systemPrompt) {\n systemPrompt.push(params.systemPrompt);\n } else {\n systemPrompt.push(\"You are a strict, fair evaluation judge.\");\n systemPrompt.push(\"Only use information from the rubric\");\n }\n\n systemPrompt.push(\n \"For each criterion return an integer score within the provided scale and a very brief justification (less than 2 sentences).\"\n );\n systemPrompt.push(\n [\n `Rubric: ${params.rubric}`,\n `Criteria:`,\n ...criteria.map(\n (criterion) =>\n `- ${criterion.id}: ${criterion.description} (weight: ${criterion.weight}, scale: ${criterion.scale?.min ?? 0}..${criterion.scale?.max ?? 5})`\n ),\n ].join(\"\\n\")\n );\n\n const responseJSONSchema = responseSchema.toJSONSchema();\n systemPrompt.push(\n `Reply back with the following JSON schema (strict):\\n${JSON.stringify(responseJSONSchema, null, 2)}\\n`\n );\n\n const userPrompt = [`Answer: ${params.response}`];\n const providerResponse = await this.provider.forward({\n messages: [\n {\n role: \"system\",\n content: systemPrompt.join(\"\\n\"),\n },\n {\n role: \"user\",\n content: userPrompt.join(\"\\n\"),\n },\n ],\n model: params.model,\n responseFormat: {\n type: \"json_schema\",\n json_schema: {\n name: \"judgeResult\",\n schema: responseJSONSchema,\n },\n },\n });\n\n const parsed = responseSchema.parse(\n parseResponseAsJSON(providerResponse.data)\n );\n\n const { explanation, results, ...extractedFields } = parsed;\n\n return {\n explanation,\n results,\n value: computeOverallScore(results, criteria),\n extractedFields: extractedFields as z.infer<z.ZodObject<T>>,\n\n provider: this.provider.kind,\n inputTokensUsed: providerResponse.inputTokensUsed,\n outputTokensUsed: providerResponse.outputTokensUsed,\n inputCost: providerResponse.inputCost,\n outputCost: providerResponse.outputCost,\n };\n }\n}\n\nexport type LLMAsAJudgeCriterion = {\n id: string;\n description: string;\n weight: number;\n scale?: {\n min: number;\n max: number;\n };\n};\n\nexport type LLMAsAJudgeScoreParams = {\n model: string;\n response: string;\n rubric: string;\n criteria: LLMAsAJudgeCriterion[];\n\n systemPrompt?: string;\n maxExplanationLength?: number;\n};\n\ntype ScorerResultWithoutExtractedFields = BaseScorerResult & {\n results: {\n id: string;\n score: number;\n explanation: string;\n }[];\n\n provider: string;\n inputTokensUsed?: number;\n outputTokensUsed?: number;\n inputCost?: string;\n outputCost?: string;\n};\n\ntype ScorerResultWithExtractedFields<T extends z.ZodRawShape> =\n ScorerResultWithoutExtractedFields & {\n extractedFields: z.infer<z.ZodObject<T>>;\n };\n\nfunction normalizeWeights(\n criteria: LLMAsAJudgeCriterion[]\n): LLMAsAJudgeCriterion[] {\n const sum = criteria.reduce((a, c) => a + (c.weight ?? 1), 0) || 1;\n return criteria.map((c) => ({ ...c, weight: (c.weight ?? 1) / sum }));\n}\n\nfunction computeOverallScore(\n results: ScorerResultWithoutExtractedFields[\"results\"],\n criteria: LLMAsAJudgeCriterion[]\n): number {\n let total = 0;\n for (const pc of results) {\n const criterion = criteria.find((c) => c.id === pc.id);\n const min = criterion?.scale?.min ?? 0;\n const max = criterion?.scale?.max ?? 5;\n const weight = criterion?.weight ?? 0;\n\n const score = Number(pc.score);\n if (!Number.isFinite(score)) continue;\n\n const clamped = Math.max(min, Math.min(max, score));\n const normalized01 = max === min ? 0 : (clamped - min) / (max - min);\n total += normalized01 * weight;\n }\n return Math.max(0, Math.min(1, total));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -7,6 +7,18 @@ import {
|
|
|
7
7
|
|
|
8
8
|
// src/providers/abstract/provider.ts
|
|
9
9
|
var AbstractProvider = class {
|
|
10
|
+
kind;
|
|
11
|
+
constructor() {
|
|
12
|
+
this.kind = this.constructor.kind;
|
|
13
|
+
if (!this.kind) throw new Error(`${this.constructor.name} must define "static readonly kind" as a constant property.`);
|
|
14
|
+
}
|
|
15
|
+
static withKind(kind) {
|
|
16
|
+
const base = this;
|
|
17
|
+
const derived = class extends base {
|
|
18
|
+
static kind = kind;
|
|
19
|
+
};
|
|
20
|
+
return derived;
|
|
21
|
+
}
|
|
10
22
|
};
|
|
11
23
|
|
|
12
24
|
// src/providers/abstract/llm.ts
|
|
@@ -15,8 +27,7 @@ var AbstractLLMProvider = class extends AbstractProvider {
|
|
|
15
27
|
|
|
16
28
|
// src/providers/mastra.ts
|
|
17
29
|
import { MastraClient } from "@mastra/client-js";
|
|
18
|
-
var MastraProvider = class extends AbstractLLMProvider {
|
|
19
|
-
kind = "mastra";
|
|
30
|
+
var MastraProvider = class extends AbstractLLMProvider.withKind(`${PEERBENCH_NAMESPACE}/llm/mastra`) {
|
|
20
31
|
endpoint;
|
|
21
32
|
authToken;
|
|
22
33
|
client;
|
|
@@ -65,8 +76,7 @@ var MastraProvider = class extends AbstractLLMProvider {
|
|
|
65
76
|
|
|
66
77
|
// src/providers/openai.ts
|
|
67
78
|
import OpenAI, { APIError } from "openai";
|
|
68
|
-
var OpenAIProvider = class extends AbstractLLMProvider {
|
|
69
|
-
kind = `${PEERBENCH_NAMESPACE}/llm/openai`;
|
|
79
|
+
var OpenAIProvider = class extends AbstractLLMProvider.withKind(`${PEERBENCH_NAMESPACE}/llm/openai`) {
|
|
70
80
|
client;
|
|
71
81
|
rateLimiter;
|
|
72
82
|
maxRetries;
|
|
@@ -152,8 +162,7 @@ import Decimal from "decimal.js";
|
|
|
152
162
|
import axios from "axios";
|
|
153
163
|
var baseURL = "https://openrouter.ai/api/v1";
|
|
154
164
|
var MODELS_CACHE_TTL = 1e3 * 60 * 60 * 24;
|
|
155
|
-
var OpenRouterProvider = class extends AbstractLLMProvider {
|
|
156
|
-
kind = `${PEERBENCH_NAMESPACE}/llm/openrouter.ai`;
|
|
165
|
+
var OpenRouterProvider = class extends AbstractLLMProvider.withKind(`${PEERBENCH_NAMESPACE}/llm/openrouter.ai`) {
|
|
157
166
|
models = void 0;
|
|
158
167
|
modelsCachePromise = Promise.resolve(void 0);
|
|
159
168
|
modelsUpdatedAt = 0;
|
|
@@ -232,4 +241,4 @@ export {
|
|
|
232
241
|
OpenAIProvider,
|
|
233
242
|
OpenRouterProvider
|
|
234
243
|
};
|
|
235
|
-
//# sourceMappingURL=chunk-
|
|
244
|
+
//# sourceMappingURL=chunk-SMLNDQFX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/abstract/provider.ts","../src/providers/abstract/llm.ts","../src/providers/mastra.ts","../src/providers/openai.ts","../src/providers/openrouter.ts"],"sourcesContent":["export abstract class AbstractProvider {\n readonly kind: string;\n\n constructor() {\n this.kind = (this.constructor as any).kind;\n if (!this.kind) throw new Error(`${this.constructor.name} must define \"static readonly kind\" as a constant property.`);\n }\n static withKind<\n TKind extends string,\n TThis extends abstract new (...args: any[]) => AbstractProvider\n >(this: TThis, kind: TKind) {\n const base = this as unknown as new (...args: any[]) => any;\n const derived = class extends base {\n static readonly kind: TKind = kind;\n declare readonly kind: TKind;\n };\n\n return derived as unknown as (new () => InstanceType<TThis> & { readonly kind: TKind }) & {\n readonly kind: TKind;\n };\n }\n}\n\nexport type ProviderResponse<TData = unknown> = {\n startedAt: number;\n completedAt: number;\n data: TData;\n};\n","import { AbstractProvider, ProviderResponse } from \"./provider\";\nimport {\n ResponseFormatJSONObject,\n ResponseFormatJSONSchema,\n ResponseFormatText,\n} from \"openai/resources/shared\";\nimport { ChatCompletionMessageParam } from \"openai/resources/chat/completions\";\n\nexport abstract class AbstractLLMProvider extends AbstractProvider {\n abstract forward(args: LLMProviderForwardArgs): Promise<ChatResponse>;\n}\n\nexport type LLMProviderForwardArgs = {\n messages: ChatCompletionMessageParam[];\n model: string;\n abortSignal?: AbortSignal;\n temperature?: number;\n responseFormat?:\n | ResponseFormatText\n | ResponseFormatJSONSchema\n | ResponseFormatJSONObject;\n};\n\nexport type ChatResponse = ProviderResponse<string> & {\n inputTokensUsed?: number;\n outputTokensUsed?: number;\n inputCost?: string;\n outputCost?: string;\n\n metadata?: Record<string, unknown>;\n};\n","import { PEERBENCH_NAMESPACE } from \"@/constants\";\nimport {\n AbstractLLMProvider,\n type ChatResponse,\n type LLMProviderForwardArgs,\n} from \"./abstract/llm\";\nimport { MastraClient, type GetAgentResponse } from \"@mastra/client-js\";\n\nexport class MastraProvider extends AbstractLLMProvider.withKind(`${PEERBENCH_NAMESPACE}/llm/mastra`) {\n\n private readonly endpoint: string;\n private readonly authToken?: string;\n private client: MastraClient;\n private memory?: AgentMemoryOption;\n\n constructor(params: {\n endpoint: string;\n authToken?: string;\n memory?: AgentMemoryOption;\n }) {\n super();\n this.endpoint = params.endpoint;\n this.authToken = params.authToken;\n this.client = new MastraClient({\n baseUrl: this.endpoint,\n headers: this.authToken\n ? {\n Authorization: `Bearer ${this.authToken}`,\n }\n : undefined,\n });\n this.memory = params.memory;\n }\n\n override async forward(\n args: LLMProviderForwardArgs & {\n memory?: AgentMemoryOption;\n\n /**\n * The model that will be used as the brain for the agent.\n */\n modelName?: string\n }\n ): Promise<ChatResponse> {\n const apiMessages = args.messages\n .filter((m) => m.role === \"user\" || m.role === \"assistant\")\n .map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content: String((m as any).content ?? \"\"),\n }));\n\n const agent = this.client.getAgent(args.model);\n\n const startedAt = Date.now();\n const response = await agent.generate(\n {\n messages: apiMessages,\n runtimeContext: {\n \"model-id\": args.modelName,\n },\n },\n { memory: args.memory ?? this.memory }\n );\n\n return {\n data: response.text,\n startedAt,\n completedAt: Date.now(),\n };\n }\n\n async getAgentInfo(args: {\n agentId: string;\n runtimeContext?: MastraRuntimeContext;\n }) {\n return await this.client\n .getAgent(args.agentId)\n .details(args.runtimeContext);\n }\n\n async getAgents(args?: {\n runtimeContext?: MastraRuntimeContext;\n partial?: boolean;\n }): Promise<Record<string, GetAgentResponse>> {\n return this.client.getAgents(args?.runtimeContext, args?.partial);\n }\n}\n\n// NOTE: Mastra client does not export these types\nexport type AgentMemoryOption = Parameters<\n Parameters<MastraClient[\"getAgent\"]>[\"0\"] extends string\n ? ReturnType<MastraClient[\"getAgent\"]>[\"generate\"]\n : never\n>[0] extends { memory?: infer M }\n ? M\n : never;\n\ntype MastraRuntimeContext = Parameters<\n Parameters<MastraClient[\"getAgent\"]>[\"0\"] extends string\n ? ReturnType<MastraClient[\"getAgent\"]>[\"generate\"]\n : never\n>[0] extends { runtimeContext?: infer R }\n ? R\n : never;\n","import { RateLimiter } from \"@/utils\";\nimport { ChatCompletionMessageParam } from \"openai/resources/chat/completions\";\nimport {\n ResponseFormatJSONObject,\n ResponseFormatJSONSchema,\n ResponseFormatText,\n} from \"openai/resources/shared\";\nimport OpenAI, { APIError } from \"openai\";\nimport { AbstractLLMProvider, ChatResponse } from \"./abstract/llm\";\nimport { PEERBENCH_NAMESPACE } from \"@/constants\";\n\nexport class OpenAIProvider extends AbstractLLMProvider.withKind(`${PEERBENCH_NAMESPACE}/llm/openai`) {\n private client: OpenAI;\n private rateLimiter: RateLimiter;\n private maxRetries: number;\n\n constructor(config: {\n apiKey: string;\n baseURL: string;\n maxRetries?: number;\n timeout?: number;\n rateLimiter?: RateLimiter;\n }) {\n super();\n this.maxRetries = config.maxRetries ?? 3;\n this.rateLimiter =\n config.rateLimiter ??\n new RateLimiter({\n maxWeight: 20,\n timeWindow: 3_000,\n });\n\n this.client = new OpenAI({\n baseURL: config.baseURL,\n apiKey: config.apiKey,\n timeout: config.timeout,\n dangerouslyAllowBrowser: true,\n });\n }\n\n async forward(args: {\n messages: ChatCompletionMessageParam[];\n model: string;\n abortSignal?: AbortSignal;\n temperature?: number;\n responseFormat?:\n | ResponseFormatText\n | ResponseFormatJSONSchema\n | ResponseFormatJSONObject;\n }): Promise<ChatResponse> {\n let retryCount = this.maxRetries;\n while (retryCount > 0) {\n let startedAt: Date = new Date();\n\n try {\n const response = await this.rateLimiter.execute(\n async () => {\n // Capture the start time of the request\n startedAt = new Date();\n return await this.client.chat.completions.create(\n {\n model: args.model,\n messages: args.messages,\n temperature: args.temperature,\n response_format: args.responseFormat,\n },\n // Signal for request\n { signal: args.abortSignal }\n );\n },\n // Signal for rate limiting\n { signal: args.abortSignal }\n );\n\n if (\"error\" in response) {\n const err = response.error as any;\n throw new Error(\n `${err.message} - Code ${err.code} - ${JSON.stringify(err)}`\n );\n }\n\n if (!response?.choices?.[0]?.message?.content) {\n throw new Error(\"No content returned from the model\");\n }\n\n return {\n data: response.choices[0].message.content,\n\n inputTokensUsed: response?.usage?.prompt_tokens,\n outputTokensUsed: response?.usage?.completion_tokens,\n\n startedAt: startedAt.getTime(),\n completedAt: Date.now(),\n };\n } catch (err) {\n if (err instanceof APIError && err.status === 401) {\n throw new Error(`Invalid credentials provided`, { cause: err });\n }\n\n retryCount--;\n\n // More likely an empty HTTP response returned by the Provider\n // and it couldn't be parsed as JSON by the OpenAI SDK. We need to retry the request\n // More info can be found in the following links:\n // https://www.reddit.com/r/SillyTavernAI/comments/1ik95vr/deepseek_r1_on_openrouter_returning_blank_messages/\n // https://github.com/cline/cline/issues/60\n if (err instanceof SyntaxError) {\n console.debug(err);\n continue;\n }\n\n // If it was another error, just continue until we run out of retries\n if (retryCount !== 0) {\n continue;\n }\n\n throw new Error(\n `Failed to forward prompt to the model: ${err instanceof Error ? err.message : err}`,\n { cause: err }\n );\n }\n }\n\n throw new Error(\n `Failed to forward prompt to the model: Max retries reached`,\n { cause: new Error(\"Max retries reached\") }\n );\n }\n}\n","import {\n AbstractLLMProvider,\n ChatResponse,\n LLMProviderForwardArgs,\n} from \"./abstract/llm\";\nimport { RateLimiter } from \"@/utils\";\nimport { OpenAIProvider } from \"./openai\";\nimport { PEERBENCH_NAMESPACE } from \"@/constants\";\nimport Decimal from \"decimal.js\";\nimport axios from \"axios\";\n\nconst baseURL = \"https://openrouter.ai/api/v1\";\nconst MODELS_CACHE_TTL = 1000 * 60 * 60 * 24; // 24 hours\n\nexport class OpenRouterProvider extends AbstractLLMProvider.withKind(`${PEERBENCH_NAMESPACE}/llm/openrouter.ai`) {\n private models: ModelsResponse | undefined = undefined;\n private modelsCachePromise: Promise<ModelsResponse | undefined> =\n Promise.resolve(undefined);\n private modelsUpdatedAt = 0;\n private openAIProvider: OpenAIProvider;\n\n constructor(config: {\n apiKey: string;\n maxRetries?: number;\n timeout?: number;\n rateLimiter?: RateLimiter;\n }) {\n super();\n this.openAIProvider = new OpenAIProvider({\n baseURL,\n apiKey: config.apiKey,\n maxRetries: config.maxRetries,\n timeout: config.timeout,\n rateLimiter: config.rateLimiter,\n });\n }\n\n override async forward(args: LLMProviderForwardArgs): Promise<ChatResponse> {\n // Update models cache concurrently (non-blocking)\n const [response] = await Promise.all([\n this.openAIProvider.forward(args),\n this.updateModelsCache().catch(() => {\n // Silently fail if cache update fails so we won't have cost info in the result\n }),\n ]);\n\n // Get the model info from the cache\n const modelInfo = this.models?.data.find((m) => m.id === args.model);\n let inputCost: string | undefined = undefined;\n let outputCost: string | undefined = undefined;\n\n if (modelInfo !== undefined) {\n // Use Decimal.js for more accurate calculation\n if (response.inputTokensUsed !== undefined) {\n inputCost = new Decimal(modelInfo.pricing.prompt)\n .mul(response.inputTokensUsed)\n .toFixed(10);\n }\n if (response.outputTokensUsed !== undefined) {\n outputCost = new Decimal(modelInfo.pricing.completion)\n .mul(response.outputTokensUsed)\n .toFixed(10);\n }\n }\n\n return {\n ...response,\n inputCost,\n outputCost,\n };\n }\n\n /**\n * Updates the cache that holds information about OpenRouter models\n * including pricing information. It will be valid for 24 hours as\n * long as the instance of this Provider object is alive.\n */\n private async updateModelsCache() {\n // Chain each update method call to the promise.\n // This approach prevents race conditions between multiple calls.\n // Since each call is chained to the end of the previous one,\n // each promise makes a request only if the models cache is not updated\n // in the last call. Otherwise it simply resolves to the cached value.\n this.modelsCachePromise = this.modelsCachePromise\n .then(async () => {\n if (\n // The data presented in the cache\n this.models !== undefined &&\n // The cache is still valid\n Date.now() - this.modelsUpdatedAt < MODELS_CACHE_TTL\n ) {\n return this.models;\n }\n\n // If the cache is not valid, update it\n return axios\n .get<ModelsResponse>(`${baseURL}/models`)\n .then((res) => res.data)\n .then((data) => {\n // Only get the models that supports text input and output\n data = {\n data: data.data.filter(\n (m) =>\n m.architecture.input_modalities.includes(\"text\") &&\n m.architecture.output_modalities.includes(\"text\") &&\n // These models are \"fast apply model\" and don't support multi turn conversations so don't include them\n ![\n \"morph/morph-v3-large\",\n \"morph/morph-v3-fast\",\n \"relace/relace-apply-3\",\n ].includes(m.id)\n ),\n };\n\n this.models = data;\n this.modelsUpdatedAt = Date.now();\n\n return data;\n });\n })\n .catch(() => undefined);\n\n // Wait for the promise chain to resolve\n await this.modelsCachePromise;\n }\n}\n\ntype PutModality = \"text\" | \"image\" | \"file\" | \"audio\";\ntype Modality = \"text->text\" | \"text+image->text\" | \"text+image->text+image\";\ntype ModelsResponse = {\n data: {\n readonly id: string;\n readonly canonical_slug: string;\n readonly hugging_face_id: null | string;\n readonly name: string;\n readonly created: number;\n readonly description: string;\n readonly context_length: number;\n readonly architecture: {\n readonly modality: Modality;\n readonly input_modalities: PutModality[];\n readonly output_modalities: PutModality[];\n readonly instruct_type: null | string;\n };\n readonly pricing: {\n readonly prompt: string;\n readonly completion: string;\n readonly request?: string;\n readonly image?: string;\n readonly web_search?: string;\n readonly internal_reasoning?: string;\n readonly input_cache_read?: string;\n readonly input_cache_write?: string;\n readonly audio?: string;\n };\n }[];\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildSchemaDefiner
|
|
3
|
-
} from "./chunk-OQE6TQXZ.js";
|
|
4
1
|
import {
|
|
5
2
|
CATEGORIES,
|
|
6
3
|
PEERBENCH_NAMESPACE
|
|
7
4
|
} from "./chunk-UHHHSYVE.js";
|
|
5
|
+
import {
|
|
6
|
+
buildSchemaDefiner
|
|
7
|
+
} from "./chunk-OQE6TQXZ.js";
|
|
8
8
|
import {
|
|
9
9
|
IdSchema
|
|
10
10
|
} from "./chunk-NUEOE3K5.js";
|
|
@@ -41,4 +41,4 @@ export {
|
|
|
41
41
|
defineSystemPromptSchema,
|
|
42
42
|
SimpleSystemPromptSchemaV1
|
|
43
43
|
};
|
|
44
|
-
//# sourceMappingURL=chunk-
|
|
44
|
+
//# sourceMappingURL=chunk-ZXTQJFGL.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as AbstractProvider } from './provider-
|
|
1
|
+
import { A as AbstractProvider } from './provider-DnEBdl1n.js';
|
|
2
2
|
import z__default, { z } from 'zod';
|
|
3
|
-
import { A as AbstractScorer } from './abstract-
|
|
3
|
+
import { A as AbstractScorer } from './abstract-BdgLjkNC.js';
|
|
4
4
|
|
|
5
5
|
declare const IdSchema: z__default.ZodString;
|
|
6
6
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { I as IdGenerator, P as ProviderCtor, S as ScorerCtor } from './index-
|
|
2
|
-
export { A as AbstractClassConstructor, C as ClassConstructor, b as Id, a as InferExtension, M as MaybePromise, c as ScoringMethod, W as WidenZodObject } from './index-
|
|
1
|
+
import { I as IdGenerator, P as ProviderCtor, S as ScorerCtor } from './index-Cn20kPrz.js';
|
|
2
|
+
export { A as AbstractClassConstructor, C as ClassConstructor, b as Id, a as InferExtension, M as MaybePromise, c as ScoringMethod, W as WidenZodObject } from './index-Cn20kPrz.js';
|
|
3
3
|
export { R as RateLimiter, b as RateLimiterCallOptions, a as RateLimiterOptions } from './rate-limiter-CSmVIRsM.js';
|
|
4
4
|
import z__default from 'zod';
|
|
5
|
-
import { A as AbstractProvider } from './provider-
|
|
6
|
-
import { A as AbstractScorer } from './abstract-
|
|
5
|
+
import { A as AbstractProvider } from './provider-DnEBdl1n.js';
|
|
6
|
+
import { A as AbstractScorer } from './abstract-BdgLjkNC.js';
|
|
7
7
|
|
|
8
8
|
declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
|
|
9
9
|
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defineRunner
|
|
3
3
|
} from "./chunk-RTEAK4II.js";
|
|
4
|
-
import {
|
|
5
|
-
ScoringMethod
|
|
6
|
-
} from "./chunk-HMQYGCKI.js";
|
|
7
4
|
import {
|
|
8
5
|
CATEGORIES,
|
|
9
6
|
PEERBENCH_NAMESPACE
|
|
@@ -16,6 +13,9 @@ import {
|
|
|
16
13
|
sleep,
|
|
17
14
|
stringToBuffer
|
|
18
15
|
} from "./chunk-4UBK6452.js";
|
|
16
|
+
import {
|
|
17
|
+
ScoringMethod
|
|
18
|
+
} from "./chunk-HMQYGCKI.js";
|
|
19
19
|
import "./chunk-PZ5AY32C.js";
|
|
20
20
|
|
|
21
21
|
// src/errors/polyfill.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AbstractProvider, P as ProviderResponse } from './provider-
|
|
1
|
+
import { A as AbstractProvider, P as ProviderResponse } from './provider-DnEBdl1n.js';
|
|
2
2
|
import { ResponseFormatText, ResponseFormatJSONSchema, ResponseFormatJSONObject } from 'openai/resources/shared';
|
|
3
3
|
import { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
|
|
4
4
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AbstractScorer, B as BaseScorerResult } from './abstract-
|
|
2
|
-
import { A as AbstractLLMProvider } from './llm-
|
|
1
|
+
import { A as AbstractScorer, B as BaseScorerResult } from './abstract-BdgLjkNC.js';
|
|
2
|
+
import { A as AbstractLLMProvider } from './llm-8ecJmwKJ.js';
|
|
3
3
|
import { R as RateLimiter } from './rate-limiter-CSmVIRsM.js';
|
|
4
4
|
import z__default from 'zod';
|
|
5
5
|
|
|
@@ -8,8 +8,12 @@ type MCQScorerParams = {
|
|
|
8
8
|
choices: Record<string, string>;
|
|
9
9
|
correctAnswers: string[];
|
|
10
10
|
};
|
|
11
|
-
declare
|
|
11
|
+
declare const MCQScorer_base: (new () => AbstractScorer & {
|
|
12
12
|
readonly kind: "peerbench.ai/mcq";
|
|
13
|
+
}) & {
|
|
14
|
+
readonly kind: "peerbench.ai/mcq";
|
|
15
|
+
};
|
|
16
|
+
declare class MCQScorer extends MCQScorer_base {
|
|
13
17
|
private regexScorer;
|
|
14
18
|
score(params: MCQScorerParams): Promise<BaseScorerResult & {
|
|
15
19
|
extractedAnswers: string[];
|
|
@@ -17,8 +21,12 @@ declare class MCQScorer extends AbstractScorer {
|
|
|
17
21
|
private buildPatternsForAnswer;
|
|
18
22
|
}
|
|
19
23
|
|
|
20
|
-
declare
|
|
24
|
+
declare const LLMAsAJudgeScorer_base: (new () => AbstractScorer & {
|
|
21
25
|
readonly kind: "peerbench.ai/llm-as-a-judge";
|
|
26
|
+
}) & {
|
|
27
|
+
readonly kind: "peerbench.ai/llm-as-a-judge";
|
|
28
|
+
};
|
|
29
|
+
declare class LLMAsAJudgeScorer extends LLMAsAJudgeScorer_base {
|
|
22
30
|
private provider;
|
|
23
31
|
constructor(config: {
|
|
24
32
|
provider: AbstractLLMProvider;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare abstract class AbstractProvider {
|
|
2
|
+
readonly kind: string;
|
|
3
|
+
constructor();
|
|
4
|
+
static withKind<TKind extends string, TThis extends abstract new (...args: any[]) => AbstractProvider>(this: TThis, kind: TKind): (new () => InstanceType<TThis> & {
|
|
5
|
+
readonly kind: TKind;
|
|
6
|
+
}) & {
|
|
7
|
+
readonly kind: TKind;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
type ProviderResponse<TData = unknown> = {
|
|
11
|
+
startedAt: number;
|
|
12
|
+
completedAt: number;
|
|
13
|
+
data: TData;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { AbstractProvider as A, type ProviderResponse as P };
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import { A as AbstractLLMProvider, L as LLMProviderForwardArgs, C as ChatResponse } from '../llm-
|
|
2
|
-
export { A as AbstractProvider, P as ProviderResponse } from '../provider-
|
|
1
|
+
import { A as AbstractLLMProvider, L as LLMProviderForwardArgs, C as ChatResponse } from '../llm-8ecJmwKJ.js';
|
|
2
|
+
export { A as AbstractProvider, P as ProviderResponse } from '../provider-DnEBdl1n.js';
|
|
3
3
|
import { MastraClient, GetAgentResponse } from '@mastra/client-js';
|
|
4
4
|
import { R as RateLimiter } from '../rate-limiter-CSmVIRsM.js';
|
|
5
5
|
import { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
|
|
6
6
|
import { ResponseFormatText, ResponseFormatJSONSchema, ResponseFormatJSONObject } from 'openai/resources/shared';
|
|
7
7
|
|
|
8
|
-
declare
|
|
9
|
-
readonly kind
|
|
8
|
+
declare const MastraProvider_base: (new () => AbstractLLMProvider & {
|
|
9
|
+
readonly kind: "peerbench.ai/llm/mastra";
|
|
10
|
+
}) & {
|
|
11
|
+
readonly kind: "peerbench.ai/llm/mastra";
|
|
12
|
+
};
|
|
13
|
+
declare class MastraProvider extends MastraProvider_base {
|
|
10
14
|
private readonly endpoint;
|
|
11
15
|
private readonly authToken?;
|
|
12
16
|
private client;
|
|
@@ -39,8 +43,12 @@ type MastraRuntimeContext = Parameters<Parameters<MastraClient["getAgent"]>["0"]
|
|
|
39
43
|
runtimeContext?: infer R;
|
|
40
44
|
} ? R : never;
|
|
41
45
|
|
|
42
|
-
declare
|
|
46
|
+
declare const OpenAIProvider_base: (new () => AbstractLLMProvider & {
|
|
43
47
|
readonly kind: "peerbench.ai/llm/openai";
|
|
48
|
+
}) & {
|
|
49
|
+
readonly kind: "peerbench.ai/llm/openai";
|
|
50
|
+
};
|
|
51
|
+
declare class OpenAIProvider extends OpenAIProvider_base {
|
|
44
52
|
private client;
|
|
45
53
|
private rateLimiter;
|
|
46
54
|
private maxRetries;
|
|
@@ -60,8 +68,12 @@ declare class OpenAIProvider extends AbstractLLMProvider {
|
|
|
60
68
|
}): Promise<ChatResponse>;
|
|
61
69
|
}
|
|
62
70
|
|
|
63
|
-
declare
|
|
71
|
+
declare const OpenRouterProvider_base: (new () => AbstractLLMProvider & {
|
|
72
|
+
readonly kind: "peerbench.ai/llm/openrouter.ai";
|
|
73
|
+
}) & {
|
|
64
74
|
readonly kind: "peerbench.ai/llm/openrouter.ai";
|
|
75
|
+
};
|
|
76
|
+
declare class OpenRouterProvider extends OpenRouterProvider_base {
|
|
65
77
|
private models;
|
|
66
78
|
private modelsCachePromise;
|
|
67
79
|
private modelsUpdatedAt;
|
package/dist/providers/index.js
CHANGED
package/dist/schemas/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { W as WidenZodObject, I as IdGenerator } from '../index-
|
|
2
|
-
export { d as IdSchema } from '../index-
|
|
1
|
+
import { W as WidenZodObject, I as IdGenerator } from '../index-Cn20kPrz.js';
|
|
2
|
+
export { d as IdSchema } from '../index-Cn20kPrz.js';
|
|
3
3
|
import z__default, { z } from 'zod';
|
|
4
|
-
import '../provider-
|
|
5
|
-
import '../abstract-
|
|
4
|
+
import '../provider-DnEBdl1n.js';
|
|
5
|
+
import '../abstract-BdgLjkNC.js';
|
|
6
6
|
|
|
7
7
|
declare const BaseResponseSchemaV1: z__default.ZodObject<{
|
|
8
8
|
id: z__default.ZodString;
|
|
@@ -58,7 +58,7 @@ declare const defineResponseSchema: <TBaseSchema extends WidenZodObject<z__defau
|
|
|
58
58
|
namespace: TNamespace extends undefined ? U["namespace"] : z__default.ZodLiteral<TNamespace>;
|
|
59
59
|
kind: TKind extends undefined ? U["kind"] : z__default.ZodLiteral<`${TKind}.rs`>;
|
|
60
60
|
schemaVersion: TSchemaVersion extends undefined ? U["schemaVersion"] : z__default.ZodLiteral<TSchemaVersion>;
|
|
61
|
-
}, z__default.core.$strip> : never>, "
|
|
61
|
+
}, z__default.core.$strip> : never>, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<z__default.core.output<TBaseSchema extends z__default.ZodObject<infer U extends Readonly<{
|
|
62
62
|
[k: string]: z__default.core.$ZodType<unknown, unknown, z__default.core.$ZodTypeInternals<unknown, unknown>>;
|
|
63
63
|
}>, z__default.core.$strip> ? z__default.ZodObject<Omit<U, "kind" | "namespace" | "schemaVersion"> & TFields & {
|
|
64
64
|
namespace: TNamespace extends undefined ? U["namespace"] : z__default.ZodLiteral<TNamespace>;
|
|
@@ -115,7 +115,7 @@ declare const defineTestCaseSchema: <TBaseSchema extends WidenZodObject<z.ZodObj
|
|
|
115
115
|
namespace: TNamespace extends undefined ? U["namespace"] : z.ZodLiteral<TNamespace>;
|
|
116
116
|
kind: TKind extends undefined ? U["kind"] : z.ZodLiteral<`${TKind}.tc`>;
|
|
117
117
|
schemaVersion: TSchemaVersion extends undefined ? U["schemaVersion"] : z.ZodLiteral<TSchemaVersion>;
|
|
118
|
-
}, z.core.$strip> : never>, "
|
|
118
|
+
}, z.core.$strip> : never>, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<z.core.output<TBaseSchema extends z.ZodObject<infer U extends Readonly<{
|
|
119
119
|
[k: string]: z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
120
120
|
}>, z.core.$strip> ? z.ZodObject<Omit<U, "kind" | "namespace" | "schemaVersion"> & TFields & {
|
|
121
121
|
namespace: TNamespace extends undefined ? U["namespace"] : z.ZodLiteral<TNamespace>;
|
|
@@ -188,7 +188,7 @@ declare const defineScoreSchema: <TBaseSchema extends WidenZodObject<z__default.
|
|
|
188
188
|
namespace: TNamespace extends undefined ? U["namespace"] : z__default.ZodLiteral<TNamespace>;
|
|
189
189
|
kind: TKind extends undefined ? U["kind"] : z__default.ZodLiteral<`${TKind}.sc`>;
|
|
190
190
|
schemaVersion: TSchemaVersion extends undefined ? U["schemaVersion"] : z__default.ZodLiteral<TSchemaVersion>;
|
|
191
|
-
}, z__default.core.$strip> : never>, "
|
|
191
|
+
}, z__default.core.$strip> : never>, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<z__default.core.output<TBaseSchema extends z__default.ZodObject<infer U extends Readonly<{
|
|
192
192
|
[k: string]: z__default.core.$ZodType<unknown, unknown, z__default.core.$ZodTypeInternals<unknown, unknown>>;
|
|
193
193
|
}>, z__default.core.$strip> ? z__default.ZodObject<Omit<U, "kind" | "namespace" | "schemaVersion"> & TFields & {
|
|
194
194
|
namespace: TNamespace extends undefined ? U["namespace"] : z__default.ZodLiteral<TNamespace>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { W as WidenZodObject, I as IdGenerator } from '../../index-
|
|
1
|
+
import { W as WidenZodObject, I as IdGenerator } from '../../index-Cn20kPrz.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import '../../provider-
|
|
4
|
-
import '../../abstract-
|
|
3
|
+
import '../../provider-DnEBdl1n.js';
|
|
4
|
+
import '../../abstract-BdgLjkNC.js';
|
|
5
5
|
|
|
6
6
|
declare const BaseSystemPromptSchemaV1: z.ZodObject<{
|
|
7
7
|
id: z.ZodString;
|
|
@@ -53,7 +53,7 @@ declare const defineSystemPromptSchema: <TBaseSchema extends WidenZodObject<z.Zo
|
|
|
53
53
|
namespace: TNamespace extends undefined ? U["namespace"] : z.ZodLiteral<TNamespace>;
|
|
54
54
|
kind: TKind extends undefined ? U["kind"] : z.ZodLiteral<`${TKind}.sys-prompt`>;
|
|
55
55
|
schemaVersion: TSchemaVersion extends undefined ? U["schemaVersion"] : z.ZodLiteral<TSchemaVersion>;
|
|
56
|
-
}, z.core.$strip> : never>, "
|
|
56
|
+
}, z.core.$strip> : never>, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<z.core.output<TBaseSchema extends z.ZodObject<infer U extends Readonly<{
|
|
57
57
|
[k: string]: z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
58
58
|
}>, z.core.$strip> ? z.ZodObject<Omit<U, "kind" | "namespace" | "schemaVersion"> & TFields & {
|
|
59
59
|
namespace: TNamespace extends undefined ? U["namespace"] : z.ZodLiteral<TNamespace>;
|
|
@@ -101,7 +101,7 @@ declare const SimpleSystemPromptSchemaV1: z.ZodObject<Omit<{
|
|
|
101
101
|
kind: `${string}/simple.sys-prompt`;
|
|
102
102
|
schemaVersion: 1;
|
|
103
103
|
metadata?: Record<string, unknown> | undefined;
|
|
104
|
-
}, "
|
|
104
|
+
}, "kind" | "id" | "namespace" | "schemaVersion">, generator: IdGenerator): Promise<{
|
|
105
105
|
id: string;
|
|
106
106
|
version: number;
|
|
107
107
|
content: string;
|
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
BaseSystemPromptSchemaV1,
|
|
3
3
|
SimpleSystemPromptSchemaV1,
|
|
4
4
|
defineSystemPromptSchema
|
|
5
|
-
} from "../../chunk-
|
|
6
|
-
import "../../chunk-OQE6TQXZ.js";
|
|
5
|
+
} from "../../chunk-ZXTQJFGL.js";
|
|
7
6
|
import "../../chunk-UHHHSYVE.js";
|
|
7
|
+
import "../../chunk-OQE6TQXZ.js";
|
|
8
8
|
import "../../chunk-NUEOE3K5.js";
|
|
9
9
|
import "../../chunk-PZ5AY32C.js";
|
|
10
10
|
export {
|
package/dist/scorers/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { A as AbstractScorer } from '../abstract-
|
|
2
|
-
export { B as BaseScorerResult } from '../abstract-
|
|
3
|
-
export { b as LLMAsAJudgeCriterion, c as LLMAsAJudgeScoreParams, L as LLMAsAJudgeScorer, a as MCQScorer, M as MCQScorerParams } from '../llm-judge-
|
|
4
|
-
import '../llm-
|
|
5
|
-
import '../provider-
|
|
1
|
+
import { A as AbstractScorer } from '../abstract-BdgLjkNC.js';
|
|
2
|
+
export { B as BaseScorerResult } from '../abstract-BdgLjkNC.js';
|
|
3
|
+
export { b as LLMAsAJudgeCriterion, c as LLMAsAJudgeScoreParams, L as LLMAsAJudgeScorer, a as MCQScorer, M as MCQScorerParams } from '../llm-judge-BuF80-5-.js';
|
|
4
|
+
import '../llm-8ecJmwKJ.js';
|
|
5
|
+
import '../provider-DnEBdl1n.js';
|
|
6
6
|
import 'openai/resources/shared';
|
|
7
7
|
import 'openai/resources/chat/completions';
|
|
8
8
|
import '../rate-limiter-CSmVIRsM.js';
|
|
@@ -48,11 +48,15 @@ type RegexScorerParams = {
|
|
|
48
48
|
*/
|
|
49
49
|
allowPartialScoring?: boolean;
|
|
50
50
|
};
|
|
51
|
+
declare const RegexScorer_base: (new () => AbstractScorer & {
|
|
52
|
+
readonly kind: "peerbench.ai/regex";
|
|
53
|
+
}) & {
|
|
54
|
+
readonly kind: "peerbench.ai/regex";
|
|
55
|
+
};
|
|
51
56
|
/**
|
|
52
57
|
* Generic Regex scorer. It scores the given input against a set of regex patterns.
|
|
53
58
|
*/
|
|
54
|
-
declare class RegexScorer extends
|
|
55
|
-
readonly kind: "peerbench.ai/regex";
|
|
59
|
+
declare class RegexScorer extends RegexScorer_base {
|
|
56
60
|
score(params: RegexScorerParams): Promise<{
|
|
57
61
|
value: number;
|
|
58
62
|
extractedAnswers: {
|
package/dist/scorers/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/providers/abstract/provider.ts","../src/providers/abstract/llm.ts","../src/providers/mastra.ts","../src/providers/openai.ts","../src/providers/openrouter.ts"],"sourcesContent":["export abstract class AbstractProvider {\n abstract readonly kind: string;\n}\n\nexport type ProviderResponse<TData = unknown> = {\n startedAt: number;\n completedAt: number;\n data: TData;\n};\n","import { AbstractProvider, ProviderResponse } from \"./provider\";\nimport {\n ResponseFormatJSONObject,\n ResponseFormatJSONSchema,\n ResponseFormatText,\n} from \"openai/resources/shared\";\nimport { ChatCompletionMessageParam } from \"openai/resources/chat/completions\";\n\nexport abstract class AbstractLLMProvider extends AbstractProvider {\n abstract forward(args: LLMProviderForwardArgs): Promise<ChatResponse>;\n}\n\nexport type LLMProviderForwardArgs = {\n messages: ChatCompletionMessageParam[];\n model: string;\n abortSignal?: AbortSignal;\n temperature?: number;\n responseFormat?:\n | ResponseFormatText\n | ResponseFormatJSONSchema\n | ResponseFormatJSONObject;\n};\n\nexport type ChatResponse = ProviderResponse<string> & {\n inputTokensUsed?: number;\n outputTokensUsed?: number;\n inputCost?: string;\n outputCost?: string;\n\n metadata?: Record<string, unknown>;\n};\n","import {\n AbstractLLMProvider,\n type ChatResponse,\n type LLMProviderForwardArgs,\n} from \"./abstract/llm\";\nimport { MastraClient, type GetAgentResponse } from \"@mastra/client-js\";\n\nexport class MastraProvider extends AbstractLLMProvider {\n override readonly kind = \"mastra\";\n\n private readonly endpoint: string;\n private readonly authToken?: string;\n private client: MastraClient;\n private memory?: AgentMemoryOption;\n\n constructor(params: {\n endpoint: string;\n authToken?: string;\n memory?: AgentMemoryOption;\n }) {\n super();\n this.endpoint = params.endpoint;\n this.authToken = params.authToken;\n this.client = new MastraClient({\n baseUrl: this.endpoint,\n headers: this.authToken\n ? {\n Authorization: `Bearer ${this.authToken}`,\n }\n : undefined,\n });\n this.memory = params.memory;\n }\n\n override async forward(\n args: LLMProviderForwardArgs & {\n memory?: AgentMemoryOption;\n\n /**\n * The model that will be used as the brain for the agent.\n */\n modelName?: string\n }\n ): Promise<ChatResponse> {\n const apiMessages = args.messages\n .filter((m) => m.role === \"user\" || m.role === \"assistant\")\n .map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content: String((m as any).content ?? \"\"),\n }));\n\n const agent = this.client.getAgent(args.model);\n\n const startedAt = Date.now();\n const response = await agent.generate(\n {\n messages: apiMessages,\n runtimeContext: {\n \"model-id\": args.modelName,\n },\n },\n { memory: args.memory ?? this.memory }\n );\n\n return {\n data: response.text,\n startedAt,\n completedAt: Date.now(),\n };\n }\n\n async getAgentInfo(args: {\n agentId: string;\n runtimeContext?: MastraRuntimeContext;\n }) {\n return await this.client\n .getAgent(args.agentId)\n .details(args.runtimeContext);\n }\n\n async getAgents(args?: {\n runtimeContext?: MastraRuntimeContext;\n partial?: boolean;\n }): Promise<Record<string, GetAgentResponse>> {\n return this.client.getAgents(args?.runtimeContext, args?.partial);\n }\n}\n\n// NOTE: Mastra client does not export these types\nexport type AgentMemoryOption = Parameters<\n Parameters<MastraClient[\"getAgent\"]>[\"0\"] extends string\n ? ReturnType<MastraClient[\"getAgent\"]>[\"generate\"]\n : never\n>[0] extends { memory?: infer M }\n ? M\n : never;\n\ntype MastraRuntimeContext = Parameters<\n Parameters<MastraClient[\"getAgent\"]>[\"0\"] extends string\n ? ReturnType<MastraClient[\"getAgent\"]>[\"generate\"]\n : never\n>[0] extends { runtimeContext?: infer R }\n ? R\n : never;\n","import { RateLimiter } from \"@/utils\";\nimport { ChatCompletionMessageParam } from \"openai/resources/chat/completions\";\nimport {\n ResponseFormatJSONObject,\n ResponseFormatJSONSchema,\n ResponseFormatText,\n} from \"openai/resources/shared\";\nimport OpenAI, { APIError } from \"openai\";\nimport { AbstractLLMProvider, ChatResponse } from \"./abstract/llm\";\nimport { PEERBENCH_NAMESPACE } from \"@/constants\";\n\nexport class OpenAIProvider extends AbstractLLMProvider {\n override readonly kind = `${PEERBENCH_NAMESPACE}/llm/openai` as const;\n\n private client: OpenAI;\n private rateLimiter: RateLimiter;\n private maxRetries: number;\n\n constructor(config: {\n apiKey: string;\n baseURL: string;\n maxRetries?: number;\n timeout?: number;\n rateLimiter?: RateLimiter;\n }) {\n super();\n this.maxRetries = config.maxRetries ?? 3;\n this.rateLimiter =\n config.rateLimiter ??\n new RateLimiter({\n maxWeight: 20,\n timeWindow: 3_000,\n });\n\n this.client = new OpenAI({\n baseURL: config.baseURL,\n apiKey: config.apiKey,\n timeout: config.timeout,\n dangerouslyAllowBrowser: true,\n });\n }\n\n async forward(args: {\n messages: ChatCompletionMessageParam[];\n model: string;\n abortSignal?: AbortSignal;\n temperature?: number;\n responseFormat?:\n | ResponseFormatText\n | ResponseFormatJSONSchema\n | ResponseFormatJSONObject;\n }): Promise<ChatResponse> {\n let retryCount = this.maxRetries;\n while (retryCount > 0) {\n let startedAt: Date = new Date();\n\n try {\n const response = await this.rateLimiter.execute(\n async () => {\n // Capture the start time of the request\n startedAt = new Date();\n return await this.client.chat.completions.create(\n {\n model: args.model,\n messages: args.messages,\n temperature: args.temperature,\n response_format: args.responseFormat,\n },\n // Signal for request\n { signal: args.abortSignal }\n );\n },\n // Signal for rate limiting\n { signal: args.abortSignal }\n );\n\n if (\"error\" in response) {\n const err = response.error as any;\n throw new Error(\n `${err.message} - Code ${err.code} - ${JSON.stringify(err)}`\n );\n }\n\n if (!response?.choices?.[0]?.message?.content) {\n throw new Error(\"No content returned from the model\");\n }\n\n return {\n data: response.choices[0].message.content,\n\n inputTokensUsed: response?.usage?.prompt_tokens,\n outputTokensUsed: response?.usage?.completion_tokens,\n\n startedAt: startedAt.getTime(),\n completedAt: Date.now(),\n };\n } catch (err) {\n if (err instanceof APIError && err.status === 401) {\n throw new Error(`Invalid credentials provided`, { cause: err });\n }\n\n retryCount--;\n\n // More likely an empty HTTP response returned by the Provider\n // and it couldn't be parsed as JSON by the OpenAI SDK. We need to retry the request\n // More info can be found in the following links:\n // https://www.reddit.com/r/SillyTavernAI/comments/1ik95vr/deepseek_r1_on_openrouter_returning_blank_messages/\n // https://github.com/cline/cline/issues/60\n if (err instanceof SyntaxError) {\n console.debug(err);\n continue;\n }\n\n // If it was another error, just continue until we run out of retries\n if (retryCount !== 0) {\n continue;\n }\n\n throw new Error(\n `Failed to forward prompt to the model: ${err instanceof Error ? err.message : err}`,\n { cause: err }\n );\n }\n }\n\n throw new Error(\n `Failed to forward prompt to the model: Max retries reached`,\n { cause: new Error(\"Max retries reached\") }\n );\n }\n}\n","import {\n AbstractLLMProvider,\n ChatResponse,\n LLMProviderForwardArgs,\n} from \"./abstract/llm\";\nimport { RateLimiter } from \"@/utils\";\nimport { OpenAIProvider } from \"./openai\";\nimport { PEERBENCH_NAMESPACE } from \"@/constants\";\nimport Decimal from \"decimal.js\";\nimport axios from \"axios\";\n\nconst baseURL = \"https://openrouter.ai/api/v1\";\nconst MODELS_CACHE_TTL = 1000 * 60 * 60 * 24; // 24 hours\n\nexport class OpenRouterProvider extends AbstractLLMProvider {\n override readonly kind = `${PEERBENCH_NAMESPACE}/llm/openrouter.ai` as const;\n\n private models: ModelsResponse | undefined = undefined;\n private modelsCachePromise: Promise<ModelsResponse | undefined> =\n Promise.resolve(undefined);\n private modelsUpdatedAt = 0;\n private openAIProvider: OpenAIProvider;\n\n constructor(config: {\n apiKey: string;\n maxRetries?: number;\n timeout?: number;\n rateLimiter?: RateLimiter;\n }) {\n super();\n this.openAIProvider = new OpenAIProvider({\n baseURL,\n apiKey: config.apiKey,\n maxRetries: config.maxRetries,\n timeout: config.timeout,\n rateLimiter: config.rateLimiter,\n });\n }\n\n override async forward(args: LLMProviderForwardArgs): Promise<ChatResponse> {\n // Update models cache concurrently (non-blocking)\n const [response] = await Promise.all([\n this.openAIProvider.forward(args),\n this.updateModelsCache().catch(() => {\n // Silently fail if cache update fails so we won't have cost info in the result\n }),\n ]);\n\n // Get the model info from the cache\n const modelInfo = this.models?.data.find((m) => m.id === args.model);\n let inputCost: string | undefined = undefined;\n let outputCost: string | undefined = undefined;\n\n if (modelInfo !== undefined) {\n // Use Decimal.js for more accurate calculation\n if (response.inputTokensUsed !== undefined) {\n inputCost = new Decimal(modelInfo.pricing.prompt)\n .mul(response.inputTokensUsed)\n .toFixed(10);\n }\n if (response.outputTokensUsed !== undefined) {\n outputCost = new Decimal(modelInfo.pricing.completion)\n .mul(response.outputTokensUsed)\n .toFixed(10);\n }\n }\n\n return {\n ...response,\n inputCost,\n outputCost,\n };\n }\n\n /**\n * Updates the cache that holds information about OpenRouter models\n * including pricing information. It will be valid for 24 hours as\n * long as the instance of this Provider object is alive.\n */\n private async updateModelsCache() {\n // Chain each update method call to the promise.\n // This approach prevents race conditions between multiple calls.\n // Since each call is chained to the end of the previous one,\n // each promise makes a request only if the models cache is not updated\n // in the last call. Otherwise it simply resolves to the cached value.\n this.modelsCachePromise = this.modelsCachePromise\n .then(async () => {\n if (\n // The data presented in the cache\n this.models !== undefined &&\n // The cache is still valid\n Date.now() - this.modelsUpdatedAt < MODELS_CACHE_TTL\n ) {\n return this.models;\n }\n\n // If the cache is not valid, update it\n return axios\n .get<ModelsResponse>(`${baseURL}/models`)\n .then((res) => res.data)\n .then((data) => {\n // Only get the models that supports text input and output\n data = {\n data: data.data.filter(\n (m) =>\n m.architecture.input_modalities.includes(\"text\") &&\n m.architecture.output_modalities.includes(\"text\") &&\n // These models are \"fast apply model\" and don't support multi turn conversations so don't include them\n ![\n \"morph/morph-v3-large\",\n \"morph/morph-v3-fast\",\n \"relace/relace-apply-3\",\n ].includes(m.id)\n ),\n };\n\n this.models = data;\n this.modelsUpdatedAt = Date.now();\n\n return data;\n });\n })\n .catch(() => undefined);\n\n // Wait for the promise chain to resolve\n await this.modelsCachePromise;\n }\n}\n\ntype PutModality = \"text\" | \"image\" | \"file\" | \"audio\";\ntype Modality = \"text->text\" | \"text+image->text\" | \"text+image->text+image\";\ntype ModelsResponse = {\n data: {\n readonly id: string;\n readonly canonical_slug: string;\n readonly hugging_face_id: null | string;\n readonly name: string;\n readonly created: number;\n readonly description: string;\n readonly context_length: number;\n readonly architecture: {\n readonly modality: Modality;\n readonly input_modalities: PutModality[];\n readonly output_modalities: PutModality[];\n readonly instruct_type: null | string;\n };\n readonly pricing: {\n readonly prompt: string;\n readonly completion: string;\n readonly request?: string;\n readonly image?: string;\n readonly web_search?: string;\n readonly internal_reasoning?: string;\n readonly input_cache_read?: string;\n readonly input_cache_write?: string;\n readonly audio?: string;\n };\n }[];\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/scorers/abstract.ts","../src/scorers/regex.ts","../src/scorers/mcq.ts","../src/scorers/llm-judge.ts"],"sourcesContent":["export abstract class AbstractScorer {\n abstract readonly kind: string;\n\n abstract score(params: any): Promise<BaseScorerResult | null>;\n}\n\nexport type BaseScorerResult = {\n value: number;\n explanation?: string;\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n};\n","import { PEERBENCH_NAMESPACE } from \"@/constants\";\nimport { AbstractScorer, BaseScorerResult } from \"./abstract\";\n\nexport type RegexPattern = {\n /**\n * The regex pattern to match against the response\n */\n regex: RegExp;\n\n /**\n * The index of the capture group to extract (1-based, like match[1])\n * If not provided, defaults to 1 (first capture group)\n */\n captureGroupIndex?: number;\n\n /**\n * Optional function to transform the extracted value before validation\n */\n transform?: (value: string) => string | undefined;\n};\n\nexport type RegexScorerParams = {\n /**\n * The input text to score\n */\n input: string;\n\n /**\n * Array of regex patterns to try (in order, first match wins)\n */\n patterns: RegexPattern[];\n\n /**\n * Expected value(s) to match against. Can be a record of expected values for named groups, or a validation function\n */\n expectedValue:\n | Record<string, string>\n | ((groupName: string, match: string) => boolean);\n\n /**\n * Optional: Which match to use when multiple matches are found\n * Defaults to \"last\" (uses the last match found)\n */\n matchPreference?: \"first\" | \"last\";\n\n /**\n * Optional: If true, allows partial scoring based on how many groups match\n * For example, if 2 groups are expected and only 1 matches, score would be 0.5\n * Defaults to false (all-or-nothing scoring)\n */\n allowPartialScoring?: boolean;\n};\n\n/**\n * Generic Regex scorer. It scores the given input against a set of regex patterns.\n */\nexport class RegexScorer extends AbstractScorer {\n override readonly kind = `${PEERBENCH_NAMESPACE}/regex` as const;\n\n override async score(params: RegexScorerParams) {\n // Collect all named group names from all patterns\n const allGroupNames = new Set<string>();\n for (const pattern of params.patterns) {\n const regexSource = pattern.regex.source;\n const namedGroupRegex = /\\(\\?<(\\w+)>/g;\n\n while (true) {\n const match = namedGroupRegex.exec(regexSource);\n if (match === null) {\n break;\n }\n\n if (match[1]) {\n allGroupNames.add(match[1]);\n }\n }\n }\n\n // Initialize result object with all group names set to null (aka not found yet)\n const extractedValues: Record<string, string | null> = {};\n for (const groupName of allGroupNames) {\n extractedValues[groupName] = null;\n }\n\n // Try regex patterns in order, stop at first successful match\n const matchPreference = params.matchPreference ?? \"last\";\n for (const pattern of params.patterns) {\n const matches = Array.from(params.input.matchAll(pattern.regex));\n const match = matchPreference === \"first\" ? matches[0] : matches.at(-1);\n\n if (match && match.groups) {\n // Extract all named groups from this match\n let hasExtractedValue = false;\n for (const [groupName, groupValue] of Object.entries(match.groups)) {\n if (groupValue !== undefined) {\n let value = groupValue;\n\n // Apply transformation if provided\n if (pattern.transform) {\n const transformed = pattern.transform(value);\n if (transformed === undefined) {\n continue;\n }\n value = transformed;\n }\n\n extractedValues[groupName] = value;\n hasExtractedValue = true;\n }\n }\n // If we extracted at least one value, stop processing further patterns\n if (hasExtractedValue) {\n break;\n }\n } else if (match) {\n // Fallback to captureGroupIndex if no named groups\n // For unnamed groups, we can't add to extractedValues by name\n // They are only used for scoring if no named groups are found\n const captureGroupIndex = pattern.captureGroupIndex ?? 1;\n const extractedValue = match[captureGroupIndex];\n\n if (extractedValue !== undefined) {\n // Apply transformation if provided\n if (pattern.transform) {\n const transformed = pattern.transform(extractedValue);\n if (transformed === undefined) {\n continue;\n }\n // For unnamed groups, we can't store in extractedValues\n // but we can use it for scoring if no named groups were found\n }\n // If we have an extracted value (even if unnamed), stop processing\n // Note: This is a fallback case, so we break here too\n break;\n }\n }\n }\n\n // Calculate score based on matched value\n const allowPartial = params.allowPartialScoring ?? false;\n let score = 0;\n\n if (typeof params.expectedValue === \"function\") {\n // To get proper type inference, cast it using \"as\"\n const validator = params.expectedValue as typeof params.expectedValue;\n const extractedEntries = Object.entries(extractedValues).filter(\n ([, value]) => value !== null\n );\n\n // If no values were extracted, score is 0\n if (extractedEntries.length === 0) {\n score = 0;\n } else {\n if (allowPartial) {\n // Count how many extracted values pass validation\n const passingCount = extractedEntries.filter(\n ([groupName, extractedValue]) =>\n validator(groupName, extractedValue as string)\n ).length;\n score = passingCount / extractedEntries.length;\n } else {\n // All extracted values must pass validation\n const allMatch = extractedEntries.every(\n ([groupName, extractedValue]) =>\n validator(groupName, extractedValue as string)\n );\n score = allMatch ? 1 : 0;\n }\n }\n } else {\n const expectedEntries = Object.entries(params.expectedValue);\n const totalExpected = expectedEntries.length;\n\n if (allowPartial) {\n // Count how many expected values match their extracted values\n const matchingCount = expectedEntries.filter(([key, expectedValue]) => {\n const extractedValue = extractedValues[key];\n return extractedValue !== null && extractedValue === expectedValue;\n }).length;\n score = totalExpected > 0 ? matchingCount / totalExpected : 0;\n } else {\n // All expected values must match\n const allMatch = expectedEntries.every(([key, expectedValue]) => {\n const extractedValue = extractedValues[key];\n return extractedValue !== null && extractedValue === expectedValue;\n });\n score = allMatch ? 1 : 0;\n }\n }\n\n return {\n value: score,\n extractedAnswers: Object.fromEntries(\n Object.entries(extractedValues).filter(\n (entry): entry is [string, string] => entry[1] !== null\n )\n ),\n } satisfies BaseScorerResult;\n }\n}\n","import { parseResponseAsJSON } from \"@/utils\";\nimport { AbstractScorer, BaseScorerResult } from \"./abstract\";\nimport { RegexScorer, RegexPattern, RegexScorerParams } from \"./regex\";\nimport { PEERBENCH_NAMESPACE } from \"@/constants\";\n\nexport type MCQScorerParams = {\n response: string;\n choices: Record<string, string>;\n correctAnswers: string[];\n};\n\nexport class MCQScorer extends AbstractScorer {\n override readonly kind = `${PEERBENCH_NAMESPACE}/mcq` as const;\n private regexScorer = new RegexScorer();\n\n async score(params: MCQScorerParams): Promise<\n BaseScorerResult & {\n extractedAnswers: string[];\n }\n > {\n const { response, choices, correctAnswers } = params;\n const normalizedCorrectAnswers = correctAnswers.map((ca) =>\n ca.toUpperCase()\n );\n\n // Direct answer comparison\n const normalizedResponse = response.trim().toUpperCase();\n if (normalizedCorrectAnswers.includes(normalizedResponse)) {\n return {\n value: 1,\n extractedAnswers: [normalizedResponse],\n };\n }\n\n // Try to parse the response as JSON (original behavior: returns early if parsed)\n const json = parseResponseAsJSON<{ answer: string }>(response);\n if (json !== undefined && typeof json === \"object\") {\n const extractedAnswer =\n json.answer !== undefined ? getFirstLetter(json.answer) : undefined;\n\n if (extractedAnswer !== undefined) {\n const normalizedExtracted = extractedAnswer.trim().toUpperCase();\n if (normalizedCorrectAnswers.includes(normalizedExtracted)) {\n return {\n value: 1,\n extractedAnswers: [extractedAnswer],\n };\n }\n\n // Response parsed as JSON but does not represent the correct answer\n return {\n value: 0,\n extractedAnswers:\n json.answer === undefined\n ? []\n : [extractedAnswer ?? String(json.answer)],\n };\n }\n }\n\n // Build patterns for all correctAnswers\n const patterns: RegexPattern[] = [];\n for (const answer of Object.values(params.choices)) {\n const answerPatterns = this.buildPatternsForAnswer(answer);\n patterns.push(...answerPatterns);\n }\n\n // Create validation function that handles choices matching\n // New RegexScorer API expects (groupName: string, match: string) => boolean\n const validateAnswer = (groupName: string, extracted: string): boolean => {\n const normalizedExtracted = extracted.trim().toUpperCase();\n\n // Check if extracted value is in correctAnswers\n if (normalizedCorrectAnswers.includes(normalizedExtracted)) {\n return true;\n }\n\n // Check if extracted text matches any choice value, and that choice key is correct\n // Note: When transform uppercases the value, we need to compare case-insensitively\n const answerOption = Object.entries(choices).find(\n ([, value]) =>\n value.trim().toUpperCase() === extracted.trim().toUpperCase()\n );\n\n if (\n answerOption &&\n normalizedCorrectAnswers.includes(answerOption[0].toUpperCase())\n ) {\n return true;\n }\n\n return false;\n };\n\n // Build regex scorer params\n const regexParams: RegexScorerParams = {\n input: response,\n patterns,\n expectedValue: validateAnswer,\n matchPreference: \"last\",\n };\n\n // Call regex scorer\n const result = await this.regexScorer.score(regexParams);\n\n return {\n value: result.value,\n extractedAnswers: Object.entries(result.extractedAnswers).map(\n ([, value]) => value\n ),\n };\n }\n\n private buildPatternsForAnswer(answerText: string): RegexPattern[] {\n const escapedAnswer = escapeRegex(answerText);\n\n return [\n {\n // \"<!NO ANSWER!>\" - This pattern matches but has no capture group, so it won't extract anything\n regex: /<!NO ANSWER!>/g,\n },\n // Specific patterns for the full answer text (checked first)\n {\n // \"Answer is $\\boxed{answer text}$\"\n regex: new RegExp(\n `[Aa]nswer is \\\\$\\\\\\\\boxed\\\\{(?<answer>${escapedAnswer})\\\\}\\\\$`,\n \"g\"\n ),\n transform: (value: string) => value.toUpperCase(),\n },\n {\n // \"Answer is answer text\"\n regex: new RegExp(`[Aa]nswer is\\\\s+(?<answer>${escapedAnswer})`, \"g\"),\n transform: (value: string) => value.toUpperCase(),\n },\n {\n // \"Answer is **answer text**\"\n regex: new RegExp(\n `[Aa]nswer is\\\\s+\\\\**(?<answer>${escapedAnswer})\\\\**`,\n \"g\"\n ),\n transform: (value: string) => value.toUpperCase(),\n },\n // Generic patterns (checked after specific patterns)\n {\n // \"Answer is $\\boxed{A}$.\"\n regex: /[Aa]nswer is \\$\\\\boxed\\{(?<answer>[A-Z])\\}\\$\\.?/g,\n },\n {\n // \"Answer is A\" - match single letter only when it's a complete standalone answer.\n // Pattern matches: \"Answer is\" + whitespace + single letter + end or punctuation\n regex: /[Aa]nswer is\\s+(?<answer>[A-Z])(?=\\s*$|[.,;:!?])/g,\n },\n {\n // \"Answer is **A**\"\n regex: /[Aa]nswer is\\s+\\**(?<answer>[A-Z])\\**/g,\n },\n {\n // \"A: answer text\"\n regex: /(?<answer>[A-Z]):.+/g,\n },\n {\n // \"A) answer text\"\n regex: /(?<answer>[A-Z])\\)\\s*.+/g,\n },\n {\n // \"A)\"\n regex: /(?<answer>[A-Z])\\)/g,\n },\n ];\n }\n}\n\nfunction getFirstLetter(text: string): string | undefined {\n const match = text.match(/[A-Za-z]/);\n return match ? match[0].toUpperCase() : undefined;\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { AbstractLLMProvider } from \"@/providers/abstract/llm\";\nimport { parseResponseAsJSON } from \"@/utils\";\nimport { RateLimiter } from \"@/utils/rate-limiter\";\nimport { AbstractScorer, BaseScorerResult } from \"./abstract\";\nimport { PEERBENCH_NAMESPACE } from \"@/constants\";\nimport z from \"zod\";\n\nexport class LLMAsAJudgeScorer extends AbstractScorer {\n override readonly kind = `${PEERBENCH_NAMESPACE}/llm-as-a-judge` as const;\n\n private provider: AbstractLLMProvider;\n\n constructor(config: {\n provider: AbstractLLMProvider;\n rateLimiter?: RateLimiter;\n }) {\n super();\n this.provider = config.provider;\n }\n\n override async score<T extends z.ZodRawShape>(\n params: LLMAsAJudgeScoreParams & { fieldsToExtract: T }\n ): Promise<ScorerResultWithExtractedFields<T> | null>;\n override async score(\n params: LLMAsAJudgeScoreParams & { fieldsToExtract?: never }\n ): Promise<ScorerResultWithoutExtractedFields | null>;\n override async score<T extends z.ZodRawShape>(\n params: LLMAsAJudgeScoreParams & { fieldsToExtract?: T }\n ): Promise<\n | ScorerResultWithoutExtractedFields\n | ScorerResultWithExtractedFields<T>\n | null\n > {\n const criteria = normalizeWeights(params.criteria);\n const systemPrompt = [];\n const responseSchema = z.object({\n results: z\n .array(\n z.object({\n id: z.string().describe(\"The id of the criterion\"),\n score: z.number().describe(\"The score of the criterion\"),\n explanation: z\n .string()\n .describe(\"The explanation of the criterion\"),\n })\n )\n .describe(\"The results of the evaluation per criterion\"),\n\n explanation: z\n .string()\n .describe(\n `The overall explanation for the score (less than ${params.maxExplanationLength ?? 200} characters)`\n ),\n\n ...(params.fieldsToExtract ?? {}),\n });\n\n if (params.systemPrompt) {\n systemPrompt.push(params.systemPrompt);\n } else {\n systemPrompt.push(\"You are a strict, fair evaluation judge.\");\n systemPrompt.push(\"Only use information from the rubric\");\n }\n\n systemPrompt.push(\n \"For each criterion return an integer score within the provided scale and a very brief justification (less than 2 sentences).\"\n );\n systemPrompt.push(\n [\n `Rubric: ${params.rubric}`,\n `Criteria:`,\n ...criteria.map(\n (criterion) =>\n `- ${criterion.id}: ${criterion.description} (weight: ${criterion.weight}, scale: ${criterion.scale?.min ?? 0}..${criterion.scale?.max ?? 5})`\n ),\n ].join(\"\\n\")\n );\n\n const responseJSONSchema = responseSchema.toJSONSchema();\n systemPrompt.push(\n `Reply back with the following JSON schema (strict):\\n${JSON.stringify(responseJSONSchema, null, 2)}\\n`\n );\n\n const userPrompt = [`Answer: ${params.response}`];\n const providerResponse = await this.provider.forward({\n messages: [\n {\n role: \"system\",\n content: systemPrompt.join(\"\\n\"),\n },\n {\n role: \"user\",\n content: userPrompt.join(\"\\n\"),\n },\n ],\n model: params.model,\n responseFormat: {\n type: \"json_schema\",\n json_schema: {\n name: \"judgeResult\",\n schema: responseJSONSchema,\n },\n },\n });\n\n const parsed = responseSchema.parse(\n parseResponseAsJSON(providerResponse.data)\n );\n\n const { explanation, results, ...extractedFields } = parsed;\n\n return {\n explanation,\n results,\n value: computeOverallScore(results, criteria),\n extractedFields: extractedFields as z.infer<z.ZodObject<T>>,\n\n provider: this.provider.kind,\n inputTokensUsed: providerResponse.inputTokensUsed,\n outputTokensUsed: providerResponse.outputTokensUsed,\n inputCost: providerResponse.inputCost,\n outputCost: providerResponse.outputCost,\n };\n }\n}\n\nexport type LLMAsAJudgeCriterion = {\n id: string;\n description: string;\n weight: number;\n scale?: {\n min: number;\n max: number;\n };\n};\n\nexport type LLMAsAJudgeScoreParams = {\n model: string;\n response: string;\n rubric: string;\n criteria: LLMAsAJudgeCriterion[];\n\n systemPrompt?: string;\n maxExplanationLength?: number;\n};\n\ntype ScorerResultWithoutExtractedFields = BaseScorerResult & {\n results: {\n id: string;\n score: number;\n explanation: string;\n }[];\n\n provider: string;\n inputTokensUsed?: number;\n outputTokensUsed?: number;\n inputCost?: string;\n outputCost?: string;\n};\n\ntype ScorerResultWithExtractedFields<T extends z.ZodRawShape> =\n ScorerResultWithoutExtractedFields & {\n extractedFields: z.infer<z.ZodObject<T>>;\n };\n\nfunction normalizeWeights(\n criteria: LLMAsAJudgeCriterion[]\n): LLMAsAJudgeCriterion[] {\n const sum = criteria.reduce((a, c) => a + (c.weight ?? 1), 0) || 1;\n return criteria.map((c) => ({ ...c, weight: (c.weight ?? 1) / sum }));\n}\n\nfunction computeOverallScore(\n results: ScorerResultWithoutExtractedFields[\"results\"],\n criteria: LLMAsAJudgeCriterion[]\n): number {\n let total = 0;\n for (const pc of results) {\n const criterion = criteria.find((c) => c.id === pc.id);\n const min = criterion?.scale?.min ?? 0;\n const max = criterion?.scale?.max ?? 5;\n const weight = criterion?.weight ?? 0;\n\n const score = Number(pc.score);\n if (!Number.isFinite(score)) continue;\n\n const clamped = Math.max(min, Math.min(max, score));\n const normalized01 = max === min ? 0 : (clamped - min) / (max - min);\n total += normalized01 * weight;\n }\n return Math.max(0, Math.min(1, total));\n}\n"],"mappings":"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","names":[]}
|
|
File without changes
|