Skip to content

Commit c1e4960

Browse files
committed
SDK update merge from dev
1 parent 7d3a2c8 commit c1e4960

68 files changed

Lines changed: 3193 additions & 2506 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

peerBenchJS/packages/sdk/.DS_Store

8 KB
Binary file not shown.

peerBenchJS/packages/sdk/docs/implementing-a-scorer.md

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,72 @@ Scorers are responsible for taking a Response that is made for a Prompt and givi
1818

1919
### Abstract Methods
2020

21-
**`scoreOne(response: PromptResponse, options?: Record<string, any>): Promise<number | undefined>`**
21+
**`scoreOne(response: PromptResponse, options?: Record<string, any>): MaybePromise<PromptScore | undefined>`**
2222

2323
- This is the main scoring method you must implement
2424
- Takes a `PromptResponse` object containing both the Prompt and Response
2525
- Optional `options` parameter for configurable scoring behavior
26-
- Must return a number between 0 and 1, or `undefined` if scoring fails
27-
- The number represents the score: 1.0 = perfect, 0.0 = completely wrong
26+
- Must return a `PromptScore` object or `undefined` if scoring fails
27+
- The `PromptScore` object includes the original response data plus a `score` field (number between 0 and 1)
28+
- The score represents: 1.0 = perfect, 0.0 = completely wrong
29+
- The `PromptScore` structure extends `PromptResponse` with additional fields:
30+
- `score?: number` - The calculated score (0-1)
31+
- `metadata?: Record<string, any>` - Additional metadata about the scoring
2832

29-
**`canScore(response: PromptResponse): Promise<boolean>`**
33+
**`canScore(response: PromptResponse): MaybePromise<boolean>`**
3034

3135
- This method determines if your Scorer can handle a specific Response
3236
- Returns `true` if your Scorer implementation is eligible to score the Response and `false` if it isn't.
37+
- `MaybePromise<T>` means the method can return either `T` or `Promise<T>` (synchronous or asynchronous)
3338

3439
Here's a very simple scorer implementation that demonstrates the basic structure:
3540

3641
```typescript
3742
import { AbstractScorer } from "@/scorers/abstract/abstract-scorer";
38-
import { PromptResponse } from "@/types";
43+
import { PromptResponse, PromptScore } from "@/types";
3944

4045
export class SimpleExactMatchScorer extends AbstractScorer {
4146
readonly identifier = "simple-exact-match";
4247

4348
async scoreOne(
4449
response: PromptResponse,
4550
options?: Record<string, any>
46-
): Promise<number | undefined> {
51+
): Promise<PromptScore | undefined> {
52+
if (!(await this.canScore(response))) {
53+
return undefined;
54+
}
55+
4756
// Extract the correct answer from the prompt
4857
const correctAnswer = response.prompt.answer;
4958

5059
// Get the model's response
51-
const modelResponse = response.response.content;
60+
const modelResponse = response.data;
5261

5362
// Simple exact match scoring (case-insensitive)
5463
const isCorrect =
55-
correctAnswer.toLowerCase().trim() === modelResponse.toLowerCase().trim();
56-
57-
// Return 1.0 for correct answers, 0.0 for incorrect
58-
return isCorrect ? 1.0 : 0.0;
64+
correctAnswer?.toLowerCase().trim() ===
65+
modelResponse?.toLowerCase().trim();
66+
67+
// Calculate score: 1.0 for correct answers, 0.0 for incorrect
68+
const score = isCorrect ? 1.0 : 0.0;
69+
70+
// Return PromptScore object with the original response data plus score and metadata
71+
return {
72+
...response,
73+
score,
74+
metadata: {
75+
scorerIdentifier: this.identifier,
76+
isExactMatch: isCorrect,
77+
},
78+
} as PromptScore;
5979
}
6080

6181
async canScore(response: PromptResponse): Promise<boolean> {
62-
// This scorer can handle any response that has content
82+
// This scorer can handle any response that has data and a prompt with an answer
6383
return (
64-
response.response.content && typeof response.response.content === "string"
84+
response.data !== undefined &&
85+
response.prompt !== undefined &&
86+
response.prompt.answer !== undefined
6587
);
6688
}
6789
}
@@ -105,7 +127,7 @@ async function main() {
105127
metadata: {},
106128
scorers: ["simple-exact-match"],
107129
},
108-
data: "A", // Correct answer
130+
data: "Paris", // Correct answer
109131
provider: "mock",
110132
modelId: "mock-model",
111133
modelName: "Mock Model",
@@ -124,7 +146,7 @@ async function main() {
124146

125147
const wrongResponse = {
126148
...mockResponse,
127-
data: "C", // Wrong answer
149+
data: "London", // Wrong answer
128150
};
129151

130152
// Test if the Scorer can handle these responses
@@ -135,13 +157,17 @@ async function main() {
135157
console.log("Can score wrong response:", canScoreWrong);
136158

137159
if (canScoreCorrect) {
138-
const correctScore = await scorer.scoreOne(mockResponse);
139-
console.log("Correct answer score:", correctScore);
160+
const correctScoreResult = await scorer.scoreOne(mockResponse);
161+
console.log("Correct answer score result:", correctScoreResult);
162+
console.log("Score:", correctScoreResult?.score);
163+
console.log("Metadata:", correctScoreResult?.metadata);
140164
}
141165

142166
if (canScoreWrong) {
143-
const wrongScore = await scorer.scoreOne(wrongResponse);
144-
console.log("Wrong answer score:", wrongScore);
167+
const wrongScoreResult = await scorer.scoreOne(wrongResponse);
168+
console.log("Wrong answer score result:", wrongScoreResult);
169+
console.log("Score:", wrongScoreResult?.score);
170+
console.log("Metadata:", wrongScoreResult?.metadata);
145171
}
146172
}
147173

@@ -160,9 +186,10 @@ This will execute `dev.ts`.
160186

161187
## Examples
162188

163-
See the `examples/scorers/` directory for complete working examples:
189+
See the `src/scorers/` directory for complete working examples:
164190

165-
- `exact-match-scorer.ts` - Exact match scoring
166-
- `semantic-similarity-scorer.ts` - Semantic similarity scoring
191+
- `exact-match-scorer.ts` - Exact match scoring that returns PromptScore objects
192+
- `multiple-choice-scorer.ts` - Multiple choice scoring with answer extraction
193+
- `ref-answer-equality-llm-judge-scorer.ts` - LLM-based scoring for reference answer equality
167194

168-
These examples demonstrate real-world implementations and can serve as templates for your own Scorers.
195+
These examples demonstrate real-world implementations and show how to properly return `PromptScore` objects with scores and metadata. They can serve as templates for your own Scorers.

peerBenchJS/packages/sdk/eslint.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import tseslint from "typescript-eslint";
33

44
export default [
55
{
6-
ignores: ["dist/**/*.js"],
6+
ignores: ["dist/**/*.js", "examples/**/*.ts"],
77
},
88
...tseslint.config({
99
extends: [eslint.configs.recommended, tseslint.configs.recommended],
10-
files: ["src/**/*.ts", "examples/**/*.ts", "scripts/**/*.ts"],
10+
files: ["src/**/*.ts", "scripts/**/*.ts"],
1111

1212
rules: {
1313
"@typescript-eslint/no-explicit-any": "off",

peerBenchJS/packages/sdk/examples/collectors/news-api-collector.ts

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,8 @@ export class NewsAPICollector extends AbstractCollector<NewsArticle[]> {
2727
readonly identifier = "news-api";
2828

2929
// API configuration - these would be set during initialization
30-
private apiKey: string; // Authentication key for the API
3130
private baseUrl = "https://newsapi.org/v2"; // Base URL for API endpoints
3231

33-
/**
34-
* Constructor for the NewsAPI collector
35-
*
36-
* @param apiKey - Authentication key required to access the news API
37-
*
38-
* The constructor demonstrates how to:
39-
* - Accept configuration parameters
40-
* - Store sensitive information securely
41-
* - Initialize the collector with required credentials
42-
*/
43-
constructor(apiKey: string) {
44-
super(); // Call parent constructor
45-
this.apiKey = apiKey; // Store the API key for later use
46-
}
47-
4832
/**
4933
* Main collection method - fetches news articles based on search query
5034
*
@@ -69,10 +53,12 @@ export class NewsAPICollector extends AbstractCollector<NewsArticle[]> {
6953
searchQuery: string,
7054
options: {
7155
includeSensitiveContent?: boolean; // Option to include sensitive content
72-
} = {
73-
includeSensitiveContent: false, // Default to excluding sensitive content
56+
apiKey: string;
7457
}
7558
): Promise<NewsArticle[] | undefined> {
59+
// Default to excluding sensitive content
60+
const includeSensitiveContent = options.includeSensitiveContent ?? false;
61+
7662
// Type guard: ensure the source is a string search query
7763
// This prevents runtime errors from invalid input types
7864
if (typeof searchQuery !== "string") {
@@ -83,8 +69,8 @@ export class NewsAPICollector extends AbstractCollector<NewsArticle[]> {
8369
// URLSearchParams automatically handles URL encoding and parameter formatting
8470
const params = new URLSearchParams();
8571
params.set("q", searchQuery); // Set the search query
86-
params.set("apiKey", this.apiKey); // Add authentication
87-
if (options.includeSensitiveContent) {
72+
params.set("apiKey", options.apiKey); // Add authentication
73+
if (includeSensitiveContent) {
8874
params.set("sensitive", "true"); // Optional parameter for content filtering
8975
}
9076

peerBenchJS/packages/sdk/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
".": {
2626
"types": "./dist/index.d.ts",
2727
"import": "./dist/index.js"
28+
},
29+
"./generators/pubmed/helpers": {
30+
"types": "./dist/index.d.ts",
31+
"import": "./dist/index.js"
2832
}
2933
},
3034
"files": [
@@ -40,17 +44,22 @@
4044
"dependencies": {
4145
"@inquirer/prompts": "^7.4.1",
4246
"@supabase/supabase-js": "^2.56.0",
47+
"@types/sbd": "^1.0.5",
4348
"abort-controller": "^3.0.0",
4449
"ansis": "^3.17.0",
4550
"axios": "^1.11.0",
4651
"cheerio": "^1.1.2",
4752
"commander": "^13.1.0",
4853
"csv": "^6.3.11",
54+
"decimal.js": "^10.6.0",
4955
"fast-xml-parser": "^5.2.5",
5056
"glob": "^11.0.2",
5157
"hyparquet": "^1.11.0",
58+
"json-stable-stringify": "^1.3.0",
59+
"jsonrepair": "^3.13.0",
5260
"multiformats": "^13.3.2",
5361
"openai": "^4.92.1",
62+
"sbd": "^1.0.19",
5463
"table": "^6.9.0",
5564
"uuid": "^11.1.0",
5665
"viem": "^2.26.2",

peerBenchJS/packages/sdk/scripts/dev-multiple-choice-scorer-with-real-responses.ts

Lines changed: 0 additions & 66 deletions
This file was deleted.

peerBenchJS/packages/sdk/scripts/dev-multiple-choice-scorer.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

peerBenchJS/packages/sdk/scripts/pubmed_case_studies.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)