@axlsdk/eval 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -0
- package/dist/chunk-F5UZX6FP.js +198 -0
- package/dist/chunk-F5UZX6FP.js.map +1 -0
- package/dist/cli.cjs +375 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +161 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +334 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +126 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {
|
|
2
|
+
evalCompare,
|
|
3
|
+
runEval
|
|
4
|
+
} from "./chunk-F5UZX6FP.js";
|
|
5
|
+
|
|
6
|
+
// src/dataset.ts
|
|
7
|
+
import { readFile } from "fs/promises";
|
|
8
|
+
import * as path from "path";
|
|
9
|
+
function dataset(config) {
|
|
10
|
+
return {
|
|
11
|
+
name: config.name,
|
|
12
|
+
schema: config.schema,
|
|
13
|
+
annotationsSchema: config.annotations,
|
|
14
|
+
async getItems() {
|
|
15
|
+
if (config.items && config.file) {
|
|
16
|
+
throw new Error('Dataset config error: "items" and "file" are mutually exclusive');
|
|
17
|
+
}
|
|
18
|
+
if (!config.items && !config.file) {
|
|
19
|
+
throw new Error('Dataset config error: either "items" or "file" must be provided');
|
|
20
|
+
}
|
|
21
|
+
if (config.items) {
|
|
22
|
+
return config.items.map((item) => ({
|
|
23
|
+
input: config.schema.parse(item.input),
|
|
24
|
+
annotations: item.annotations && config.annotations ? config.annotations.parse(item.annotations) : item.annotations
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
const resolvedPath = path.resolve(config.basePath ?? process.cwd(), config.file);
|
|
28
|
+
const content = await readFile(resolvedPath, "utf-8");
|
|
29
|
+
const items = JSON.parse(content);
|
|
30
|
+
return items.map((item) => ({
|
|
31
|
+
input: config.schema.parse(item.input),
|
|
32
|
+
annotations: item.annotations && config.annotations ? config.annotations.parse(item.annotations) : item.annotations
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/scorer.ts
|
|
39
|
+
function scorer(config) {
|
|
40
|
+
return {
|
|
41
|
+
name: config.name,
|
|
42
|
+
description: config.description,
|
|
43
|
+
isLlm: false,
|
|
44
|
+
score: config.score
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/llm-scorer.ts
|
|
49
|
+
function llmScorer(config) {
|
|
50
|
+
const scorerInstance = {
|
|
51
|
+
name: config.name,
|
|
52
|
+
description: config.description,
|
|
53
|
+
isLlm: true,
|
|
54
|
+
async score(output, input, annotations) {
|
|
55
|
+
const injectedProvider = scorerInstance._provider;
|
|
56
|
+
if (!injectedProvider) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`LLM scorer "${config.name}" requires a provider. Run via axl.eval() or the CLI.`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const prompt = [
|
|
62
|
+
`Evaluate the following output.`,
|
|
63
|
+
``,
|
|
64
|
+
`## Input`,
|
|
65
|
+
`${JSON.stringify(input, null, 2)}`,
|
|
66
|
+
annotations ? `
|
|
67
|
+
## Annotations (Ground Truth)
|
|
68
|
+
${JSON.stringify(annotations, null, 2)}` : "",
|
|
69
|
+
``,
|
|
70
|
+
`## Output to Evaluate`,
|
|
71
|
+
`${JSON.stringify(output, null, 2)}`,
|
|
72
|
+
``,
|
|
73
|
+
`Respond with valid JSON matching the required schema with a score field (0-1) and reasoning.`
|
|
74
|
+
].join("\n");
|
|
75
|
+
const colonIdx = config.model.indexOf(":");
|
|
76
|
+
const model = colonIdx > -1 ? config.model.slice(colonIdx + 1) : config.model;
|
|
77
|
+
const response = await injectedProvider.chat(
|
|
78
|
+
[
|
|
79
|
+
{ role: "system", content: config.system },
|
|
80
|
+
{ role: "user", content: prompt }
|
|
81
|
+
],
|
|
82
|
+
{ model, temperature: config.temperature ?? 0.2 }
|
|
83
|
+
);
|
|
84
|
+
const parsed = JSON.parse(response.content);
|
|
85
|
+
const validated = config.schema.parse(parsed);
|
|
86
|
+
return validated.score;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
return scorerInstance;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/define-eval.ts
|
|
93
|
+
function defineEval(config) {
|
|
94
|
+
return config;
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
dataset,
|
|
98
|
+
defineEval,
|
|
99
|
+
evalCompare,
|
|
100
|
+
llmScorer,
|
|
101
|
+
runEval,
|
|
102
|
+
scorer
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/dataset.ts","../src/scorer.ts","../src/llm-scorer.ts","../src/define-eval.ts"],"sourcesContent":["import type { z } from 'zod';\nimport { readFile } from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport type DatasetItem<TInput, TAnnotations = undefined> = {\n input: TInput;\n annotations?: TAnnotations;\n};\n\nexport type DatasetConfig<\n TInput extends z.ZodTypeAny,\n TAnnotations extends z.ZodTypeAny = z.ZodTypeAny,\n> = {\n name: string;\n schema: TInput;\n annotations?: TAnnotations;\n items?: DatasetItem<z.infer<TInput>, z.infer<TAnnotations>>[];\n file?: string;\n /** Base directory for resolving relative file paths. Defaults to cwd. */\n basePath?: string;\n};\n\nexport type Dataset<TInput = unknown, TAnnotations = unknown> = {\n readonly name: string;\n readonly schema: z.ZodTypeAny;\n readonly annotationsSchema?: z.ZodTypeAny;\n getItems(): Promise<DatasetItem<TInput, TAnnotations>[]>;\n};\n\nexport function dataset<TInput extends z.ZodTypeAny, TAnnotations extends z.ZodTypeAny>(\n config: DatasetConfig<TInput, TAnnotations>,\n): Dataset<z.infer<TInput>, z.infer<TAnnotations>> {\n return {\n name: config.name,\n schema: config.schema,\n annotationsSchema: config.annotations,\n async getItems() {\n if (config.items && config.file) {\n throw new Error('Dataset config error: \"items\" and \"file\" are mutually exclusive');\n }\n if (!config.items && !config.file) {\n throw new Error('Dataset config error: either \"items\" or \"file\" must be provided');\n }\n if (config.items) {\n return config.items.map((item) => ({\n input: config.schema.parse(item.input),\n annotations:\n item.annotations && config.annotations\n ? config.annotations.parse(item.annotations)\n : item.annotations,\n }));\n }\n const resolvedPath = path.resolve(config.basePath ?? process.cwd(), config.file!);\n const content = await readFile(resolvedPath, 'utf-8');\n const items = JSON.parse(content) as DatasetItem<z.infer<TInput>, z.infer<TAnnotations>>[];\n return items.map((item) => ({\n input: config.schema.parse(item.input),\n annotations:\n item.annotations && config.annotations\n ? config.annotations.parse(item.annotations)\n : item.annotations,\n }));\n },\n };\n}\n","export type ScorerFn<TOutput, TInput, TAnnotations> = (\n output: TOutput,\n input: TInput,\n annotations?: TAnnotations,\n) => number;\n\nexport type ScorerConfig<TOutput = any, TInput = any, TAnnotations = any> = {\n name: string;\n description: string;\n score: ScorerFn<TOutput, TInput, TAnnotations>;\n};\n\nexport type Scorer<TOutput = any, TInput = any, TAnnotations = any> = {\n readonly name: string;\n readonly description: string;\n readonly isLlm: boolean;\n score(output: TOutput, input: TInput, annotations?: TAnnotations): number | Promise<number>;\n};\n\nexport function scorer<TOutput = any, TInput = any, TAnnotations = any>(\n config: ScorerConfig<TOutput, TInput, TAnnotations>,\n): Scorer<TOutput, TInput, TAnnotations> {\n return {\n name: config.name,\n description: config.description,\n isLlm: false,\n score: config.score,\n };\n}\n","import type { z } from 'zod';\nimport type { Scorer } from './scorer.js';\n\nexport type LlmScorerConfig = {\n name: string;\n description: string;\n model: string;\n system: string;\n schema: z.ZodType<{ score: number; [key: string]: any }>;\n temperature?: number;\n};\n\nexport function llmScorer(config: LlmScorerConfig): Scorer {\n const scorerInstance: Scorer & { _provider?: any } = {\n name: config.name,\n description: config.description,\n isLlm: true,\n async score(output: any, input: any, annotations?: any): Promise<number> {\n const injectedProvider = (scorerInstance as any)._provider;\n if (!injectedProvider) {\n throw new Error(\n `LLM scorer \"${config.name}\" requires a provider. Run via axl.eval() or the CLI.`,\n );\n }\n\n const prompt = [\n `Evaluate the following output.`,\n ``,\n `## Input`,\n `${JSON.stringify(input, null, 2)}`,\n annotations\n ? `\\n## Annotations (Ground Truth)\\n${JSON.stringify(annotations, null, 2)}`\n : '',\n ``,\n `## Output to Evaluate`,\n `${JSON.stringify(output, null, 2)}`,\n ``,\n `Respond with valid JSON matching the required schema with a score field (0-1) and reasoning.`,\n ].join('\\n');\n\n const colonIdx = config.model.indexOf(':');\n const model = colonIdx > -1 ? config.model.slice(colonIdx + 1) : config.model;\n\n const response = await injectedProvider.chat(\n [\n { role: 'system', content: config.system },\n { role: 'user', content: prompt },\n ],\n { model, temperature: config.temperature ?? 0.2 },\n );\n\n const parsed = JSON.parse(response.content);\n const validated = config.schema.parse(parsed);\n return validated.score;\n },\n };\n\n return scorerInstance;\n}\n","import type { EvalConfig } from './types.js';\n\nexport function defineEval(config: EvalConfig): EvalConfig {\n return config;\n}\n"],"mappings":";;;;;;AACA,SAAS,gBAAgB;AACzB,YAAY,UAAU;AA2Bf,SAAS,QACd,QACiD;AACjD,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO;AAAA,IACf,mBAAmB,OAAO;AAAA,IAC1B,MAAM,WAAW;AACf,UAAI,OAAO,SAAS,OAAO,MAAM;AAC/B,cAAM,IAAI,MAAM,iEAAiE;AAAA,MACnF;AACA,UAAI,CAAC,OAAO,SAAS,CAAC,OAAO,MAAM;AACjC,cAAM,IAAI,MAAM,iEAAiE;AAAA,MACnF;AACA,UAAI,OAAO,OAAO;AAChB,eAAO,OAAO,MAAM,IAAI,CAAC,UAAU;AAAA,UACjC,OAAO,OAAO,OAAO,MAAM,KAAK,KAAK;AAAA,UACrC,aACE,KAAK,eAAe,OAAO,cACvB,OAAO,YAAY,MAAM,KAAK,WAAW,IACzC,KAAK;AAAA,QACb,EAAE;AAAA,MACJ;AACA,YAAM,eAAoB,aAAQ,OAAO,YAAY,QAAQ,IAAI,GAAG,OAAO,IAAK;AAChF,YAAM,UAAU,MAAM,SAAS,cAAc,OAAO;AACpD,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,aAAO,MAAM,IAAI,CAAC,UAAU;AAAA,QAC1B,OAAO,OAAO,OAAO,MAAM,KAAK,KAAK;AAAA,QACrC,aACE,KAAK,eAAe,OAAO,cACvB,OAAO,YAAY,MAAM,KAAK,WAAW,IACzC,KAAK;AAAA,MACb,EAAE;AAAA,IACJ;AAAA,EACF;AACF;;;AC7CO,SAAS,OACd,QACuC;AACvC,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,aAAa,OAAO;AAAA,IACpB,OAAO;AAAA,IACP,OAAO,OAAO;AAAA,EAChB;AACF;;;AChBO,SAAS,UAAU,QAAiC;AACzD,QAAM,iBAA+C;AAAA,IACnD,MAAM,OAAO;AAAA,IACb,aAAa,OAAO;AAAA,IACpB,OAAO;AAAA,IACP,MAAM,MAAM,QAAa,OAAY,aAAoC;AACvE,YAAM,mBAAoB,eAAuB;AACjD,UAAI,CAAC,kBAAkB;AACrB,cAAM,IAAI;AAAA,UACR,eAAe,OAAO,IAAI;AAAA,QAC5B;AAAA,MACF;AAEA,YAAM,SAAS;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,QACjC,cACI;AAAA;AAAA,EAAoC,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC,KACxE;AAAA,QACJ;AAAA,QACA;AAAA,QACA,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,QAClC;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAEX,YAAM,WAAW,OAAO,MAAM,QAAQ,GAAG;AACzC,YAAM,QAAQ,WAAW,KAAK,OAAO,MAAM,MAAM,WAAW,CAAC,IAAI,OAAO;AAExE,YAAM,WAAW,MAAM,iBAAiB;AAAA,QACtC;AAAA,UACE,EAAE,MAAM,UAAU,SAAS,OAAO,OAAO;AAAA,UACzC,EAAE,MAAM,QAAQ,SAAS,OAAO;AAAA,QAClC;AAAA,QACA,EAAE,OAAO,aAAa,OAAO,eAAe,IAAI;AAAA,MAClD;AAEA,YAAM,SAAS,KAAK,MAAM,SAAS,OAAO;AAC1C,YAAM,YAAY,OAAO,OAAO,MAAM,MAAM;AAC5C,aAAO,UAAU;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AACT;;;ACxDO,SAAS,WAAW,QAAgC;AACzD,SAAO;AACT;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@axlsdk/eval",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Evaluation framework for Axl agentic workflows",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"bin": {
|
|
22
|
+
"axl-eval": "./dist/cli.js"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest watch",
|
|
32
|
+
"lint": "tsc --noEmit"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@axlsdk/axl": "workspace:*"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^25.2.3",
|
|
39
|
+
"tsup": "^8.3.0",
|
|
40
|
+
"typescript": "^5.7.0",
|
|
41
|
+
"vitest": "^3.0.0",
|
|
42
|
+
"zod": "^3.24.0"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"ai",
|
|
46
|
+
"evaluation",
|
|
47
|
+
"scoring",
|
|
48
|
+
"agents"
|
|
49
|
+
],
|
|
50
|
+
"license": "Apache-2.0",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/axl-sdk/axl.git",
|
|
54
|
+
"directory": "packages/axl-eval"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://github.com/axl-sdk/axl#readme",
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/axl-sdk/axl/issues"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=20.0.0"
|
|
65
|
+
}
|
|
66
|
+
}
|