agentv 5.3.1-next.1 → 5.3.2-next.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 +52 -44
- package/dist/{artifact-writer-7NBCOAYC.js → artifact-writer-KJEOROKQ.js} +5 -5
- package/dist/{chunk-ELCJ23K4.js → chunk-6262OKXM.js} +2856 -2404
- package/dist/chunk-6262OKXM.js.map +1 -0
- package/dist/chunk-AQ5BIAXF.js +604 -0
- package/dist/chunk-AQ5BIAXF.js.map +1 -0
- package/dist/chunk-BV5VQLI2.js +2 -0
- package/dist/{chunk-LXBI3SPX.js → chunk-JGSRUJZQ.js} +46 -20
- package/dist/chunk-JGSRUJZQ.js.map +1 -0
- package/dist/chunk-MMDLXYBX.js +721 -0
- package/dist/chunk-MMDLXYBX.js.map +1 -0
- package/dist/{chunk-LKGARI3W.js → chunk-QSK3PC44.js} +812 -570
- package/dist/chunk-QSK3PC44.js.map +1 -0
- package/dist/chunk-TEEXVJWM.js +2 -0
- package/dist/{chunk-RKE7SSET.js → chunk-WIAJ7JAV.js} +186 -64
- package/dist/chunk-WIAJ7JAV.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +17517 -10
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +14 -0
- package/dist/config.js.map +1 -0
- package/dist/contracts-DsZmZLl8.d.ts +742 -0
- package/dist/contracts.d.ts +2 -0
- package/dist/contracts.js +28 -0
- package/dist/contracts.js.map +1 -0
- package/dist/dashboard/assets/{index-CbEMiJSb.js → index-BfqOlLOF.js} +1 -1
- package/dist/dashboard/assets/index-Bh8lpGce.css +1 -0
- package/dist/dashboard/assets/index-oPR3ywQb.js +121 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/{dist-NMXMI5SK.js → dist-A3SGR7TW.js} +16 -16
- package/dist/dist-A3SGR7TW.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +137 -18
- package/dist/{interactive-BN527UV3.js → interactive-DL7N2C7K.js} +24 -24
- package/dist/interactive-DL7N2C7K.js.map +1 -0
- package/dist/provider.d.ts +2 -0
- package/dist/provider.js +24 -0
- package/dist/provider.js.map +1 -0
- package/dist/sdk.d.ts +802 -0
- package/dist/sdk.js +145 -0
- package/dist/sdk.js.map +1 -0
- package/dist/skills/agentv-eval-migrations/references/breaking-changes.md +17 -18
- package/dist/skills/agentv-eval-writer/SKILL.md +27 -15
- package/dist/skills/agentv-eval-writer/references/custom-evaluators.md +5 -5
- package/dist/skills/agentv-eval-writer/references/eval.schema.json +5402 -4639
- package/dist/skills/agentv-eval-writer/references/python-helpers.md +2 -2
- package/dist/skills/agentv-eval-writer/references/rubric-evaluator.md +19 -2
- package/dist/templates/.agentv/providers.yaml +42 -0
- package/dist/templates/.env.example +2 -2
- package/dist/{ts-eval-loader-2RFVZHCT-7CZ3DCDD.js → ts-eval-loader-3G5GEAEC-6F52JLPP.js} +3 -3
- package/dist/ts-eval-loader-3G5GEAEC-6F52JLPP.js.map +1 -0
- package/package.json +29 -4
- package/dist/chunk-ASIGJIOJ.js +0 -17993
- package/dist/chunk-ASIGJIOJ.js.map +0 -1
- package/dist/chunk-ELCJ23K4.js.map +0 -1
- package/dist/chunk-LKGARI3W.js.map +0 -1
- package/dist/chunk-LXBI3SPX.js.map +0 -1
- package/dist/chunk-RKE7SSET.js.map +0 -1
- package/dist/dashboard/assets/index-DTA6-l7q.js +0 -121
- package/dist/dashboard/assets/index-D_bokML8.css +0 -1
- package/dist/interactive-BN527UV3.js.map +0 -1
- package/dist/templates/.agentv/targets.yaml +0 -97
- /package/dist/{artifact-writer-7NBCOAYC.js.map → artifact-writer-KJEOROKQ.js.map} +0 -0
- /package/dist/{dist-NMXMI5SK.js.map → chunk-BV5VQLI2.js.map} +0 -0
- /package/dist/{ts-eval-loader-2RFVZHCT-7CZ3DCDD.js.map → chunk-TEEXVJWM.js.map} +0 -0
|
@@ -0,0 +1,721 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
PromptTemplateInputSchema,
|
|
4
|
+
ScriptGraderInputSchema,
|
|
5
|
+
ScriptGraderResultSchema,
|
|
6
|
+
runScriptGrader
|
|
7
|
+
} from "./chunk-AQ5BIAXF.js";
|
|
8
|
+
import {
|
|
9
|
+
toCamelCaseDeep
|
|
10
|
+
} from "./chunk-6262OKXM.js";
|
|
11
|
+
|
|
12
|
+
// ../../packages/sdk/dist/index.js
|
|
13
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
14
|
+
import { readFile, stat } from "node:fs/promises";
|
|
15
|
+
import nodePath from "node:path";
|
|
16
|
+
import { readFileSync } from "node:fs";
|
|
17
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
18
|
+
var EVAL_SUITE_SYMBOL = Symbol.for("agentv/eval-suite");
|
|
19
|
+
var TO_EVAL_YAML_OBJECT_SYMBOL = Symbol.for("agentv/to-eval-yaml-object");
|
|
20
|
+
var KNOWN_SNAKE_CASE_KEYS = {
|
|
21
|
+
afterAll: "after_all",
|
|
22
|
+
afterEach: "after_each",
|
|
23
|
+
argsMatch: "args_match",
|
|
24
|
+
beforeAll: "before_all",
|
|
25
|
+
beforeEach: "before_each",
|
|
26
|
+
budgetUsd: "budget_usd",
|
|
27
|
+
conversationId: "conversation_id",
|
|
28
|
+
dependsOn: "depends_on",
|
|
29
|
+
expectedOutput: "expected_output",
|
|
30
|
+
explorationTolerance: "exploration_tolerance",
|
|
31
|
+
failOnError: "fail_on_error",
|
|
32
|
+
inputFiles: "input_files",
|
|
33
|
+
keepWorkspaces: "keep_workspaces",
|
|
34
|
+
maxCalls: "max_calls",
|
|
35
|
+
maxCostUsd: "max_cost_usd",
|
|
36
|
+
maxDurationMs: "max_duration_ms",
|
|
37
|
+
maxInput: "max_input",
|
|
38
|
+
maxLlmCalls: "max_llm_calls",
|
|
39
|
+
maxOutput: "max_output",
|
|
40
|
+
maxSteps: "max_steps",
|
|
41
|
+
maxTokens: "max_tokens",
|
|
42
|
+
maxToolCalls: "max_tool_calls",
|
|
43
|
+
minScore: "min_score",
|
|
44
|
+
onDependencyFailure: "on_dependency_failure",
|
|
45
|
+
onTurnFailure: "on_turn_failure",
|
|
46
|
+
outputPath: "output_path",
|
|
47
|
+
readOnly: "read_only",
|
|
48
|
+
reasoningEffort: "reasoning_effort",
|
|
49
|
+
rubricPrompt: "rubric_prompt",
|
|
50
|
+
scoreRange: "score_range",
|
|
51
|
+
scoreRanges: "score_ranges",
|
|
52
|
+
skipDefaults: "skip_defaults",
|
|
53
|
+
targetExplorationRatio: "target_exploration_ratio",
|
|
54
|
+
timeoutMs: "timeout_ms",
|
|
55
|
+
timeoutSeconds: "timeout_seconds",
|
|
56
|
+
useTarget: "use_target",
|
|
57
|
+
defaultTest: "default_test",
|
|
58
|
+
windowSize: "window_size"
|
|
59
|
+
};
|
|
60
|
+
function lowerEvalYamlValue(value) {
|
|
61
|
+
if (Array.isArray(value)) {
|
|
62
|
+
return value.map((item) => lowerEvalYamlValue(item));
|
|
63
|
+
}
|
|
64
|
+
if (value && typeof value === "object") {
|
|
65
|
+
const result = {};
|
|
66
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
67
|
+
const loweredKey = KNOWN_SNAKE_CASE_KEYS[key] ?? key;
|
|
68
|
+
result[loweredKey] = lowerEvalYamlValue(nestedValue);
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
function lowerEvalConfig(config) {
|
|
75
|
+
const lowered = lowerEvalYamlValue(config);
|
|
76
|
+
const { budget_usd: budgetUsd, repeat, ...loweredWithoutRuntimeOptions } = lowered;
|
|
77
|
+
validateRepeatValue(repeat, "repeat");
|
|
78
|
+
if (budgetUsd === void 0 && repeat === void 0) {
|
|
79
|
+
return lowered;
|
|
80
|
+
}
|
|
81
|
+
const evaluateOptions = lowered.evaluate_options && typeof lowered.evaluate_options === "object" && !Array.isArray(lowered.evaluate_options) ? { ...lowered.evaluate_options } : {};
|
|
82
|
+
if (budgetUsd !== void 0 && evaluateOptions.budget_usd === void 0) {
|
|
83
|
+
evaluateOptions.budget_usd = budgetUsd;
|
|
84
|
+
}
|
|
85
|
+
if (repeat !== void 0 && evaluateOptions.repeat === void 0) {
|
|
86
|
+
evaluateOptions.repeat = repeat;
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
...loweredWithoutRuntimeOptions,
|
|
90
|
+
evaluate_options: evaluateOptions
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function validateRepeatValue(value, location) {
|
|
94
|
+
if (value === void 0) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`defineEval() expects ${location} to be a positive integer; object-shaped repeat authoring has been removed.`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function attachEvalSuiteBrand(definition) {
|
|
104
|
+
validateTopLevelRuntimeFields(definition);
|
|
105
|
+
const branded = definition;
|
|
106
|
+
if (branded[EVAL_SUITE_SYMBOL] === true) {
|
|
107
|
+
return branded;
|
|
108
|
+
}
|
|
109
|
+
Object.defineProperties(branded, {
|
|
110
|
+
[EVAL_SUITE_SYMBOL]: {
|
|
111
|
+
value: true,
|
|
112
|
+
enumerable: false,
|
|
113
|
+
configurable: false,
|
|
114
|
+
writable: false
|
|
115
|
+
},
|
|
116
|
+
[TO_EVAL_YAML_OBJECT_SYMBOL]: {
|
|
117
|
+
value: () => toEvalYamlObject(definition),
|
|
118
|
+
enumerable: false,
|
|
119
|
+
configurable: false,
|
|
120
|
+
writable: false
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return branded;
|
|
124
|
+
}
|
|
125
|
+
function validateTopLevelRuntimeFields(definition) {
|
|
126
|
+
const rawDefinition = definition;
|
|
127
|
+
if (Object.prototype.hasOwnProperty.call(rawDefinition, "input")) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
"defineEval() does not accept top-level 'input'. Use prompts with default test vars or tests[].vars instead."
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (Object.prototype.hasOwnProperty.call(rawDefinition, "preprocessors")) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
"defineEval() does not accept top-level 'preprocessors'. Use defaultTest.options.transform or assertion-level transform instead."
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (Object.prototype.hasOwnProperty.call(rawDefinition, "graders")) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
"defineEval() no longer accepts top-level 'graders'. Put grader providers in 'providers' and select them with defaults.grader, defaultTest.options.provider, tests[].options.provider, or assertion provider."
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
if (Object.prototype.hasOwnProperty.call(rawDefinition, "experiment")) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
"defineEval() no longer accepts top-level 'experiment'. Use tags: { experiment: '<name>' } or CLI --experiment."
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
for (const field of ["model", "policy", "execution", "runs", "earlyExit"]) {
|
|
148
|
+
if (Object.prototype.hasOwnProperty.call(rawDefinition, field)) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`defineEval() does not accept top-level '${field}'. Put target overrides in target and repeat controls under repeat, which serializes to evaluate_options.repeat.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
validateRepeatValue(rawDefinition.repeat, "repeat");
|
|
155
|
+
if (Array.isArray(rawDefinition.tests)) {
|
|
156
|
+
rawDefinition.tests.forEach((test, index) => {
|
|
157
|
+
if (test && typeof test === "object" && Object.prototype.hasOwnProperty.call(test, "input")) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
`defineEval() does not accept tests[${index}].input. Use prompts with tests[].vars instead.`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
const options = test.options;
|
|
163
|
+
if (options && typeof options === "object" && !Array.isArray(options)) {
|
|
164
|
+
validateRepeatValue(
|
|
165
|
+
options.repeat,
|
|
166
|
+
`tests[${index}].options.repeat`
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
validateProviderSurface(definition);
|
|
172
|
+
}
|
|
173
|
+
function validateProviderSurface(definition) {
|
|
174
|
+
const visit = (value, path) => {
|
|
175
|
+
if (Array.isArray(value)) {
|
|
176
|
+
value.forEach((entry, index) => visit(entry, `${path}[${index}]`));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (!value || typeof value !== "object") return;
|
|
180
|
+
const record = value;
|
|
181
|
+
if (path.endsWith(".defaults") && Object.prototype.hasOwnProperty.call(record, "target")) {
|
|
182
|
+
throw new Error("defineEval() no longer accepts 'defaults.target'. Use 'defaults.provider'.");
|
|
183
|
+
}
|
|
184
|
+
if (Object.prototype.hasOwnProperty.call(record, "target")) {
|
|
185
|
+
throw new Error(
|
|
186
|
+
`defineEval() no longer accepts '${path}.target'. Use '${path}.provider' or '${path}.providers' instead.`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
if (Object.prototype.hasOwnProperty.call(record, "targets")) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
`defineEval() no longer accepts '${path}.targets'. Use '${path}.providers' instead.`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
for (const [key, nested] of Object.entries(record)) {
|
|
195
|
+
visit(nested, `${path}.${key}`);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
visit(definition, "eval");
|
|
199
|
+
}
|
|
200
|
+
function defineEval(definition) {
|
|
201
|
+
return attachEvalSuiteBrand(definition);
|
|
202
|
+
}
|
|
203
|
+
function toEvalYamlObject(definition) {
|
|
204
|
+
return lowerEvalConfig(definition);
|
|
205
|
+
}
|
|
206
|
+
function serializeEvalYaml(definition) {
|
|
207
|
+
return stringifyYaml(toEvalYamlObject(definition), { lineWidth: 0 }).trimEnd();
|
|
208
|
+
}
|
|
209
|
+
function withCommon(config, options = {}) {
|
|
210
|
+
return {
|
|
211
|
+
...options.metric !== void 0 ? { metric: options.metric } : {},
|
|
212
|
+
...config,
|
|
213
|
+
...options.weight !== void 0 ? { weight: options.weight } : {},
|
|
214
|
+
...options.required !== void 0 ? { required: options.required } : {},
|
|
215
|
+
...options.minScore !== void 0 ? { minScore: options.minScore } : {},
|
|
216
|
+
...options.negate !== void 0 ? { negate: options.negate } : {},
|
|
217
|
+
...options.transform !== void 0 ? { transform: options.transform } : {}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function containsGrader(value, options) {
|
|
221
|
+
return withCommon({ type: "contains", value }, options);
|
|
222
|
+
}
|
|
223
|
+
function equalsGrader(value, options) {
|
|
224
|
+
return withCommon({ type: "equals", value }, options);
|
|
225
|
+
}
|
|
226
|
+
function exactGrader(value, options) {
|
|
227
|
+
return equalsGrader(value, options);
|
|
228
|
+
}
|
|
229
|
+
function regexGrader(pattern, options = {}) {
|
|
230
|
+
const value = pattern instanceof RegExp ? pattern.source : pattern;
|
|
231
|
+
const flags = options.flags ?? (pattern instanceof RegExp ? pattern.flags : void 0);
|
|
232
|
+
return withCommon(
|
|
233
|
+
{
|
|
234
|
+
type: "regex",
|
|
235
|
+
value,
|
|
236
|
+
...flags ? { flags } : {}
|
|
237
|
+
},
|
|
238
|
+
options
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
function isJsonGrader(options) {
|
|
242
|
+
return withCommon({ type: "is-json" }, options);
|
|
243
|
+
}
|
|
244
|
+
function jsonGrader(options) {
|
|
245
|
+
return isJsonGrader(options);
|
|
246
|
+
}
|
|
247
|
+
function llmRubricGrader(valueOrCriteria, options = {}) {
|
|
248
|
+
return withCommon(
|
|
249
|
+
{
|
|
250
|
+
type: "llm-rubric",
|
|
251
|
+
...valueOrCriteria !== void 0 ? { value: valueOrCriteria } : {},
|
|
252
|
+
...options.prompt !== void 0 ? { prompt: options.prompt } : {},
|
|
253
|
+
...options.provider !== void 0 ? { provider: options.provider } : {},
|
|
254
|
+
...options.config !== void 0 ? { config: options.config } : {},
|
|
255
|
+
...options.maxSteps !== void 0 ? { maxSteps: options.maxSteps } : {},
|
|
256
|
+
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
257
|
+
},
|
|
258
|
+
options
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
function codeGrader(command, options = {}) {
|
|
262
|
+
return scriptGrader(command, options);
|
|
263
|
+
}
|
|
264
|
+
function scriptGrader(command, options = {}) {
|
|
265
|
+
return withCommon(
|
|
266
|
+
{
|
|
267
|
+
type: "script",
|
|
268
|
+
command,
|
|
269
|
+
...options.cwd !== void 0 ? { cwd: options.cwd } : {},
|
|
270
|
+
...options.provider !== void 0 ? { provider: options.provider } : {},
|
|
271
|
+
...options.config !== void 0 ? { config: options.config } : {}
|
|
272
|
+
},
|
|
273
|
+
options
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
var graders = Object.freeze({
|
|
277
|
+
contains: containsGrader,
|
|
278
|
+
equals: equalsGrader,
|
|
279
|
+
exact: exactGrader,
|
|
280
|
+
regex: regexGrader,
|
|
281
|
+
isJson: isJsonGrader,
|
|
282
|
+
json: jsonGrader,
|
|
283
|
+
llmRubric: llmRubricGrader,
|
|
284
|
+
codeGrader,
|
|
285
|
+
script: scriptGrader,
|
|
286
|
+
scriptGrader
|
|
287
|
+
});
|
|
288
|
+
var ProviderNotAvailableError = class extends Error {
|
|
289
|
+
constructor(message) {
|
|
290
|
+
super(message);
|
|
291
|
+
this.name = "ProviderNotAvailableError";
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
var ProviderInvocationError = class extends Error {
|
|
295
|
+
statusCode;
|
|
296
|
+
constructor(message, statusCode) {
|
|
297
|
+
super(message);
|
|
298
|
+
this.name = "ProviderInvocationError";
|
|
299
|
+
this.statusCode = statusCode;
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
function createProviderClient() {
|
|
303
|
+
const proxyUrl = process.env.AGENTV_PROVIDER_PROXY_URL;
|
|
304
|
+
const proxyToken = process.env.AGENTV_PROVIDER_PROXY_TOKEN;
|
|
305
|
+
if (!proxyUrl) {
|
|
306
|
+
return void 0;
|
|
307
|
+
}
|
|
308
|
+
if (!proxyToken) {
|
|
309
|
+
throw new ProviderNotAvailableError(
|
|
310
|
+
"AGENTV_PROVIDER_PROXY_URL is set but AGENTV_PROVIDER_PROXY_TOKEN is missing"
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
return createProviderClientInternal(proxyUrl, proxyToken);
|
|
314
|
+
}
|
|
315
|
+
function createProviderClientInternal(url, token) {
|
|
316
|
+
const headers = {
|
|
317
|
+
"Content-Type": "application/json",
|
|
318
|
+
Authorization: `Bearer ${token}`
|
|
319
|
+
};
|
|
320
|
+
return {
|
|
321
|
+
async invoke(request) {
|
|
322
|
+
const response = await fetch(`${url}/invoke`, {
|
|
323
|
+
method: "POST",
|
|
324
|
+
headers,
|
|
325
|
+
body: JSON.stringify({
|
|
326
|
+
question: request.question,
|
|
327
|
+
systemPrompt: request.systemPrompt,
|
|
328
|
+
evalCaseId: request.evalCaseId,
|
|
329
|
+
attempt: request.attempt,
|
|
330
|
+
provider: request.provider
|
|
331
|
+
})
|
|
332
|
+
});
|
|
333
|
+
if (!response.ok) {
|
|
334
|
+
const errorBody = await response.text();
|
|
335
|
+
let errorMessage;
|
|
336
|
+
try {
|
|
337
|
+
const errorJson = JSON.parse(errorBody);
|
|
338
|
+
errorMessage = errorJson.error ?? `HTTP ${response.status}`;
|
|
339
|
+
} catch {
|
|
340
|
+
errorMessage = errorBody || `HTTP ${response.status}`;
|
|
341
|
+
}
|
|
342
|
+
throw new ProviderInvocationError(errorMessage, response.status);
|
|
343
|
+
}
|
|
344
|
+
return await response.json();
|
|
345
|
+
},
|
|
346
|
+
async invokeBatch(requests) {
|
|
347
|
+
const response = await fetch(`${url}/invokeBatch`, {
|
|
348
|
+
method: "POST",
|
|
349
|
+
headers,
|
|
350
|
+
body: JSON.stringify({
|
|
351
|
+
requests: requests.map((r) => ({
|
|
352
|
+
question: r.question,
|
|
353
|
+
systemPrompt: r.systemPrompt,
|
|
354
|
+
evalCaseId: r.evalCaseId,
|
|
355
|
+
attempt: r.attempt,
|
|
356
|
+
provider: r.provider
|
|
357
|
+
}))
|
|
358
|
+
})
|
|
359
|
+
});
|
|
360
|
+
if (!response.ok) {
|
|
361
|
+
const errorBody = await response.text();
|
|
362
|
+
let errorMessage;
|
|
363
|
+
try {
|
|
364
|
+
const errorJson = JSON.parse(errorBody);
|
|
365
|
+
errorMessage = errorJson.error ?? `HTTP ${response.status}`;
|
|
366
|
+
} catch {
|
|
367
|
+
errorMessage = errorBody || `HTTP ${response.status}`;
|
|
368
|
+
}
|
|
369
|
+
throw new ProviderInvocationError(errorMessage, response.status);
|
|
370
|
+
}
|
|
371
|
+
const result = await response.json();
|
|
372
|
+
return result.responses;
|
|
373
|
+
},
|
|
374
|
+
async getInfo() {
|
|
375
|
+
const response = await fetch(`${url}/info`, {
|
|
376
|
+
method: "GET",
|
|
377
|
+
headers
|
|
378
|
+
});
|
|
379
|
+
if (!response.ok) {
|
|
380
|
+
const errorBody = await response.text();
|
|
381
|
+
let errorMessage;
|
|
382
|
+
try {
|
|
383
|
+
const errorJson = JSON.parse(errorBody);
|
|
384
|
+
errorMessage = errorJson.error ?? `HTTP ${response.status}`;
|
|
385
|
+
} catch {
|
|
386
|
+
errorMessage = errorBody || `HTTP ${response.status}`;
|
|
387
|
+
}
|
|
388
|
+
throw new ProviderInvocationError(errorMessage, response.status);
|
|
389
|
+
}
|
|
390
|
+
return await response.json();
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
function workspacePathFrom(input) {
|
|
395
|
+
const workspacePath = input.workspacePath ?? process.env.AGENTV_WORKSPACE_PATH;
|
|
396
|
+
if (!workspacePath?.trim()) {
|
|
397
|
+
return void 0;
|
|
398
|
+
}
|
|
399
|
+
return workspacePath;
|
|
400
|
+
}
|
|
401
|
+
function normalizeDisplayPath(relativePath) {
|
|
402
|
+
return relativePath.split(nodePath.sep).join("/");
|
|
403
|
+
}
|
|
404
|
+
function resolveWorkspacePath(workspacePath, relativePath) {
|
|
405
|
+
const displayPath = normalizeDisplayPath(relativePath);
|
|
406
|
+
if (!workspacePath) {
|
|
407
|
+
return {
|
|
408
|
+
displayPath,
|
|
409
|
+
error: "Workspace path is not available. Configure an environment recipe in the eval YAML."
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
if (!relativePath.trim()) {
|
|
413
|
+
return { displayPath, error: "Workspace file path must not be empty." };
|
|
414
|
+
}
|
|
415
|
+
if (nodePath.isAbsolute(relativePath)) {
|
|
416
|
+
return {
|
|
417
|
+
displayPath,
|
|
418
|
+
error: `Workspace file path must be relative: ${displayPath}`
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
const root = nodePath.resolve(workspacePath);
|
|
422
|
+
const absolutePath = nodePath.resolve(root, relativePath);
|
|
423
|
+
const relativeToRoot = nodePath.relative(root, absolutePath);
|
|
424
|
+
if (relativeToRoot === "" || relativeToRoot.startsWith("..") || nodePath.isAbsolute(relativeToRoot)) {
|
|
425
|
+
return {
|
|
426
|
+
displayPath,
|
|
427
|
+
error: `Workspace file path must stay inside the workspace: ${displayPath}`
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
displayPath: normalizeDisplayPath(relativeToRoot),
|
|
432
|
+
absolutePath
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function check(text, pass, reason, evidence) {
|
|
436
|
+
return {
|
|
437
|
+
text,
|
|
438
|
+
pass,
|
|
439
|
+
reason,
|
|
440
|
+
...evidence !== void 0 ? { evidence } : {}
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function quote(value) {
|
|
444
|
+
return JSON.stringify(value);
|
|
445
|
+
}
|
|
446
|
+
function regexLabel(pattern) {
|
|
447
|
+
return `/${pattern.source}/${pattern.flags}`;
|
|
448
|
+
}
|
|
449
|
+
async function readFileForAssertion(file) {
|
|
450
|
+
try {
|
|
451
|
+
return { content: await file.readText() };
|
|
452
|
+
} catch (error) {
|
|
453
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function isScriptGraderResult(value) {
|
|
457
|
+
return !Array.isArray(value) && typeof value === "object" && value !== null && "score" in value;
|
|
458
|
+
}
|
|
459
|
+
function createWorkspace(input) {
|
|
460
|
+
const workspacePath = workspacePathFrom(input);
|
|
461
|
+
const textCache = /* @__PURE__ */ new Map();
|
|
462
|
+
async function readText(relativePath) {
|
|
463
|
+
const resolved = resolveWorkspacePath(workspacePath, relativePath);
|
|
464
|
+
if (resolved.error) {
|
|
465
|
+
throw new Error(resolved.error);
|
|
466
|
+
}
|
|
467
|
+
const absolutePath = resolved.absolutePath;
|
|
468
|
+
if (!absolutePath) {
|
|
469
|
+
throw new Error(`Unable to resolve workspace file: ${resolved.displayPath}`);
|
|
470
|
+
}
|
|
471
|
+
let pendingRead = textCache.get(absolutePath);
|
|
472
|
+
if (!pendingRead) {
|
|
473
|
+
pendingRead = readFile(absolutePath, "utf8");
|
|
474
|
+
textCache.set(absolutePath, pendingRead);
|
|
475
|
+
}
|
|
476
|
+
return pendingRead;
|
|
477
|
+
}
|
|
478
|
+
function file(relativePath) {
|
|
479
|
+
const resolved = resolveWorkspacePath(workspacePath, relativePath);
|
|
480
|
+
const label = resolved.displayPath;
|
|
481
|
+
return {
|
|
482
|
+
path: label,
|
|
483
|
+
...resolved.absolutePath !== void 0 ? { absolutePath: resolved.absolutePath } : {},
|
|
484
|
+
readText() {
|
|
485
|
+
return readText(relativePath);
|
|
486
|
+
},
|
|
487
|
+
async exists(options = {}) {
|
|
488
|
+
const text = options.text ?? `${label} exists`;
|
|
489
|
+
if (resolved.error) {
|
|
490
|
+
return check(text, false, resolved.error);
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
const fileStat = await stat(resolved.absolutePath);
|
|
494
|
+
if (fileStat.isFile()) {
|
|
495
|
+
return check(text, true, `${label} exists.`);
|
|
496
|
+
}
|
|
497
|
+
return check(text, false, `${label} exists but is not a file.`);
|
|
498
|
+
} catch {
|
|
499
|
+
return check(text, false, `${label} does not exist.`);
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
async contains(expected, options = {}) {
|
|
503
|
+
const text = options.text ?? `${label} contains ${quote(expected)}`;
|
|
504
|
+
const content = await readFileForAssertion(this);
|
|
505
|
+
if ("error" in content) {
|
|
506
|
+
return check(text, false, content.error);
|
|
507
|
+
}
|
|
508
|
+
const pass = content.content.includes(expected);
|
|
509
|
+
return check(
|
|
510
|
+
text,
|
|
511
|
+
pass,
|
|
512
|
+
pass ? `${label} contains ${quote(expected)}.` : `${label} is missing ${quote(expected)}.`
|
|
513
|
+
);
|
|
514
|
+
},
|
|
515
|
+
async notContains(expected, options = {}) {
|
|
516
|
+
const text = options.text ?? `${label} does not contain ${quote(expected)}`;
|
|
517
|
+
const content = await readFileForAssertion(this);
|
|
518
|
+
if ("error" in content) {
|
|
519
|
+
return check(text, false, content.error);
|
|
520
|
+
}
|
|
521
|
+
const pass = !content.content.includes(expected);
|
|
522
|
+
return check(
|
|
523
|
+
text,
|
|
524
|
+
pass,
|
|
525
|
+
pass ? `${label} does not contain ${quote(expected)}.` : `${label} contains unexpected text ${quote(expected)}.`
|
|
526
|
+
);
|
|
527
|
+
},
|
|
528
|
+
async matches(pattern, options = {}) {
|
|
529
|
+
const text = options.text ?? `${label} matches ${regexLabel(pattern)}`;
|
|
530
|
+
const content = await readFileForAssertion(this);
|
|
531
|
+
if ("error" in content) {
|
|
532
|
+
return check(text, false, content.error);
|
|
533
|
+
}
|
|
534
|
+
pattern.lastIndex = 0;
|
|
535
|
+
const pass = pattern.test(content.content);
|
|
536
|
+
return check(
|
|
537
|
+
text,
|
|
538
|
+
pass,
|
|
539
|
+
pass ? `${label} matches ${regexLabel(pattern)}.` : `${label} does not match ${regexLabel(pattern)}.`
|
|
540
|
+
);
|
|
541
|
+
},
|
|
542
|
+
async notMatches(pattern, options = {}) {
|
|
543
|
+
const text = options.text ?? `${label} does not match ${regexLabel(pattern)}`;
|
|
544
|
+
const content = await readFileForAssertion(this);
|
|
545
|
+
if ("error" in content) {
|
|
546
|
+
return check(text, false, content.error);
|
|
547
|
+
}
|
|
548
|
+
pattern.lastIndex = 0;
|
|
549
|
+
const pass = !pattern.test(content.content);
|
|
550
|
+
return check(
|
|
551
|
+
text,
|
|
552
|
+
pass,
|
|
553
|
+
pass ? `${label} does not match ${regexLabel(pattern)}.` : `${label} matches unexpected pattern ${regexLabel(pattern)}.`
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
return {
|
|
559
|
+
...workspacePath !== void 0 ? { path: workspacePath } : {},
|
|
560
|
+
file,
|
|
561
|
+
readText
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
async function normalizeWorkspaceGraderResult(result) {
|
|
565
|
+
if (isScriptGraderResult(result)) {
|
|
566
|
+
return ScriptGraderResultSchema.parse(result);
|
|
567
|
+
}
|
|
568
|
+
const checks = Array.isArray(result) ? await Promise.all(result) : [result];
|
|
569
|
+
const passed = checks.filter((item) => item.pass).length;
|
|
570
|
+
const score = checks.length > 0 ? checks.reduce((sum, item) => sum + (item.score ?? (item.pass ? 1 : 0)), 0) / checks.length : 0;
|
|
571
|
+
return ScriptGraderResultSchema.parse({
|
|
572
|
+
pass: checks.length > 0 && passed === checks.length,
|
|
573
|
+
score,
|
|
574
|
+
reason: checks.length > 0 ? `${passed}/${checks.length} checks passed.` : "No checks ran.",
|
|
575
|
+
checks
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
async function runWorkspaceGrader(handler, input) {
|
|
579
|
+
return normalizeWorkspaceGraderResult(
|
|
580
|
+
await handler({
|
|
581
|
+
...input,
|
|
582
|
+
workspace: createWorkspace(input)
|
|
583
|
+
})
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
function defineWorkspaceGrader(handler) {
|
|
587
|
+
runScriptGrader((input) => runWorkspaceGrader(handler, input));
|
|
588
|
+
}
|
|
589
|
+
function enrichInput(input) {
|
|
590
|
+
return input;
|
|
591
|
+
}
|
|
592
|
+
function readStdin() {
|
|
593
|
+
return readFileSync(0, "utf8");
|
|
594
|
+
}
|
|
595
|
+
function clampScore(value) {
|
|
596
|
+
if (Number.isNaN(value) || !Number.isFinite(value)) {
|
|
597
|
+
return 0;
|
|
598
|
+
}
|
|
599
|
+
return Math.max(0, Math.min(1, value));
|
|
600
|
+
}
|
|
601
|
+
function formatError(error) {
|
|
602
|
+
if (error instanceof Error) {
|
|
603
|
+
return error.message;
|
|
604
|
+
}
|
|
605
|
+
return String(error);
|
|
606
|
+
}
|
|
607
|
+
function normalizeScore(result) {
|
|
608
|
+
let score;
|
|
609
|
+
if (result.score !== void 0) {
|
|
610
|
+
score = clampScore(result.score);
|
|
611
|
+
} else if (result.pass !== void 0) {
|
|
612
|
+
score = result.pass ? 1 : 0;
|
|
613
|
+
} else {
|
|
614
|
+
score = 0;
|
|
615
|
+
}
|
|
616
|
+
const pass = result.pass ?? score >= 0.5;
|
|
617
|
+
return {
|
|
618
|
+
pass,
|
|
619
|
+
score,
|
|
620
|
+
reason: result.reason ?? (pass ? "Assertion passed" : "Assertion failed"),
|
|
621
|
+
checks: result.checks ? result.checks.map((check2) => ({
|
|
622
|
+
...check2,
|
|
623
|
+
...check2.score !== void 0 ? { score: clampScore(check2.score) } : {}
|
|
624
|
+
})) : [],
|
|
625
|
+
details: result.details
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
async function runAssertion(handler) {
|
|
629
|
+
try {
|
|
630
|
+
const stdin = readStdin();
|
|
631
|
+
const rawInput = JSON.parse(stdin);
|
|
632
|
+
const camelInput = toCamelCaseDeep(rawInput);
|
|
633
|
+
const input = ScriptGraderInputSchema.parse(camelInput);
|
|
634
|
+
if (input.outputPath && (input.output === null || input.output === void 0)) {
|
|
635
|
+
let cachedOutput;
|
|
636
|
+
const filePath = input.outputPath;
|
|
637
|
+
Object.defineProperty(input, "output", {
|
|
638
|
+
get() {
|
|
639
|
+
if (cachedOutput === void 0) {
|
|
640
|
+
cachedOutput = JSON.parse(readFileSync(filePath, "utf8"));
|
|
641
|
+
}
|
|
642
|
+
return cachedOutput;
|
|
643
|
+
},
|
|
644
|
+
configurable: true,
|
|
645
|
+
enumerable: true
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
enrichInput(input);
|
|
649
|
+
const rawResult = await handler(input);
|
|
650
|
+
const normalized = normalizeScore(rawResult);
|
|
651
|
+
const result = ScriptGraderResultSchema.parse(normalized);
|
|
652
|
+
console.log(JSON.stringify(result, null, 2));
|
|
653
|
+
} catch (error) {
|
|
654
|
+
const errorMessage = formatError(error);
|
|
655
|
+
const errorResult = {
|
|
656
|
+
pass: false,
|
|
657
|
+
score: 0,
|
|
658
|
+
reason: `Assertion failed: ${errorMessage}`,
|
|
659
|
+
checks: [{ text: "Assertion execution", pass: false, reason: errorMessage }]
|
|
660
|
+
};
|
|
661
|
+
console.log(JSON.stringify(errorResult, null, 2));
|
|
662
|
+
process.exit(1);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
function readStdin2() {
|
|
666
|
+
return readFileSync2(0, "utf8");
|
|
667
|
+
}
|
|
668
|
+
async function runPromptTemplate(handler) {
|
|
669
|
+
try {
|
|
670
|
+
const stdin = readStdin2();
|
|
671
|
+
const rawInput = JSON.parse(stdin);
|
|
672
|
+
const camelInput = toCamelCaseDeep(rawInput);
|
|
673
|
+
const input = PromptTemplateInputSchema.parse(camelInput);
|
|
674
|
+
enrichInput(input);
|
|
675
|
+
const prompt = await handler(input);
|
|
676
|
+
console.log(prompt);
|
|
677
|
+
} catch (error) {
|
|
678
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
679
|
+
process.exit(1);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
function defineScriptGrader(handler) {
|
|
683
|
+
runScriptGrader(handler);
|
|
684
|
+
}
|
|
685
|
+
function defineCodeGrader(handler) {
|
|
686
|
+
defineScriptGrader(handler);
|
|
687
|
+
}
|
|
688
|
+
function definePromptTemplate(handler) {
|
|
689
|
+
runPromptTemplate(handler);
|
|
690
|
+
}
|
|
691
|
+
function defineAssertion(handler) {
|
|
692
|
+
runAssertion(handler);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
export {
|
|
696
|
+
defineEval,
|
|
697
|
+
toEvalYamlObject,
|
|
698
|
+
serializeEvalYaml,
|
|
699
|
+
containsGrader,
|
|
700
|
+
equalsGrader,
|
|
701
|
+
exactGrader,
|
|
702
|
+
regexGrader,
|
|
703
|
+
isJsonGrader,
|
|
704
|
+
jsonGrader,
|
|
705
|
+
llmRubricGrader,
|
|
706
|
+
codeGrader,
|
|
707
|
+
scriptGrader,
|
|
708
|
+
graders,
|
|
709
|
+
ProviderNotAvailableError,
|
|
710
|
+
ProviderInvocationError,
|
|
711
|
+
createProviderClient,
|
|
712
|
+
createWorkspace,
|
|
713
|
+
normalizeWorkspaceGraderResult,
|
|
714
|
+
runWorkspaceGrader,
|
|
715
|
+
defineWorkspaceGrader,
|
|
716
|
+
defineScriptGrader,
|
|
717
|
+
defineCodeGrader,
|
|
718
|
+
definePromptTemplate,
|
|
719
|
+
defineAssertion
|
|
720
|
+
};
|
|
721
|
+
//# sourceMappingURL=chunk-MMDLXYBX.js.map
|