@axlsdk/eval 0.10.0 → 0.10.1
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 +81 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -127,33 +127,108 @@ console.log(comparison.improvements);
|
|
|
127
127
|
|
|
128
128
|
### `defineEval(config)`
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
Define an eval file for discovery by the CLI or Studio middleware:
|
|
131
131
|
|
|
132
132
|
```typescript
|
|
133
|
-
|
|
133
|
+
// evals/math.eval.ts
|
|
134
|
+
import { defineEval, dataset, scorer } from '@axlsdk/eval';
|
|
135
|
+
import { z } from 'zod';
|
|
136
|
+
|
|
137
|
+
const mathDataset = dataset({
|
|
138
|
+
name: 'math-basics',
|
|
139
|
+
schema: z.object({ question: z.string() }),
|
|
140
|
+
annotations: z.object({ answer: z.number() }),
|
|
141
|
+
items: [
|
|
142
|
+
{ input: { question: '2+2' }, annotations: { answer: 4 } },
|
|
143
|
+
{ input: { question: '3*5' }, annotations: { answer: 15 } },
|
|
144
|
+
],
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const correctAnswer = scorer({
|
|
148
|
+
name: 'correct-answer',
|
|
149
|
+
description: 'Checks if the output contains the expected numeric answer',
|
|
150
|
+
score: (output, _input, annotations) =>
|
|
151
|
+
String(output).includes(String(annotations?.answer)) ? 1 : 0,
|
|
152
|
+
});
|
|
134
153
|
|
|
135
154
|
export default defineEval({
|
|
136
155
|
workflow: 'math-workflow',
|
|
137
|
-
dataset:
|
|
138
|
-
scorers: [
|
|
156
|
+
dataset: mathDataset,
|
|
157
|
+
scorers: [correctAnswer],
|
|
139
158
|
});
|
|
140
159
|
```
|
|
141
160
|
|
|
161
|
+
By default, the eval runner calls `runtime.execute(workflow, input)` for each dataset item, which requires the workflow to be registered on the runtime.
|
|
162
|
+
|
|
163
|
+
For self-contained evals — where you want to call your own code directly instead of going through a registered workflow — export an `executeWorkflow` function alongside the config. This is especially useful in monorepos where importing the runtime would create circular dependencies:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// evals/translate.eval.ts
|
|
167
|
+
import { defineEval, dataset, scorer } from '@axlsdk/eval';
|
|
168
|
+
import { z } from 'zod';
|
|
169
|
+
import { translate } from '../src/services/translation.js'; // import your code directly
|
|
170
|
+
|
|
171
|
+
const translationDataset = dataset({
|
|
172
|
+
name: 'translations',
|
|
173
|
+
schema: z.object({ text: z.string(), targetLang: z.string() }),
|
|
174
|
+
items: [
|
|
175
|
+
{ input: { text: 'Hello', targetLang: 'es' } },
|
|
176
|
+
{ input: { text: 'Goodbye', targetLang: 'fr' } },
|
|
177
|
+
],
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const notEmpty = scorer({
|
|
181
|
+
name: 'not-empty',
|
|
182
|
+
description: 'Output is non-empty',
|
|
183
|
+
score: (output) => (String(output).length > 0 ? 1 : 0),
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
export default defineEval({
|
|
187
|
+
workflow: 'translation', // label for results (not a runtime lookup)
|
|
188
|
+
dataset: translationDataset,
|
|
189
|
+
scorers: [notEmpty],
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Called instead of runtime.execute() — the eval is fully self-contained
|
|
193
|
+
export async function executeWorkflow(input: { text: string; targetLang: string }) {
|
|
194
|
+
const result = await translate(input.text, input.targetLang);
|
|
195
|
+
return { output: result };
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
142
199
|
## CLI
|
|
143
200
|
|
|
144
201
|
Run evaluations from the command line:
|
|
145
202
|
|
|
146
203
|
```bash
|
|
147
204
|
# Run an eval file
|
|
148
|
-
npx axl eval ./evals/math.ts
|
|
205
|
+
npx axl eval ./evals/math.eval.ts
|
|
206
|
+
|
|
207
|
+
# Run all evals in a directory
|
|
208
|
+
npx axl eval ./evals/
|
|
149
209
|
|
|
150
210
|
# Save results to a file
|
|
151
|
-
npx axl eval ./evals/math.ts --output ./results/baseline.json
|
|
211
|
+
npx axl eval ./evals/math.eval.ts --output ./results/baseline.json
|
|
152
212
|
|
|
153
213
|
# Compare two results
|
|
154
214
|
npx axl eval compare ./results/baseline.json ./results/candidate.json
|
|
155
215
|
```
|
|
156
216
|
|
|
217
|
+
## Studio Integration
|
|
218
|
+
|
|
219
|
+
Eval files can also be lazy-loaded by the Studio middleware, enabling the Eval Runner panel without static imports that would create circular dependencies:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { createStudioMiddleware } from '@axlsdk/studio/middleware';
|
|
223
|
+
|
|
224
|
+
const studio = createStudioMiddleware({
|
|
225
|
+
runtime,
|
|
226
|
+
evals: 'evals/**/*.eval.ts',
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
See the [@axlsdk/studio README](../axl-studio/README.md#lazy-eval-loading) for details.
|
|
231
|
+
|
|
157
232
|
## Integration with AxlRuntime
|
|
158
233
|
|
|
159
234
|
```typescript
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axlsdk/eval",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Evaluation framework for Axl agentic workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@axlsdk/axl": "0.10.
|
|
28
|
+
"@axlsdk/axl": "0.10.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^25.2.3",
|