agentv 5.1.0-next.1 → 5.3.0-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 +16 -12
- package/dist/{artifact-writer-IORG7CW5.js → artifact-writer-JFNIPMKW.js} +5 -5
- package/dist/{chunk-ZGPCX334.js → chunk-6ZZCDZPD.js} +4101 -1204
- package/dist/chunk-6ZZCDZPD.js.map +1 -0
- package/dist/{chunk-CBBBRTQ3.js → chunk-BHKQHG26.js} +64 -3
- package/dist/chunk-BHKQHG26.js.map +1 -0
- package/dist/{chunk-AM2IPHKS.js → chunk-FVR4RQFK.js} +302 -162
- package/dist/chunk-FVR4RQFK.js.map +1 -0
- package/dist/{chunk-GIRUNQGP.js → chunk-T32NL3E6.js} +262 -154
- package/dist/chunk-T32NL3E6.js.map +1 -0
- package/dist/{chunk-GJWPQXHN.js → chunk-V52ATPTT.js} +104 -188
- package/dist/chunk-V52ATPTT.js.map +1 -0
- package/dist/cli.js +6 -6
- package/dist/dashboard/assets/{index-BSHoWrdr.js → index-DNgf3qJ2.js} +1 -1
- package/dist/dashboard/assets/{index-zvUKAkKn.css → index-D_bokML8.css} +1 -1
- package/dist/dashboard/assets/index-r_jSJmlw.js +121 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/{dist-2D2GBHZV.js → dist-6Z7U473R.js} +14 -8
- package/dist/index.js +6 -6
- package/dist/{interactive-V4SEHLNY.js → interactive-RUY3OCBI.js} +6 -6
- package/dist/skills/agentv-bench/SKILL.md +17 -13
- package/dist/skills/agentv-bench/agents/analyzer.md +1 -1
- package/dist/skills/agentv-bench/agents/comparator.md +3 -3
- package/dist/skills/agentv-bench/agents/grader.md +4 -2
- package/dist/skills/agentv-bench/references/description-optimization.md +5 -6
- package/dist/skills/agentv-bench/references/environment-adaptation.md +2 -2
- package/dist/skills/agentv-bench/references/eval-yaml-spec.md +35 -19
- package/dist/skills/agentv-bench/references/migrating-from-skill-creator.md +1 -1
- package/dist/skills/agentv-eval-migrations/references/breaking-changes.md +125 -28
- package/dist/skills/agentv-eval-writer/SKILL.md +113 -87
- package/dist/skills/agentv-eval-writer/references/eval.schema.json +772 -1367
- package/dist/{ts-eval-loader-SSPJVEHD-AL2A3V5Z.js → ts-eval-loader-DQDYRULE-V3377FOL.js} +3 -2
- package/package.json +8 -2
- package/dist/chunk-AM2IPHKS.js.map +0 -1
- package/dist/chunk-CBBBRTQ3.js.map +0 -1
- package/dist/chunk-GIRUNQGP.js.map +0 -1
- package/dist/chunk-GJWPQXHN.js.map +0 -1
- package/dist/chunk-ZGPCX334.js.map +0 -1
- package/dist/dashboard/assets/index-BaLLxmVO.js +0 -121
- /package/dist/{artifact-writer-IORG7CW5.js.map → artifact-writer-JFNIPMKW.js.map} +0 -0
- /package/dist/{dist-2D2GBHZV.js.map → dist-6Z7U473R.js.map} +0 -0
- /package/dist/{interactive-V4SEHLNY.js.map → interactive-RUY3OCBI.js.map} +0 -0
- /package/dist/{ts-eval-loader-SSPJVEHD-AL2A3V5Z.js.map → ts-eval-loader-DQDYRULE-V3377FOL.js.map} +0 -0
|
@@ -61,11 +61,11 @@ import {
|
|
|
61
61
|
validateFileReferences,
|
|
62
62
|
validateTargetsFile,
|
|
63
63
|
validateWorkspacePaths
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-FVR4RQFK.js";
|
|
65
65
|
import {
|
|
66
66
|
materializeEvalBundle,
|
|
67
67
|
writeArtifactsFromResults as writeArtifactsFromResults2
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-BHKQHG26.js";
|
|
69
69
|
import {
|
|
70
70
|
discoverClaudeSessions,
|
|
71
71
|
discoverCodexSessions,
|
|
@@ -77,16 +77,17 @@ import {
|
|
|
77
77
|
prepareEvalWorkspace,
|
|
78
78
|
readGitResultArtifact,
|
|
79
79
|
runBeforeSessionHook,
|
|
80
|
-
scanRepoDeps,
|
|
81
80
|
syncProjects,
|
|
82
81
|
transpileEvalYamlFile,
|
|
83
82
|
trimBaselineResult
|
|
84
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-V52ATPTT.js";
|
|
85
84
|
import {
|
|
86
85
|
AGENTV_RESULTS_ARTIFACTS_REF,
|
|
87
86
|
DEFAULT_CATEGORY,
|
|
88
87
|
DEFAULT_THRESHOLD,
|
|
89
88
|
EXECUTION_TRACE_SCHEMA_VERSION,
|
|
89
|
+
LEGACY_METRICS_SCHEMA_VERSION,
|
|
90
|
+
METRICS_SCHEMA_VERSION,
|
|
90
91
|
RESULT_INDEX_FILENAME,
|
|
91
92
|
addProject,
|
|
92
93
|
aggregateRunDir,
|
|
@@ -111,6 +112,7 @@ import {
|
|
|
111
112
|
loadTestSuite,
|
|
112
113
|
mergeConfigObjects,
|
|
113
114
|
normalizeCategoryPath,
|
|
115
|
+
normalizeMetricsArtifactWire,
|
|
114
116
|
normalizeResultRow,
|
|
115
117
|
omitExternalTraceMetadataKeys,
|
|
116
118
|
parseYamlValue,
|
|
@@ -140,7 +142,7 @@ import {
|
|
|
140
142
|
traceEnvelopeToTranscriptMessages,
|
|
141
143
|
traceFromTranscriptJsonLines,
|
|
142
144
|
writeArtifactsFromResults
|
|
143
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-6ZZCDZPD.js";
|
|
144
146
|
import {
|
|
145
147
|
__commonJS,
|
|
146
148
|
__require,
|
|
@@ -901,7 +903,7 @@ var require_src = __commonJS({
|
|
|
901
903
|
});
|
|
902
904
|
|
|
903
905
|
// src/index.ts
|
|
904
|
-
import
|
|
906
|
+
import path32 from "node:path";
|
|
905
907
|
|
|
906
908
|
// ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
907
909
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -3975,7 +3977,8 @@ export default defineAssertion(({ output }) => {
|
|
|
3975
3977
|
const pass = text.length > 0;
|
|
3976
3978
|
return {
|
|
3977
3979
|
pass,
|
|
3978
|
-
|
|
3980
|
+
score: pass ? 1 : 0,
|
|
3981
|
+
reason: pass ? 'Output has content' : 'Output is empty',
|
|
3979
3982
|
};
|
|
3980
3983
|
});
|
|
3981
3984
|
`,
|
|
@@ -3989,7 +3992,14 @@ export default defineAssertion(({ output }) => {
|
|
|
3989
3992
|
return {
|
|
3990
3993
|
pass: score >= 0.5,
|
|
3991
3994
|
score,
|
|
3992
|
-
|
|
3995
|
+
reason: score === 1.0 ? 'Output has content' : 'Output is empty',
|
|
3996
|
+
checks: [
|
|
3997
|
+
{
|
|
3998
|
+
text: 'Output has content',
|
|
3999
|
+
pass: score === 1.0,
|
|
4000
|
+
reason: score === 1.0 ? 'Output is non-empty' : 'Output is empty',
|
|
4001
|
+
},
|
|
4002
|
+
],
|
|
3993
4003
|
};
|
|
3994
4004
|
});
|
|
3995
4005
|
`
|
|
@@ -5042,15 +5052,19 @@ var ScriptGraderInputSchema = external_exports.object({
|
|
|
5042
5052
|
workspacePath: external_exports.string().nullable().optional(),
|
|
5043
5053
|
config: external_exports.record(external_exports.unknown()).nullable().optional()
|
|
5044
5054
|
});
|
|
5055
|
+
var ScriptGraderCheckSchema = external_exports.object({
|
|
5056
|
+
id: external_exports.string().optional(),
|
|
5057
|
+
text: external_exports.string(),
|
|
5058
|
+
pass: external_exports.boolean(),
|
|
5059
|
+
score: external_exports.number().min(0).max(1).optional(),
|
|
5060
|
+
reason: external_exports.string(),
|
|
5061
|
+
evidence: external_exports.string().optional()
|
|
5062
|
+
});
|
|
5045
5063
|
var ScriptGraderResultSchema = external_exports.object({
|
|
5064
|
+
pass: external_exports.boolean(),
|
|
5046
5065
|
score: external_exports.number().min(0).max(1),
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
text: external_exports.string(),
|
|
5050
|
-
passed: external_exports.boolean(),
|
|
5051
|
-
evidence: external_exports.string().optional()
|
|
5052
|
-
})
|
|
5053
|
-
).optional().default([]),
|
|
5066
|
+
reason: external_exports.string(),
|
|
5067
|
+
checks: external_exports.array(ScriptGraderCheckSchema).optional().default([]),
|
|
5054
5068
|
/** Optional structured details for domain-specific metrics (e.g., TP/TN/FP/FN counts, alignments). */
|
|
5055
5069
|
details: external_exports.record(external_exports.unknown()).optional()
|
|
5056
5070
|
});
|
|
@@ -5192,14 +5206,26 @@ async function runScriptGrader(handler) {
|
|
|
5192
5206
|
const rawResult = await handler(input);
|
|
5193
5207
|
const result = ScriptGraderResultSchema.parse({
|
|
5194
5208
|
...rawResult,
|
|
5195
|
-
score: clampScore(rawResult.score)
|
|
5209
|
+
score: clampScore(rawResult.score),
|
|
5210
|
+
checks: rawResult.checks?.map((check2) => ({
|
|
5211
|
+
...check2,
|
|
5212
|
+
...check2.score !== void 0 ? { score: clampScore(check2.score) } : {}
|
|
5213
|
+
}))
|
|
5196
5214
|
});
|
|
5197
5215
|
console.log(JSON.stringify(result, null, 2));
|
|
5198
5216
|
} catch (error) {
|
|
5199
5217
|
const errorMessage = formatError(error);
|
|
5200
5218
|
const errorResult = {
|
|
5219
|
+
pass: false,
|
|
5201
5220
|
score: 0,
|
|
5202
|
-
|
|
5221
|
+
reason: `Evaluation failed: ${errorMessage}`,
|
|
5222
|
+
checks: [
|
|
5223
|
+
{
|
|
5224
|
+
text: "Script grader execution",
|
|
5225
|
+
pass: false,
|
|
5226
|
+
reason: errorMessage
|
|
5227
|
+
}
|
|
5228
|
+
]
|
|
5203
5229
|
};
|
|
5204
5230
|
console.log(JSON.stringify(errorResult, null, 2));
|
|
5205
5231
|
process.exit(1);
|
|
@@ -5267,27 +5293,36 @@ function parseJsonObjectFromText(text) {
|
|
|
5267
5293
|
function isVitestJsonReport(value) {
|
|
5268
5294
|
return typeof value === "object" && value !== null && Array.isArray(value.testResults);
|
|
5269
5295
|
}
|
|
5270
|
-
function assertionText(file,
|
|
5271
|
-
const title =
|
|
5296
|
+
function assertionText(file, assertion) {
|
|
5297
|
+
const title = assertion.fullName ?? [...assertion.ancestorTitles ?? [], assertion.title].filter(Boolean).join(" ");
|
|
5272
5298
|
return title || file.name || "Vitest assertion";
|
|
5273
5299
|
}
|
|
5274
5300
|
function vitestReportToScriptGraderResult(report, options = {}) {
|
|
5275
|
-
const
|
|
5301
|
+
const checks = (report.testResults ?? []).flatMap(
|
|
5276
5302
|
(file) => (file.assertionResults ?? []).map((item) => {
|
|
5277
|
-
const
|
|
5303
|
+
const pass2 = item.status === "passed";
|
|
5278
5304
|
const evidence = item.failureMessages && item.failureMessages.length > 0 ? truncate(item.failureMessages.join("\n\n")) : void 0;
|
|
5279
5305
|
return {
|
|
5280
5306
|
text: assertionText(file, item),
|
|
5281
|
-
|
|
5307
|
+
pass: pass2,
|
|
5308
|
+
reason: pass2 ? "Vitest test passed." : "Vitest test failed.",
|
|
5282
5309
|
...evidence !== void 0 ? { evidence } : {}
|
|
5283
5310
|
};
|
|
5284
5311
|
})
|
|
5285
5312
|
);
|
|
5286
|
-
if (
|
|
5287
|
-
const
|
|
5313
|
+
if (checks.length === 0) {
|
|
5314
|
+
const pass2 = options.passWithNoTests === true;
|
|
5288
5315
|
return ScriptGraderResultSchema.parse({
|
|
5289
|
-
|
|
5290
|
-
|
|
5316
|
+
pass: pass2,
|
|
5317
|
+
score: pass2 ? 1 : 0,
|
|
5318
|
+
reason: pass2 ? "Vitest reported no tests; configured to pass." : "Vitest reported no tests.",
|
|
5319
|
+
checks: [
|
|
5320
|
+
{
|
|
5321
|
+
text: "Vitest reported no tests",
|
|
5322
|
+
pass: pass2,
|
|
5323
|
+
reason: pass2 ? "passWithNoTests is enabled." : "No Vitest tests were discovered."
|
|
5324
|
+
}
|
|
5325
|
+
],
|
|
5291
5326
|
details: {
|
|
5292
5327
|
vitest_success: report.success ?? false,
|
|
5293
5328
|
num_total_tests: report.numTotalTests ?? 0,
|
|
@@ -5298,15 +5333,18 @@ function vitestReportToScriptGraderResult(report, options = {}) {
|
|
|
5298
5333
|
}
|
|
5299
5334
|
});
|
|
5300
5335
|
}
|
|
5301
|
-
const passedCount =
|
|
5336
|
+
const passedCount = checks.filter((item) => item.pass).length;
|
|
5337
|
+
const pass = passedCount === checks.length;
|
|
5302
5338
|
return ScriptGraderResultSchema.parse({
|
|
5303
|
-
|
|
5304
|
-
|
|
5339
|
+
pass,
|
|
5340
|
+
score: passedCount / checks.length,
|
|
5341
|
+
reason: `${passedCount}/${checks.length} Vitest tests passed.`,
|
|
5342
|
+
checks,
|
|
5305
5343
|
details: {
|
|
5306
|
-
vitest_success: report.success ??
|
|
5307
|
-
num_total_tests: report.numTotalTests ??
|
|
5344
|
+
vitest_success: report.success ?? pass,
|
|
5345
|
+
num_total_tests: report.numTotalTests ?? checks.length,
|
|
5308
5346
|
num_passed_tests: report.numPassedTests ?? passedCount,
|
|
5309
|
-
num_failed_tests: report.numFailedTests ??
|
|
5347
|
+
num_failed_tests: report.numFailedTests ?? checks.length - passedCount,
|
|
5310
5348
|
num_pending_tests: report.numPendingTests ?? 0,
|
|
5311
5349
|
num_todo_tests: report.numTodoTests ?? 0
|
|
5312
5350
|
}
|
|
@@ -5384,12 +5422,14 @@ async function runVitestWorkspaceGrader(options, input) {
|
|
|
5384
5422
|
const workspacePath = workspacePathFrom2(input);
|
|
5385
5423
|
if (!workspacePath) {
|
|
5386
5424
|
return {
|
|
5425
|
+
pass: false,
|
|
5387
5426
|
score: 0,
|
|
5388
|
-
|
|
5427
|
+
reason: "Vitest workspace verifier requires workspace_path.",
|
|
5428
|
+
checks: [
|
|
5389
5429
|
{
|
|
5390
5430
|
text: "Vitest workspace verifier requires workspace_path",
|
|
5391
|
-
|
|
5392
|
-
|
|
5431
|
+
pass: false,
|
|
5432
|
+
reason: "Configure an environment recipe in the eval YAML so AgentV can pass workspace_path."
|
|
5393
5433
|
}
|
|
5394
5434
|
]
|
|
5395
5435
|
};
|
|
@@ -5423,13 +5463,16 @@ async function runVitestWorkspaceGrader(options, input) {
|
|
|
5423
5463
|
const report = await readVitestReport(result, outputFile);
|
|
5424
5464
|
return vitestReportToScriptGraderResult(report, options);
|
|
5425
5465
|
} catch (error) {
|
|
5466
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
5426
5467
|
return {
|
|
5468
|
+
pass: false,
|
|
5427
5469
|
score: 0,
|
|
5428
|
-
|
|
5470
|
+
reason: "Vitest workspace verifier failed to run.",
|
|
5471
|
+
checks: [
|
|
5429
5472
|
{
|
|
5430
5473
|
text: "Vitest workspace verifier failed to run",
|
|
5431
|
-
|
|
5432
|
-
|
|
5474
|
+
pass: false,
|
|
5475
|
+
reason
|
|
5433
5476
|
}
|
|
5434
5477
|
]
|
|
5435
5478
|
};
|
|
@@ -7970,13 +8013,31 @@ var inspectCommand = subcommands({
|
|
|
7970
8013
|
import { existsSync as existsSync6 } from "node:fs";
|
|
7971
8014
|
import { mkdir as mkdir6, readFile as readFile4, readdir, writeFile as writeFile6 } from "node:fs/promises";
|
|
7972
8015
|
import { join } from "node:path";
|
|
7973
|
-
function
|
|
8016
|
+
function toComponentResult(assertion, evaluator) {
|
|
7974
8017
|
return {
|
|
7975
|
-
|
|
7976
|
-
passed: assertion.passed,
|
|
7977
|
-
evidence: assertion.evidence ?? "",
|
|
8018
|
+
pass: assertion.passed,
|
|
7978
8019
|
score: assertion.passed ? 1 : 0,
|
|
7979
|
-
|
|
8020
|
+
reason: assertion.evidence ?? assertion.text,
|
|
8021
|
+
assertion: {
|
|
8022
|
+
...evaluator ? { name: evaluator.name, type: evaluator.type } : {},
|
|
8023
|
+
value: assertion.text
|
|
8024
|
+
}
|
|
8025
|
+
};
|
|
8026
|
+
}
|
|
8027
|
+
function evaluatorComponent(evaluator) {
|
|
8028
|
+
const pass = evaluator.score >= DEFAULT_THRESHOLD;
|
|
8029
|
+
return {
|
|
8030
|
+
pass,
|
|
8031
|
+
score: evaluator.score,
|
|
8032
|
+
reason: pass ? "Grader passed." : "Grader failed.",
|
|
8033
|
+
assertion: {
|
|
8034
|
+
name: evaluator.name,
|
|
8035
|
+
type: evaluator.type,
|
|
8036
|
+
weight: evaluator.weight
|
|
8037
|
+
},
|
|
8038
|
+
component_results: evaluator.assertions.map(
|
|
8039
|
+
(assertion) => toComponentResult(assertion, evaluator)
|
|
8040
|
+
)
|
|
7980
8041
|
};
|
|
7981
8042
|
}
|
|
7982
8043
|
var evalBenchCommand = command({
|
|
@@ -8055,20 +8116,18 @@ var evalBenchCommand = command({
|
|
|
8055
8116
|
const failed = allAssertions.filter((a) => !a.passed).length;
|
|
8056
8117
|
const passRate = allAssertions.length > 0 ? Math.round(passed / allAssertions.length * 1e3) / 1e3 : weightedScore >= 0.5 ? 1 : 0;
|
|
8057
8118
|
allPassRates.push(passRate);
|
|
8119
|
+
const pass = weightedScore >= DEFAULT_THRESHOLD;
|
|
8058
8120
|
const grading = {
|
|
8121
|
+
pass,
|
|
8059
8122
|
score: Math.round(weightedScore * 1e3) / 1e3,
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
reasoning: "",
|
|
8069
|
-
weight: e.weight,
|
|
8070
|
-
assertion_results: e.assertions.map(toAssertionResult)
|
|
8071
|
-
}))
|
|
8123
|
+
reason: pass ? "All grading components passed." : "One or more grading components failed.",
|
|
8124
|
+
component_results: evaluators.length > 0 ? evaluators.map(evaluatorComponent) : allAssertions.map((assertion) => toComponentResult(assertion)),
|
|
8125
|
+
metadata: {
|
|
8126
|
+
pass_count: passed,
|
|
8127
|
+
fail_count: failed,
|
|
8128
|
+
sample_count: allAssertions.length,
|
|
8129
|
+
pass_rate: passRate
|
|
8130
|
+
}
|
|
8072
8131
|
};
|
|
8073
8132
|
await writeFile6(
|
|
8074
8133
|
join(testDir, "grading.json"),
|
|
@@ -8079,14 +8138,10 @@ var evalBenchCommand = command({
|
|
|
8079
8138
|
const scores = evaluators.map((e) => ({
|
|
8080
8139
|
name: e.name,
|
|
8081
8140
|
type: e.type,
|
|
8141
|
+
pass: e.score >= DEFAULT_THRESHOLD,
|
|
8082
8142
|
score: e.score,
|
|
8083
8143
|
weight: e.weight,
|
|
8084
|
-
|
|
8085
|
-
assertions: e.assertions.map((a) => ({
|
|
8086
|
-
text: a.text,
|
|
8087
|
-
passed: a.passed,
|
|
8088
|
-
evidence: a.evidence ?? ""
|
|
8089
|
-
}))
|
|
8144
|
+
reason: e.score >= DEFAULT_THRESHOLD ? "Grader passed." : "Grader failed."
|
|
8090
8145
|
}));
|
|
8091
8146
|
let executionStatus = "ok";
|
|
8092
8147
|
const metricsPath = join(testDir, "metrics.json");
|
|
@@ -12783,9 +12838,10 @@ function formatSummary(results, grading) {
|
|
|
12783
12838
|
let failed;
|
|
12784
12839
|
let passRate;
|
|
12785
12840
|
if (grading) {
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
12841
|
+
const metadata = grading.metadata ?? {};
|
|
12842
|
+
passed = typeof metadata.pass_count === "number" ? metadata.pass_count : grading.pass ? total : 0;
|
|
12843
|
+
failed = typeof metadata.sample_count === "number" && typeof metadata.pass_count === "number" ? metadata.sample_count - metadata.pass_count : total - passed;
|
|
12844
|
+
passRate = typeof metadata.pass_rate === "number" ? metadata.pass_rate : total > 0 ? Math.round(passed / total * 1e3) / 1e3 : 0;
|
|
12789
12845
|
} else {
|
|
12790
12846
|
passed = results.filter((r) => r.score >= 1).length;
|
|
12791
12847
|
failed = total - passed;
|
|
@@ -12844,6 +12900,94 @@ var resultsSummaryCommand = command({
|
|
|
12844
12900
|
// src/commands/results/validate.ts
|
|
12845
12901
|
import { existsSync as existsSync14, readFileSync as readFileSync12, statSync as statSync5 } from "node:fs";
|
|
12846
12902
|
import path24 from "node:path";
|
|
12903
|
+
var LEGACY_GRADING_FIELDS = [
|
|
12904
|
+
"assertion_results",
|
|
12905
|
+
"assertions",
|
|
12906
|
+
"passed",
|
|
12907
|
+
"evidence",
|
|
12908
|
+
"verdict",
|
|
12909
|
+
"graders",
|
|
12910
|
+
"checks"
|
|
12911
|
+
];
|
|
12912
|
+
function isRecord2(value) {
|
|
12913
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12914
|
+
}
|
|
12915
|
+
function validateGradingNode(value, pathLabel) {
|
|
12916
|
+
if (!isRecord2(value)) {
|
|
12917
|
+
return [`${pathLabel} must be an object`];
|
|
12918
|
+
}
|
|
12919
|
+
const errors = [];
|
|
12920
|
+
if (typeof value.pass !== "boolean" || typeof value.score !== "number" || typeof value.reason !== "string") {
|
|
12921
|
+
errors.push(`${pathLabel} must include pass, score, and reason`);
|
|
12922
|
+
}
|
|
12923
|
+
if (value.component_results !== void 0) {
|
|
12924
|
+
if (!Array.isArray(value.component_results)) {
|
|
12925
|
+
errors.push(`${pathLabel}.component_results must be an array when present`);
|
|
12926
|
+
} else {
|
|
12927
|
+
value.component_results.forEach((component, index) => {
|
|
12928
|
+
errors.push(...validateGradingNode(component, `${pathLabel}.component_results[${index}]`));
|
|
12929
|
+
});
|
|
12930
|
+
}
|
|
12931
|
+
}
|
|
12932
|
+
return errors;
|
|
12933
|
+
}
|
|
12934
|
+
function validateNoLegacyGradingFields(value, pathLabel) {
|
|
12935
|
+
if (Array.isArray(value)) {
|
|
12936
|
+
return value.flatMap(
|
|
12937
|
+
(entry, index) => validateNoLegacyGradingFields(entry, `${pathLabel}[${index}]`)
|
|
12938
|
+
);
|
|
12939
|
+
}
|
|
12940
|
+
if (!isRecord2(value)) {
|
|
12941
|
+
return [];
|
|
12942
|
+
}
|
|
12943
|
+
const errors = [];
|
|
12944
|
+
const legacyFields = LEGACY_GRADING_FIELDS.filter((field) => Object.hasOwn(value, field));
|
|
12945
|
+
if (legacyFields.length > 0) {
|
|
12946
|
+
errors.push(`${pathLabel} uses legacy field(s): ${legacyFields.join(", ")}`);
|
|
12947
|
+
}
|
|
12948
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
12949
|
+
errors.push(...validateNoLegacyGradingFields(entry, `${pathLabel}.${key}`));
|
|
12950
|
+
}
|
|
12951
|
+
return errors;
|
|
12952
|
+
}
|
|
12953
|
+
function validateMetricsArtifact(value) {
|
|
12954
|
+
if (!isRecord2(value)) {
|
|
12955
|
+
return [{ severity: "error", message: "metrics.json must be an object" }];
|
|
12956
|
+
}
|
|
12957
|
+
const diagnostics = [];
|
|
12958
|
+
const schemaVersion = value.schema_version;
|
|
12959
|
+
const isCurrentSchema = schemaVersion === METRICS_SCHEMA_VERSION;
|
|
12960
|
+
const isLegacySchema = schemaVersion === LEGACY_METRICS_SCHEMA_VERSION;
|
|
12961
|
+
if (isCurrentSchema && Object.hasOwn(value, "trace")) {
|
|
12962
|
+
diagnostics.push({
|
|
12963
|
+
severity: "error",
|
|
12964
|
+
message: "metrics.json must not include trace in agentv.metrics.v2"
|
|
12965
|
+
});
|
|
12966
|
+
} else if (isLegacySchema && Object.hasOwn(value, "trace")) {
|
|
12967
|
+
diagnostics.push({
|
|
12968
|
+
severity: "warning",
|
|
12969
|
+
message: "metrics.json uses legacy trace identity; readers ignore it"
|
|
12970
|
+
});
|
|
12971
|
+
}
|
|
12972
|
+
if (isCurrentSchema && Object.hasOwn(value, "metrics")) {
|
|
12973
|
+
diagnostics.push({
|
|
12974
|
+
severity: "error",
|
|
12975
|
+
message: "metrics.json must not include nested metrics in agentv.metrics.v2"
|
|
12976
|
+
});
|
|
12977
|
+
} else if (isLegacySchema && Object.hasOwn(value, "metrics")) {
|
|
12978
|
+
diagnostics.push({
|
|
12979
|
+
severity: "warning",
|
|
12980
|
+
message: "metrics.json uses legacy nested metrics; readers flatten it"
|
|
12981
|
+
});
|
|
12982
|
+
}
|
|
12983
|
+
if (!normalizeMetricsArtifactWire(value)) {
|
|
12984
|
+
diagnostics.push({
|
|
12985
|
+
severity: "error",
|
|
12986
|
+
message: "metrics.json does not match a supported metrics artifact shape"
|
|
12987
|
+
});
|
|
12988
|
+
}
|
|
12989
|
+
return diagnostics;
|
|
12990
|
+
}
|
|
12847
12991
|
function checkDirectoryNaming(runDir) {
|
|
12848
12992
|
const dirName = path24.basename(runDir);
|
|
12849
12993
|
const pathSegments = path24.normalize(runDir).split(path24.sep).filter(Boolean);
|
|
@@ -12962,7 +13106,8 @@ function checkIndexJsonl(runDir) {
|
|
|
12962
13106
|
if (typeof s.name !== "string") missing.push("name");
|
|
12963
13107
|
if (typeof s.type !== "string") missing.push("type");
|
|
12964
13108
|
if (typeof s.score !== "number") missing.push("score");
|
|
12965
|
-
if (typeof s.
|
|
13109
|
+
if (typeof s.pass !== "boolean") missing.push("pass");
|
|
13110
|
+
if (typeof s.reason !== "string") missing.push("reason");
|
|
12966
13111
|
if (missing.length > 0) {
|
|
12967
13112
|
diagnostics.push({
|
|
12968
13113
|
severity: "warning",
|
|
@@ -13035,22 +13180,13 @@ function checkArtifactFiles(runDir, entries2) {
|
|
|
13035
13180
|
} else {
|
|
13036
13181
|
try {
|
|
13037
13182
|
const grading = JSON.parse(readFileSync12(gradingPath, "utf8"));
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
|
|
13042
|
-
message: `${testId}: grading.json uses legacy 'assertions' array; rewrite the run to emit 'assertion_results'`
|
|
13043
|
-
});
|
|
13044
|
-
} else {
|
|
13183
|
+
for (const error of [
|
|
13184
|
+
...validateGradingNode(grading, "grading.json"),
|
|
13185
|
+
...validateNoLegacyGradingFields(grading, "grading.json")
|
|
13186
|
+
]) {
|
|
13045
13187
|
diagnostics.push({
|
|
13046
13188
|
severity: "error",
|
|
13047
|
-
message: `${testId}:
|
|
13048
|
-
});
|
|
13049
|
-
}
|
|
13050
|
-
if (!grading.summary) {
|
|
13051
|
-
diagnostics.push({
|
|
13052
|
-
severity: "warning",
|
|
13053
|
-
message: `${testId}: grading.json missing 'summary' object`
|
|
13189
|
+
message: `${testId}: ${error}`
|
|
13054
13190
|
});
|
|
13055
13191
|
}
|
|
13056
13192
|
} catch {
|
|
@@ -13068,6 +13204,21 @@ function checkArtifactFiles(runDir, entries2) {
|
|
|
13068
13204
|
severity: "warning",
|
|
13069
13205
|
message: `${testId}: metrics.json not found at '${entry.metrics_path}'`
|
|
13070
13206
|
});
|
|
13207
|
+
} else {
|
|
13208
|
+
try {
|
|
13209
|
+
const metrics = JSON.parse(readFileSync12(metricsPath, "utf8"));
|
|
13210
|
+
for (const diagnostic of validateMetricsArtifact(metrics)) {
|
|
13211
|
+
diagnostics.push({
|
|
13212
|
+
severity: diagnostic.severity,
|
|
13213
|
+
message: `${testId}: ${diagnostic.message}`
|
|
13214
|
+
});
|
|
13215
|
+
}
|
|
13216
|
+
} catch {
|
|
13217
|
+
diagnostics.push({
|
|
13218
|
+
severity: "error",
|
|
13219
|
+
message: `${testId}: metrics.json is not valid JSON`
|
|
13220
|
+
});
|
|
13221
|
+
}
|
|
13071
13222
|
}
|
|
13072
13223
|
}
|
|
13073
13224
|
}
|
|
@@ -13964,7 +14115,7 @@ function inferRawContentType(filePath) {
|
|
|
13964
14115
|
function contentDispositionFilename(filePath) {
|
|
13965
14116
|
return path27.basename(filePath).replace(/["\\\r\n]/g, "_");
|
|
13966
14117
|
}
|
|
13967
|
-
function
|
|
14118
|
+
function isRecord3(value) {
|
|
13968
14119
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13969
14120
|
}
|
|
13970
14121
|
function nonEmptyString(value) {
|
|
@@ -13972,12 +14123,12 @@ function nonEmptyString(value) {
|
|
|
13972
14123
|
}
|
|
13973
14124
|
function artifactPointerPath(pointer) {
|
|
13974
14125
|
if (typeof pointer === "string") return nonEmptyString(pointer);
|
|
13975
|
-
if (!
|
|
14126
|
+
if (!isRecord3(pointer)) return void 0;
|
|
13976
14127
|
return nonEmptyString(pointer.path) ?? nonEmptyString(pointer.artifact_path) ?? nonEmptyString(pointer.relative_path);
|
|
13977
14128
|
}
|
|
13978
14129
|
function artifactPointerDescription(pointer) {
|
|
13979
14130
|
if (typeof pointer === "string") return pointer;
|
|
13980
|
-
if (!
|
|
14131
|
+
if (!isRecord3(pointer)) return void 0;
|
|
13981
14132
|
const ref = nonEmptyString(pointer.ref);
|
|
13982
14133
|
const storage = nonEmptyString(pointer.storage);
|
|
13983
14134
|
const uri = nonEmptyString(pointer.uri) ?? nonEmptyString(pointer.href);
|
|
@@ -13991,19 +14142,19 @@ function artifactPointerDescription(pointer) {
|
|
|
13991
14142
|
return parts.length > 0 ? parts.join(", ") : void 0;
|
|
13992
14143
|
}
|
|
13993
14144
|
function artifactPointerRef(pointer) {
|
|
13994
|
-
return
|
|
14145
|
+
return isRecord3(pointer) ? nonEmptyString(pointer.ref) : void 0;
|
|
13995
14146
|
}
|
|
13996
14147
|
function artifactPointerKey(pointer) {
|
|
13997
|
-
return
|
|
14148
|
+
return isRecord3(pointer) ? nonEmptyString(pointer.key) : void 0;
|
|
13998
14149
|
}
|
|
13999
14150
|
function artifactPointerSha256(pointer) {
|
|
14000
|
-
return
|
|
14151
|
+
return isRecord3(pointer) ? nonEmptyString(pointer.sha256) : void 0;
|
|
14001
14152
|
}
|
|
14002
14153
|
function artifactPointerMediaType(pointer) {
|
|
14003
|
-
return
|
|
14154
|
+
return isRecord3(pointer) ? nonEmptyString(pointer.media_type) : void 0;
|
|
14004
14155
|
}
|
|
14005
14156
|
function artifactPointerObjectVersion(pointer) {
|
|
14006
|
-
return
|
|
14157
|
+
return isRecord3(pointer) ? nonEmptyString(pointer.object_version) : void 0;
|
|
14007
14158
|
}
|
|
14008
14159
|
function resolveRecordArtifactPointer(record, kind) {
|
|
14009
14160
|
const legacyArtifactPointers = record.artifact_pointers;
|
|
@@ -14350,6 +14501,12 @@ async function readArtifactCatalogEntryText(searchDir, projectId, meta, entry) {
|
|
|
14350
14501
|
});
|
|
14351
14502
|
return { content };
|
|
14352
14503
|
}
|
|
14504
|
+
function readableLocalCatalogEntry(meta, entry) {
|
|
14505
|
+
if (!entry || entry.storage !== "local") return entry;
|
|
14506
|
+
const baseDir = runWorkspaceDirFromManifestPath(meta.path);
|
|
14507
|
+
const resolved = resolveReadableRunArtifactFile(baseDir, entry.displayPath);
|
|
14508
|
+
return resolved.absolutePath ? entry : void 0;
|
|
14509
|
+
}
|
|
14353
14510
|
function artifactFileContentResponse(c4, filePath, fileContent) {
|
|
14354
14511
|
if (c4.req.query("raw") === "1" || c4.req.query("download") === "1") {
|
|
14355
14512
|
c4.header("Content-Type", inferRawContentType(filePath));
|
|
@@ -14449,7 +14606,7 @@ function buildRepeatTrialReadModels(baseDir, record) {
|
|
|
14449
14606
|
const answerPath = caseTrialArtifactPath(resultDir, runPath, "outputs/answer.md");
|
|
14450
14607
|
const resultPath = caseTrialArtifactPath(resultDir, runPath, "result.json");
|
|
14451
14608
|
const runResult = readArtifactJsonObject(baseDir, resultPath);
|
|
14452
|
-
const metrics = readArtifactJsonObject(baseDir, metricsPath);
|
|
14609
|
+
const metrics = normalizeMetricsArtifactWire(readArtifactJsonObject(baseDir, metricsPath));
|
|
14453
14610
|
const timing = readArtifactJsonObject(baseDir, timingPath);
|
|
14454
14611
|
const toolCalls = objectField(metrics, "tool_calls");
|
|
14455
14612
|
const tokenUsage = objectField(metrics, "tokens") ?? objectField(timing, "token_usage");
|
|
@@ -15199,6 +15356,10 @@ async function handleEvalTranscript(c4, { searchDir, projectId }) {
|
|
|
15199
15356
|
runPath
|
|
15200
15357
|
);
|
|
15201
15358
|
const answerEntry = findPointerArtifactCatalogEntry(catalog, answer, "answer", runPath);
|
|
15359
|
+
const transcriptRawEntry = readableLocalCatalogEntry(
|
|
15360
|
+
meta,
|
|
15361
|
+
record.transcript_raw_path ? findArtifactCatalogEntry(catalog, record.transcript_raw_path) : void 0
|
|
15362
|
+
);
|
|
15202
15363
|
if (!transcriptEntry && !transcript.path) {
|
|
15203
15364
|
return c4.json({
|
|
15204
15365
|
status: transcript.unsupportedReason ? "unsupported" : "missing",
|
|
@@ -15242,6 +15403,7 @@ async function handleEvalTranscript(c4, { searchDir, projectId }) {
|
|
|
15242
15403
|
return c4.json({
|
|
15243
15404
|
status: "ok",
|
|
15244
15405
|
transcript_path: transcriptEntry.displayPath,
|
|
15406
|
+
...transcriptRawEntry && { transcript_raw_path: transcriptRawEntry.displayPath },
|
|
15245
15407
|
content,
|
|
15246
15408
|
language: inferLanguage(transcriptEntry.displayPath),
|
|
15247
15409
|
...answerEntry && { answer_path: answerEntry.displayPath },
|
|
@@ -16326,7 +16488,7 @@ import { config as loadDotenv } from "dotenv";
|
|
|
16326
16488
|
var TASK_EVAL_FILENAME = "EVAL.yaml";
|
|
16327
16489
|
var TASK_TARGETS_FILENAME = "targets.yaml";
|
|
16328
16490
|
var ENV_REF_PATTERN = /\$\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
|
|
16329
|
-
function
|
|
16491
|
+
function isRecord4(value) {
|
|
16330
16492
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16331
16493
|
}
|
|
16332
16494
|
function displayRecord(record) {
|
|
@@ -16368,11 +16530,11 @@ function stringArray(value) {
|
|
|
16368
16530
|
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && entry.length > 0) : [];
|
|
16369
16531
|
}
|
|
16370
16532
|
function readExecutionTarget(parsedEval) {
|
|
16371
|
-
if (!
|
|
16533
|
+
if (!isRecord4(parsedEval)) {
|
|
16372
16534
|
return void 0;
|
|
16373
16535
|
}
|
|
16374
16536
|
const execution = parsedEval.execution;
|
|
16375
|
-
if (
|
|
16537
|
+
if (isRecord4(execution) && typeof execution.target === "string" && execution.target.length > 0) {
|
|
16376
16538
|
return execution.target;
|
|
16377
16539
|
}
|
|
16378
16540
|
return typeof parsedEval.target === "string" && parsedEval.target.length > 0 ? parsedEval.target : void 0;
|
|
@@ -16383,10 +16545,10 @@ async function readTaskTarget(evalPath, fallback) {
|
|
|
16383
16545
|
}
|
|
16384
16546
|
async function readTargetDefinitions2(targetsPath) {
|
|
16385
16547
|
const parsed = parseYamlValue(await readFile8(targetsPath, "utf8"));
|
|
16386
|
-
if (!
|
|
16548
|
+
if (!isRecord4(parsed) || !Array.isArray(parsed.targets)) {
|
|
16387
16549
|
throw new Error(`Targets file is missing a top-level targets array: ${targetsPath}`);
|
|
16388
16550
|
}
|
|
16389
|
-
return parsed.targets.filter(
|
|
16551
|
+
return parsed.targets.filter(isRecord4);
|
|
16390
16552
|
}
|
|
16391
16553
|
function targetName(definition) {
|
|
16392
16554
|
if (typeof definition.id === "string" && definition.id.trim().length > 0) {
|
|
@@ -16442,7 +16604,7 @@ function collectEnvRefs(value, names = /* @__PURE__ */ new Set()) {
|
|
|
16442
16604
|
}
|
|
16443
16605
|
return names;
|
|
16444
16606
|
}
|
|
16445
|
-
if (
|
|
16607
|
+
if (isRecord4(value)) {
|
|
16446
16608
|
for (const [key, entry] of Object.entries(value)) {
|
|
16447
16609
|
if (key === "required_env") {
|
|
16448
16610
|
for (const required of stringArray(entry)) {
|
|
@@ -17595,58 +17757,6 @@ var validateCommand = command({
|
|
|
17595
17757
|
}
|
|
17596
17758
|
});
|
|
17597
17759
|
|
|
17598
|
-
// src/commands/workspace/deps.ts
|
|
17599
|
-
import path32 from "node:path";
|
|
17600
|
-
var depsCommand = command({
|
|
17601
|
-
name: "deps",
|
|
17602
|
-
description: "Scan eval files and list git repo dependencies needed by workspaces",
|
|
17603
|
-
args: {
|
|
17604
|
-
evalPaths: restPositionals({
|
|
17605
|
-
type: string,
|
|
17606
|
-
displayName: "eval-paths",
|
|
17607
|
-
description: "Path(s) or glob(s) to evaluation .yaml file(s)"
|
|
17608
|
-
}),
|
|
17609
|
-
usedBy: flag({
|
|
17610
|
-
long: "used-by",
|
|
17611
|
-
description: "Include list of eval files that reference each repo"
|
|
17612
|
-
})
|
|
17613
|
-
},
|
|
17614
|
-
handler: async ({ evalPaths, usedBy }) => {
|
|
17615
|
-
if (evalPaths.length === 0) {
|
|
17616
|
-
console.error("Usage: agentv workspace deps <eval-paths...>");
|
|
17617
|
-
process.exit(1);
|
|
17618
|
-
}
|
|
17619
|
-
const cwd = process.cwd();
|
|
17620
|
-
const resolvedPaths = await resolveEvalPaths(evalPaths, cwd);
|
|
17621
|
-
const result = await scanRepoDeps(resolvedPaths);
|
|
17622
|
-
for (const err2 of result.errors) {
|
|
17623
|
-
console.error(`error: ${path32.relative(cwd, err2.file)}: ${err2.message}`);
|
|
17624
|
-
}
|
|
17625
|
-
if (result.errors.length > 0) {
|
|
17626
|
-
process.exit(1);
|
|
17627
|
-
}
|
|
17628
|
-
const output = {
|
|
17629
|
-
repos: result.repos.map((r) => ({
|
|
17630
|
-
url: r.url,
|
|
17631
|
-
...r.ref !== void 0 && { ref: r.ref },
|
|
17632
|
-
...r.sparse !== void 0 && { sparse: r.sparse },
|
|
17633
|
-
...r.ancestor !== void 0 && { ancestor: r.ancestor },
|
|
17634
|
-
...usedBy && { used_by: r.usedBy.map((p) => path32.relative(cwd, p)) }
|
|
17635
|
-
}))
|
|
17636
|
-
};
|
|
17637
|
-
console.log(JSON.stringify(output, null, 2));
|
|
17638
|
-
}
|
|
17639
|
-
});
|
|
17640
|
-
|
|
17641
|
-
// src/commands/workspace/index.ts
|
|
17642
|
-
var workspaceCommand = subcommands({
|
|
17643
|
-
name: "workspace",
|
|
17644
|
-
description: "Inspect workspace dependencies",
|
|
17645
|
-
cmds: {
|
|
17646
|
-
deps: depsCommand
|
|
17647
|
-
}
|
|
17648
|
-
});
|
|
17649
|
-
|
|
17650
17760
|
// src/update-check.ts
|
|
17651
17761
|
import { spawn as spawn4 } from "node:child_process";
|
|
17652
17762
|
import { readFile as readFile9 } from "node:fs/promises";
|
|
@@ -17655,8 +17765,8 @@ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
|
17655
17765
|
var CONFIG_DIR = getAgentvConfigDir();
|
|
17656
17766
|
var CACHE_FILE = "version-check.json";
|
|
17657
17767
|
var NPM_REGISTRY_BASE2 = "https://registry.npmjs.org/agentv/";
|
|
17658
|
-
async function getCachedUpdateInfo(
|
|
17659
|
-
const filePath =
|
|
17768
|
+
async function getCachedUpdateInfo(path33) {
|
|
17769
|
+
const filePath = path33 ?? join6(CONFIG_DIR, CACHE_FILE);
|
|
17660
17770
|
try {
|
|
17661
17771
|
const raw = await readFile9(filePath, "utf-8");
|
|
17662
17772
|
const data = JSON.parse(raw);
|
|
@@ -17761,8 +17871,7 @@ var app = subcommands({
|
|
|
17761
17871
|
trend: trendCommand,
|
|
17762
17872
|
transpile: transpileCommand,
|
|
17763
17873
|
trim: trimCommand,
|
|
17764
|
-
validate: validateCommand
|
|
17765
|
-
workspace: workspaceCommand
|
|
17874
|
+
validate: validateCommand
|
|
17766
17875
|
}
|
|
17767
17876
|
});
|
|
17768
17877
|
var EVAL_SUBCOMMANDS = /* @__PURE__ */ new Set(["run", "assert", "aggregate", "bundle", "vitest"]);
|
|
@@ -17788,8 +17897,7 @@ var TOP_LEVEL_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
17788
17897
|
"trend",
|
|
17789
17898
|
"transpile",
|
|
17790
17899
|
"trim",
|
|
17791
|
-
"validate"
|
|
17792
|
-
"workspace"
|
|
17900
|
+
"validate"
|
|
17793
17901
|
]);
|
|
17794
17902
|
function usesDeprecatedStudioAlias(argv) {
|
|
17795
17903
|
return argv[2] === "studio";
|
|
@@ -17845,7 +17953,7 @@ ${updateNotice}
|
|
|
17845
17953
|
if (shouldRunBeforeSessionHook(processedArgv)) {
|
|
17846
17954
|
const cwd = process.cwd();
|
|
17847
17955
|
const repoRoot = await findRepoRoot(cwd);
|
|
17848
|
-
const sessionConfig = await loadConfig(
|
|
17956
|
+
const sessionConfig = await loadConfig(path32.join(cwd, "_"), repoRoot);
|
|
17849
17957
|
const beforeSessionCommand = sessionConfig?.hooks?.before_session;
|
|
17850
17958
|
if (beforeSessionCommand) {
|
|
17851
17959
|
runBeforeSessionHook(beforeSessionCommand);
|
|
@@ -17862,4 +17970,4 @@ export {
|
|
|
17862
17970
|
preprocessArgv,
|
|
17863
17971
|
runCli
|
|
17864
17972
|
};
|
|
17865
|
-
//# sourceMappingURL=chunk-
|
|
17973
|
+
//# sourceMappingURL=chunk-T32NL3E6.js.map
|