@plune-ai/cli 0.34.0 → 0.34.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 +1 -1
- package/dist/cli.cjs +26 -12
- package/dist/index.cjs +2 -1
- package/dist/index.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,7 +117,7 @@ the last resort, used only when `PLUNE_TOKEN` is set nowhere else. Nothing write
|
|
|
117
117
|
| ------- | ------- |
|
|
118
118
|
| `plune run` | Run the suite. Flags: `--dry-run` (price the run from the model's rates — no provider key, no network), `--only <id\|tag>` (repeatable), `--bail`, `--no-cache`, `--cache-strict`, `--cache-max-age <duration>`, `--concurrency <n>`, `--format console\|json\|markdown`, `-o, --output <file>`. |
|
|
119
119
|
| `plune report` | Re-render the most recent run. Flags: `--format`, `-o`. |
|
|
120
|
-
| `plune diff <baseline> <current>` | Compare two `plune run --format json` outputs and report pass→fail regressions. Flags: `--fail-on-regression
|
|
120
|
+
| `plune diff <baseline> <current>` | Compare two `plune run --format json` outputs and report pass→fail regressions. Flags: `--fail-on-regression` (exit `1` on a regression, `3` when none but an eval was not measured), `--format`, `-o`. |
|
|
121
121
|
| `plune init` | Scaffold `plune.yaml`, a sample dataset, and `.env.example`. Flags: `--yes` (non-interactive), `--force`. |
|
|
122
122
|
| `plune login` | Save a [Plune platform](https://plune.ai/platform) API token so `sync` and `ingest` can reach it. The token is **checked against the API before it is saved**, so a wrong one fails here rather than two commands later. Get one at `https://beta.plune.ai` → Account → API tokens. Flags: `--token <token>` (omit to paste it or pipe it via stdin), `--skip-verify` (save without checking, for offline setup). In CI, skip this step: every platform command reads `PLUNE_TOKEN` from the environment first, and the saved login only when it is not set. |
|
|
123
123
|
| `plune logout` | Remove the saved token. |
|
package/dist/cli.cjs
CHANGED
|
@@ -2010,7 +2010,8 @@ async function runOrchestration(config, options, deps) {
|
|
|
2010
2010
|
limit,
|
|
2011
2011
|
(row) => runRow({
|
|
2012
2012
|
template,
|
|
2013
|
-
|
|
2013
|
+
// `defaults.assertions` apply to every eval, ahead of its own (#2415).
|
|
2014
|
+
assertions: [...config.defaults?.assertions ?? [], ...ev.assertions],
|
|
2014
2015
|
row,
|
|
2015
2016
|
providerConfig,
|
|
2016
2017
|
provider,
|
|
@@ -2887,13 +2888,13 @@ var init_fallback = __esm({
|
|
|
2887
2888
|
function failureOf(attempt, home = (0, import_node_os2.homedir)()) {
|
|
2888
2889
|
const error = chosen(attempt);
|
|
2889
2890
|
const line = error === void 0 ? void 0 : firstLine(machineless(error.text, attempt.repoRoot, home));
|
|
2890
|
-
const
|
|
2891
|
+
const headline2 = line !== void 0 && jsonBytes(line) <= HEADLINE_LIMIT ? line : void 0;
|
|
2891
2892
|
const steps = chainOf(attempt.steps);
|
|
2892
2893
|
const location = error === void 0 ? void 0 : fromRoot(placeOf(error, attempt.testFile), attempt.repoRoot);
|
|
2893
2894
|
const artifacts = attempt.attachments.filter((a) => a.path !== void 0 && !a.name.startsWith("_") && a.contentType !== METADATA_TYPE).map(({ name, contentType }) => ({ name: fileNameOf(name), ...contentType ? { contentType } : {} })).filter((a) => a.name !== "");
|
|
2894
2895
|
const ciUrl = webLink(attempt.buildHref);
|
|
2895
2896
|
const failure = {
|
|
2896
|
-
...
|
|
2897
|
+
...headline2 !== void 0 ? { headline: headline2 } : {},
|
|
2897
2898
|
...steps.length > 0 ? { steps } : {},
|
|
2898
2899
|
...location !== void 0 ? { location } : {},
|
|
2899
2900
|
...artifacts.length > 0 ? { artifacts } : {},
|
|
@@ -6241,7 +6242,8 @@ function classify2(baseline, current) {
|
|
|
6241
6242
|
if (baseline === "absent") return current === "passed" ? "new-pass" : "new-fail";
|
|
6242
6243
|
if (current === "absent") return "removed";
|
|
6243
6244
|
if (baseline === "passed") return current === "passed" ? "stable-pass" : "regression";
|
|
6244
|
-
|
|
6245
|
+
if (current === "passed") return "improvement";
|
|
6246
|
+
return baseline === "errored" ? "unmeasured" : "pre-existing-fail";
|
|
6245
6247
|
}
|
|
6246
6248
|
function diffRuns(baseline, current) {
|
|
6247
6249
|
const baseMap = new Map(baseline.evals.map((e) => [e.id, evalStatus(e)]));
|
|
@@ -6262,6 +6264,7 @@ function diffRuns(baseline, current) {
|
|
|
6262
6264
|
stablePasses: count2("stable-pass"),
|
|
6263
6265
|
errored: count2("errored"),
|
|
6264
6266
|
removed: count2("removed"),
|
|
6267
|
+
unmeasured: count2("errored") + count2("unmeasured"),
|
|
6265
6268
|
hasRegression: count2("regression") > 0
|
|
6266
6269
|
};
|
|
6267
6270
|
return { evals, summary };
|
|
@@ -6332,6 +6335,11 @@ __export(diff_exports2, {
|
|
|
6332
6335
|
renderDiff: () => renderDiff,
|
|
6333
6336
|
renderDiffMarkdown: () => renderDiffMarkdown
|
|
6334
6337
|
});
|
|
6338
|
+
function headline(d) {
|
|
6339
|
+
if (d.summary.hasRegression) return { mark: "\u274C", text: `${d.summary.regressions} regression(s)` };
|
|
6340
|
+
if (d.summary.unmeasured > 0) return { mark: "\u26A0\uFE0F", text: `${d.summary.unmeasured} eval(s) not measured` };
|
|
6341
|
+
return null;
|
|
6342
|
+
}
|
|
6335
6343
|
function summaryLine(d) {
|
|
6336
6344
|
const s = d.summary;
|
|
6337
6345
|
return [
|
|
@@ -6341,14 +6349,14 @@ function summaryLine(d) {
|
|
|
6341
6349
|
`${s.preExistingFails} pre-existing-fail`,
|
|
6342
6350
|
`${s.errored} errored`,
|
|
6343
6351
|
`${s.removed} removed`,
|
|
6352
|
+
`${s.unmeasured} not measured`,
|
|
6344
6353
|
`${s.stablePasses} stable`
|
|
6345
6354
|
].join(" \xB7 ");
|
|
6346
6355
|
}
|
|
6347
6356
|
function renderDiffMarkdown(d) {
|
|
6348
6357
|
const out = [STICKY_MARKER, "## Plune eval diff", ""];
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
);
|
|
6358
|
+
const head = headline(d);
|
|
6359
|
+
out.push(head ? `### ${head.mark} ${head.text}` : "### \u2705 No regressions");
|
|
6352
6360
|
out.push("");
|
|
6353
6361
|
const notable = d.evals.filter((e) => e.status !== "stable-pass");
|
|
6354
6362
|
if (notable.length > 0) {
|
|
@@ -6363,9 +6371,8 @@ function renderDiffMarkdown(d) {
|
|
|
6363
6371
|
return out.join("\n");
|
|
6364
6372
|
}
|
|
6365
6373
|
function renderDiffConsole(d) {
|
|
6366
|
-
const
|
|
6367
|
-
|
|
6368
|
-
];
|
|
6374
|
+
const head = headline(d);
|
|
6375
|
+
const out = [`Plune eval diff: ${head ? head.text : "no regressions"}`];
|
|
6369
6376
|
for (const e of d.evals) {
|
|
6370
6377
|
if (e.status === "stable-pass") continue;
|
|
6371
6378
|
out.push(` ${e.id}: ${e.baseline} -> ${e.current} [${e.status}]`);
|
|
@@ -6395,6 +6402,7 @@ var init_diff3 = __esm({
|
|
|
6395
6402
|
"new-pass": "\u{1F7E2} new pass",
|
|
6396
6403
|
"stable-pass": "\u2705 stable",
|
|
6397
6404
|
errored: "\u26A0\uFE0F errored",
|
|
6405
|
+
unmeasured: "\u26A0\uFE0F not measured (baseline errored)",
|
|
6398
6406
|
removed: "\u2796 removed"
|
|
6399
6407
|
};
|
|
6400
6408
|
}
|
|
@@ -9014,7 +9022,11 @@ ${missed.map((m) => ` - ${m}`).join("\n")}
|
|
|
9014
9022
|
failUnexpected(err, globals.verbose === true);
|
|
9015
9023
|
}
|
|
9016
9024
|
});
|
|
9017
|
-
program.command("diff").description("Compare two `plune run --format json` outputs and report regressions").argument("<baseline>", "Path to the baseline run JSON (e.g. from main)").argument("<current>", "Path to the current run JSON (e.g. from the PR)").option("--format <fmt>", "console | json | markdown", "console").option(
|
|
9025
|
+
program.command("diff").description("Compare two `plune run --format json` outputs and report regressions").argument("<baseline>", "Path to the baseline run JSON (e.g. from main)").argument("<current>", "Path to the current run JSON (e.g. from the PR)").option("--format <fmt>", "console | json | markdown", "console").option(
|
|
9026
|
+
"--fail-on-regression",
|
|
9027
|
+
"Exit 1 when a pass\u2192fail regression is detected, 3 when none is but an eval was not measured",
|
|
9028
|
+
false
|
|
9029
|
+
).option("-o, --output <path>", "Write the diff to a file instead of stdout").action(
|
|
9018
9030
|
async (baseline, current, options, command) => {
|
|
9019
9031
|
const verbose = command.optsWithGlobals().verbose === true;
|
|
9020
9032
|
const [{ handleDiff: handleDiff2, DiffInputError: DiffInputError2 }, { renderDiff: renderDiff2 }] = await Promise.all([
|
|
@@ -9024,7 +9036,9 @@ ${missed.map((m) => ` - ${m}`).join("\n")}
|
|
|
9024
9036
|
try {
|
|
9025
9037
|
const diff = handleDiff2({ baselinePath: baseline, currentPath: current });
|
|
9026
9038
|
writeReport(renderDiff2(diff, toFormat(options.format)), options.output);
|
|
9027
|
-
process.exitCode =
|
|
9039
|
+
process.exitCode = 0;
|
|
9040
|
+
if (options.failOnRegression && diff.summary.hasRegression) process.exitCode = 1;
|
|
9041
|
+
else if (options.failOnRegression && diff.summary.unmeasured > 0) process.exitCode = 3;
|
|
9028
9042
|
} catch (err) {
|
|
9029
9043
|
if (err instanceof DiffInputError2) {
|
|
9030
9044
|
process.stderr.write(err.message + "\n");
|
package/dist/index.cjs
CHANGED
|
@@ -1647,7 +1647,8 @@ async function runOrchestration(config, options, deps) {
|
|
|
1647
1647
|
limit,
|
|
1648
1648
|
(row) => runRow({
|
|
1649
1649
|
template,
|
|
1650
|
-
|
|
1650
|
+
// `defaults.assertions` apply to every eval, ahead of its own (#2415).
|
|
1651
|
+
assertions: [...config.defaults?.assertions ?? [], ...ev.assertions],
|
|
1651
1652
|
row,
|
|
1652
1653
|
providerConfig,
|
|
1653
1654
|
provider,
|
package/dist/index.js
CHANGED
|
@@ -1587,7 +1587,8 @@ async function runOrchestration(config, options, deps) {
|
|
|
1587
1587
|
limit,
|
|
1588
1588
|
(row) => runRow({
|
|
1589
1589
|
template,
|
|
1590
|
-
|
|
1590
|
+
// `defaults.assertions` apply to every eval, ahead of its own (#2415).
|
|
1591
|
+
assertions: [...config.defaults?.assertions ?? [], ...ev.assertions],
|
|
1591
1592
|
row,
|
|
1592
1593
|
providerConfig,
|
|
1593
1594
|
provider,
|
package/package.json
CHANGED