veryfront 0.1.963 → 0.1.965
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/esm/cli/commands/eval/command-help.js +1 -1
- package/esm/cli/commands/eval/command.d.ts +4 -1
- package/esm/cli/commands/eval/command.d.ts.map +1 -1
- package/esm/cli/commands/eval/command.js +119 -4
- package/esm/deno.js +1 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
|
@@ -18,7 +18,7 @@ export const evalHelp = {
|
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
flag: "--report-dir <path>",
|
|
21
|
-
description: "Write summary.json
|
|
21
|
+
description: "Write summary.json, results.jsonl, and report.md artifacts to a directory",
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
flag: "--junit <path>",
|
|
@@ -18,6 +18,7 @@ type EvalArtifactPaths = {
|
|
|
18
18
|
directory: string;
|
|
19
19
|
summary: string;
|
|
20
20
|
results: string;
|
|
21
|
+
reportMarkdown: string;
|
|
21
22
|
};
|
|
22
23
|
type EvalModelArtifactPaths = EvalArtifactPaths & {
|
|
23
24
|
junit: string;
|
|
@@ -36,7 +37,7 @@ type EvalSummaryArtifact = {
|
|
|
36
37
|
baseline?: EvalReportComparison;
|
|
37
38
|
};
|
|
38
39
|
type EvalModelComparisonPolicy = Omit<EvalModelComparisonOptions, "baselineModel">;
|
|
39
|
-
export declare function createDefaultEvalReportDir(runId: string): string;
|
|
40
|
+
export declare function createDefaultEvalReportDir(runId: string, label?: string): string;
|
|
40
41
|
export declare function createEvalArtifactPaths(reportDir: string): EvalArtifactPaths;
|
|
41
42
|
export declare function createEvalModelArtifactPaths(reportDir: string, model: string): EvalModelArtifactPaths;
|
|
42
43
|
export declare function normalizeEvalCliId(id: string): string;
|
|
@@ -49,6 +50,8 @@ export declare function createResolvedEvalModelComparisonConfig(projectDir: stri
|
|
|
49
50
|
export declare function createEvalModelComparisonArtifact(reports: EvalReport[], baselineModel: string, policy?: EvalModelComparisonPolicy): EvalModelComparison;
|
|
50
51
|
export declare function createEvalModelComparisonExitCode(reports: EvalReport[]): 0 | 1;
|
|
51
52
|
export declare function createResultsJsonl(report: EvalReport): string;
|
|
53
|
+
/** Render a human-reviewable markdown report for a single eval run. */
|
|
54
|
+
export declare function createEvalMarkdownReport(report: EvalReport, baseline?: EvalReportComparison): string;
|
|
52
55
|
export declare function createJunitXml(report: EvalReport): string;
|
|
53
56
|
export declare function writeEvalArtifacts(report: EvalReport, paths: EvalArtifactPaths, baseline?: EvalReportComparison): Promise<void>;
|
|
54
57
|
export declare function createEvalExitCode(report: EvalReport, baseline?: EvalReportComparison): 0 | 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/eval/command.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAS,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EACV,cAAc,EAGd,mBAAmB,EAEnB,0BAA0B,EAE1B,UAAU,EACV,oBAAoB,EAEpB,YAAY,
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/eval/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,14 +36,24 @@ function stripFileProtocol(path) {
|
|
|
36
36
|
function createCliRunId(now = new Date()) {
|
|
37
37
|
return `evalrun_${now.toISOString().replace(/[-:.]/g, "").replace("T", "_").replace("Z", "")}`;
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
return
|
|
39
|
+
function createEvalReportDirTimestamp(runId) {
|
|
40
|
+
return runId.startsWith("evalrun_") ? runId.slice("evalrun_".length) : runId;
|
|
41
|
+
}
|
|
42
|
+
function sanitizeEvalReportDirLabel(label) {
|
|
43
|
+
const normalized = label.startsWith("eval:") ? label.slice("eval:".length) : label;
|
|
44
|
+
return normalized.trim().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^[-._]+|[-._]+$/g, "");
|
|
45
|
+
}
|
|
46
|
+
export function createDefaultEvalReportDir(runId, label) {
|
|
47
|
+
const timestamp = createEvalReportDirTimestamp(runId);
|
|
48
|
+
const suffix = label ? sanitizeEvalReportDirLabel(label) : "";
|
|
49
|
+
return join(".veryfront", "evals", suffix ? `${timestamp}-${suffix}` : timestamp);
|
|
41
50
|
}
|
|
42
51
|
export function createEvalArtifactPaths(reportDir) {
|
|
43
52
|
return {
|
|
44
53
|
directory: reportDir,
|
|
45
54
|
summary: join(reportDir, "summary.json"),
|
|
46
55
|
results: join(reportDir, "results.jsonl"),
|
|
56
|
+
reportMarkdown: join(reportDir, "report.md"),
|
|
47
57
|
};
|
|
48
58
|
}
|
|
49
59
|
function sanitizeModelIdForPath(model) {
|
|
@@ -55,6 +65,7 @@ export function createEvalModelArtifactPaths(reportDir, model) {
|
|
|
55
65
|
directory,
|
|
56
66
|
summary: join(directory, "summary.json"),
|
|
57
67
|
results: join(directory, "results.jsonl"),
|
|
68
|
+
reportMarkdown: join(directory, "report.md"),
|
|
58
69
|
junit: join(directory, "junit.xml"),
|
|
59
70
|
};
|
|
60
71
|
}
|
|
@@ -284,6 +295,107 @@ export function createResultsJsonl(report) {
|
|
|
284
295
|
return "";
|
|
285
296
|
return `${report.records.map((record) => JSON.stringify(record)).join("\n")}\n`;
|
|
286
297
|
}
|
|
298
|
+
function markdownCell(value) {
|
|
299
|
+
return value.replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
300
|
+
}
|
|
301
|
+
function numberCell(value) {
|
|
302
|
+
return value === undefined ? "-" : String(Math.round(value));
|
|
303
|
+
}
|
|
304
|
+
function decimalCell(value) {
|
|
305
|
+
if (value === undefined)
|
|
306
|
+
return "-";
|
|
307
|
+
if (Number.isInteger(value))
|
|
308
|
+
return String(value);
|
|
309
|
+
return value.toFixed(4).replace(/0+$/, "").replace(/\.$/, "");
|
|
310
|
+
}
|
|
311
|
+
function percentCell(value) {
|
|
312
|
+
return `${Math.round(value * 100)}%`;
|
|
313
|
+
}
|
|
314
|
+
function durationCell(valueMs) {
|
|
315
|
+
return valueMs === undefined ? "-" : `${(valueMs / 1000).toFixed(3)}s`;
|
|
316
|
+
}
|
|
317
|
+
function usdCell(value) {
|
|
318
|
+
if (value === undefined)
|
|
319
|
+
return "-";
|
|
320
|
+
const absolute = Math.abs(value);
|
|
321
|
+
if (absolute >= 0.01)
|
|
322
|
+
return `$${value.toFixed(2)}`;
|
|
323
|
+
return `$${value.toFixed(6).replace(/0+$/, "").replace(/\.$/, "")}`;
|
|
324
|
+
}
|
|
325
|
+
function isBlockingEvalResultFailure(result) {
|
|
326
|
+
return !result.skipped && result.pass === false &&
|
|
327
|
+
(result.severity === "gate" || result.severity === "budget");
|
|
328
|
+
}
|
|
329
|
+
function examplePassed(record) {
|
|
330
|
+
if (!record.completed || record.error)
|
|
331
|
+
return false;
|
|
332
|
+
return [...(record.metrics ?? []), ...(record.checks ?? [])].every((result) => !isBlockingEvalResultFailure(result));
|
|
333
|
+
}
|
|
334
|
+
function usageRows(usage) {
|
|
335
|
+
if (!usage)
|
|
336
|
+
return [];
|
|
337
|
+
const rows = [
|
|
338
|
+
["Input tokens", numberCell(usage.inputTokens)],
|
|
339
|
+
["Output tokens", numberCell(usage.outputTokens)],
|
|
340
|
+
["Total tokens", numberCell(usage.totalTokens)],
|
|
341
|
+
["Billable input tokens", numberCell(usage.billableInputTokens)],
|
|
342
|
+
["Billable output tokens", numberCell(usage.billableOutputTokens)],
|
|
343
|
+
["Provider cost USD", usdCell(usage.providerCostUsd ?? usage.costUsd)],
|
|
344
|
+
["Veryfront charge USD", usdCell(usage.veryfrontChargeUsd)],
|
|
345
|
+
["Veryfront billed USD", usdCell(usage.veryfrontBilledUsd)],
|
|
346
|
+
["Cost credits", decimalCell(usage.costCredits)],
|
|
347
|
+
["Cost source", usage.costSource ?? "-"],
|
|
348
|
+
["Usage capture status", usage.usageCaptureStatus ?? "-"],
|
|
349
|
+
];
|
|
350
|
+
return rows.filter(([, value]) => value !== "-");
|
|
351
|
+
}
|
|
352
|
+
/** Render a human-reviewable markdown report for a single eval run. */
|
|
353
|
+
export function createEvalMarkdownReport(report, baseline) {
|
|
354
|
+
const lines = [
|
|
355
|
+
`# Eval report: ${markdownCell(report.definitionId)}`,
|
|
356
|
+
"",
|
|
357
|
+
`Run: \`${markdownCell(report.runId)}\``,
|
|
358
|
+
`Target: \`${markdownCell(report.target)}\``,
|
|
359
|
+
...(report.metadata?.model ? [`Model: \`${markdownCell(report.metadata.model)}\``] : []),
|
|
360
|
+
`Result: \`${report.summary.passed}/${report.summary.records} passed (${percentCell(report.summary.passRate)})\``,
|
|
361
|
+
"",
|
|
362
|
+
"## Metrics",
|
|
363
|
+
"",
|
|
364
|
+
"| Metric | Severity | Passed | Failed | Pass rate |",
|
|
365
|
+
"| --- | --- | ---: | ---: | ---: |",
|
|
366
|
+
];
|
|
367
|
+
for (const metric of report.summary.metrics) {
|
|
368
|
+
lines.push(`| \`${markdownCell(metric.name)}\` | ${metric.severity} | ${metric.passed} | ${metric.failed} | ${percentCell(metric.passRate)} |`);
|
|
369
|
+
}
|
|
370
|
+
const rows = usageRows(report.summary.usage);
|
|
371
|
+
if (rows.length > 0) {
|
|
372
|
+
lines.push("", "## Usage", "", "| Usage | Value |", "| --- | ---: |");
|
|
373
|
+
for (const [label, value] of rows) {
|
|
374
|
+
lines.push(`| ${label} | ${value.startsWith("$") ? `\`${value}\`` : value} |`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
lines.push("", "## Examples", "", "| Example | Result | Duration | Tokens | Billed USD | Credits |", "| --- | ---: | ---: | ---: | ---: | ---: |");
|
|
378
|
+
for (const record of report.records) {
|
|
379
|
+
lines.push(`| \`${markdownCell(record.id)}\` | ${examplePassed(record) ? "PASS" : "FAIL"} | ${durationCell(record.durationMs)} | ${numberCell(record.usage.totalTokens)} | ${record.usage.veryfrontBilledUsd === undefined
|
|
380
|
+
? "-"
|
|
381
|
+
: `\`${usdCell(record.usage.veryfrontBilledUsd)}\``} | ${decimalCell(record.usage.costCredits)} |`);
|
|
382
|
+
}
|
|
383
|
+
if (baseline) {
|
|
384
|
+
const direction = baseline.passRateDelta >= 0 ? "+" : "";
|
|
385
|
+
lines.push("", "## Baseline", "", `Status: \`${baseline.regressed ? "regressed" : "ok"}\``, `Pass rate delta: \`${direction}${Math.round(baseline.passRateDelta * 100)} pp\``);
|
|
386
|
+
if (baseline.newFailedExamples.length > 0) {
|
|
387
|
+
lines.push(`New failed examples: ${baseline.newFailedExamples.map(markdownCell).join(", ")}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (report.exports?.length) {
|
|
391
|
+
lines.push("", "## Exports", "");
|
|
392
|
+
for (const result of report.exports) {
|
|
393
|
+
lines.push(`- \`${markdownCell(result.exporterId)}\`: ${result.ok ? "ok" : `failed, ${markdownCell(result.error)}`}`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
lines.push("");
|
|
397
|
+
return lines.join("\n");
|
|
398
|
+
}
|
|
287
399
|
export function createJunitXml(report) {
|
|
288
400
|
const skipped = report.records.reduce((count, record) => count + skippedResults(record).length, 0);
|
|
289
401
|
const lines = [
|
|
@@ -320,6 +432,7 @@ export async function writeEvalArtifacts(report, paths, baseline) {
|
|
|
320
432
|
await dntShim.Deno.mkdir(paths.directory, { recursive: true });
|
|
321
433
|
await dntShim.Deno.writeTextFile(paths.summary, JSON.stringify(createSummaryArtifact(report, baseline), null, 2));
|
|
322
434
|
await dntShim.Deno.writeTextFile(paths.results, createResultsJsonl(report));
|
|
435
|
+
await dntShim.Deno.writeTextFile(paths.reportMarkdown, createEvalMarkdownReport(report, baseline));
|
|
323
436
|
}
|
|
324
437
|
async function readEvalReport(path) {
|
|
325
438
|
return JSON.parse(await dntShim.Deno.readTextFile(path));
|
|
@@ -507,7 +620,8 @@ async function writeEvalModelComparisonArtifacts(comparison, paths) {
|
|
|
507
620
|
}
|
|
508
621
|
async function runEvalModelComparison(input) {
|
|
509
622
|
const runId = createCliRunId();
|
|
510
|
-
const reportDir = input.options.reportDir ??
|
|
623
|
+
const reportDir = input.options.reportDir ??
|
|
624
|
+
createDefaultEvalReportDir(runId, input.evalItem.id);
|
|
511
625
|
const paths = createEvalModelComparisonArtifactPaths(reportDir, input.config.models);
|
|
512
626
|
const provenance = await resolveEvalRunProvenance({
|
|
513
627
|
projectDir: input.projectDir,
|
|
@@ -690,7 +804,7 @@ export async function evalCommand(options) {
|
|
|
690
804
|
return;
|
|
691
805
|
}
|
|
692
806
|
const runId = createCliRunId();
|
|
693
|
-
const artifactPaths = createEvalArtifactPaths(options.reportDir ?? createDefaultEvalReportDir(runId));
|
|
807
|
+
const artifactPaths = createEvalArtifactPaths(options.reportDir ?? createDefaultEvalReportDir(runId, evalItem.id));
|
|
694
808
|
const provenance = await resolveEvalRunProvenance({
|
|
695
809
|
projectDir,
|
|
696
810
|
frameworkVersion: VERSION,
|
|
@@ -731,6 +845,7 @@ export async function evalCommand(options) {
|
|
|
731
845
|
else {
|
|
732
846
|
printReport(report, baseline);
|
|
733
847
|
cliLogger.info(`Report directory: ${artifactPaths.directory}`);
|
|
848
|
+
cliLogger.info(`Report markdown: ${artifactPaths.reportMarkdown}`);
|
|
734
849
|
if (options.report)
|
|
735
850
|
cliLogger.info(`Report: ${options.report}`);
|
|
736
851
|
if (options.junit)
|
package/esm/deno.js
CHANGED