agentv 5.3.1-next.1 → 5.3.3
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-LKGARI3W.js → chunk-6RFRY7X2.js} +812 -570
- package/dist/chunk-6RFRY7X2.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-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-WPQJDJKZ.js} +24 -24
- package/dist/interactive-WPQJDJKZ.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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
writeArtifactsFromResults
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WIAJ7JAV.js";
|
|
5
5
|
import {
|
|
6
6
|
RunBudgetTracker,
|
|
7
7
|
buildWipBranchName,
|
|
@@ -18,12 +18,12 @@ import {
|
|
|
18
18
|
resolveResultsRepoRunsDir,
|
|
19
19
|
setupWipWorktree,
|
|
20
20
|
syncResultsRepoForProject
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-JGSRUJZQ.js";
|
|
22
22
|
import {
|
|
23
23
|
AGENTV_LOCAL_CONFIG_FILE_NAME,
|
|
24
24
|
AGENTV_LOCAL_CONFIG_YML_FILE_NAME,
|
|
25
25
|
CLI_PLACEHOLDERS,
|
|
26
|
-
|
|
26
|
+
COMMON_PROVIDER_SETTINGS,
|
|
27
27
|
DEFAULT_EVAL_PATTERNS,
|
|
28
28
|
DEFAULT_THRESHOLD,
|
|
29
29
|
KNOWN_PROVIDERS,
|
|
@@ -51,8 +51,9 @@ import {
|
|
|
51
51
|
interpolateEnv,
|
|
52
52
|
isAgentVConfigFileName,
|
|
53
53
|
isGraderKind,
|
|
54
|
+
isScenarioFileReference,
|
|
54
55
|
isTypeScriptEvalConfigFileName,
|
|
55
|
-
|
|
56
|
+
listProviderLabels,
|
|
56
57
|
loadCasesFromDirectory,
|
|
57
58
|
loadCasesFromFile,
|
|
58
59
|
loadConfig,
|
|
@@ -61,17 +62,19 @@ import {
|
|
|
61
62
|
loadTestSuiteFromYamlObject,
|
|
62
63
|
normalizeComposableConfigGraph,
|
|
63
64
|
normalizeMetricsArtifactWire,
|
|
65
|
+
normalizeProviderDefinition,
|
|
64
66
|
normalizeResultRow,
|
|
65
|
-
normalizeTargetDefinition,
|
|
66
67
|
parseJsonlResults,
|
|
67
68
|
parseYamlValue,
|
|
68
|
-
|
|
69
|
+
readProviderDefinitions,
|
|
69
70
|
readTestSuiteMetadata,
|
|
70
71
|
resolveConfigFieldReferences,
|
|
71
72
|
resolveEnvironmentRecipe,
|
|
72
73
|
resolveFileReference,
|
|
74
|
+
resolveProviderDefinition,
|
|
75
|
+
resolveProviderDefinitionEnvironments,
|
|
73
76
|
resolveResultsConfigForProject,
|
|
74
|
-
|
|
77
|
+
resolveScenarioFileReference,
|
|
75
78
|
runEvaluation,
|
|
76
79
|
serializeEvaluationResultWire,
|
|
77
80
|
shouldEnableCache,
|
|
@@ -86,7 +89,7 @@ import {
|
|
|
86
89
|
traceEnvelopeToTranscriptMessages,
|
|
87
90
|
typeScriptEvalConfigGlob,
|
|
88
91
|
writeInitialRunSummaryArtifact
|
|
89
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-6262OKXM.js";
|
|
90
93
|
|
|
91
94
|
// src/commands/eval/shared.ts
|
|
92
95
|
import { constants } from "node:fs";
|
|
@@ -346,83 +349,6 @@ async function findRepoRoot(start) {
|
|
|
346
349
|
return fallback;
|
|
347
350
|
}
|
|
348
351
|
|
|
349
|
-
// package.json
|
|
350
|
-
var package_default = {
|
|
351
|
-
name: "agentv",
|
|
352
|
-
version: "5.3.1-next.1",
|
|
353
|
-
description: "CLI entry point for AgentV",
|
|
354
|
-
type: "module",
|
|
355
|
-
repository: {
|
|
356
|
-
type: "git",
|
|
357
|
-
url: "https://github.com/EntityProcess/agentv.git"
|
|
358
|
-
},
|
|
359
|
-
homepage: "https://agentv.dev",
|
|
360
|
-
bugs: {
|
|
361
|
-
url: "https://github.com/EntityProcess/agentv/issues"
|
|
362
|
-
},
|
|
363
|
-
bin: {
|
|
364
|
-
agentv: "./dist/cli.js"
|
|
365
|
-
},
|
|
366
|
-
files: ["dist", "README.md"],
|
|
367
|
-
scripts: {
|
|
368
|
-
dev: "bun src/cli.ts",
|
|
369
|
-
build: "(cd ../../packages/sdk && bun run build) && tsup && bun run copy-readme",
|
|
370
|
-
"copy-readme": `bun -e "import { cpSync } from 'fs'; cpSync('../../README.md', 'README.md')"`,
|
|
371
|
-
prepublishOnly: `node -e "if(process.env.ALLOW_PUBLISH!=='1'){console.error('ERROR: Use bun run publish:next, then bun run promote:latest');process.exit(1)}"`,
|
|
372
|
-
typecheck: "(cd ../../packages/sdk && bun run build) && tsc --noEmit",
|
|
373
|
-
lint: "biome check .",
|
|
374
|
-
format: "biome format --write .",
|
|
375
|
-
fix: "biome check --write .",
|
|
376
|
-
test: "(cd ../../packages/sdk && bun run build) && bun test",
|
|
377
|
-
"test:watch": "bun test --watch"
|
|
378
|
-
},
|
|
379
|
-
dependencies: {
|
|
380
|
-
"@hono/node-server": "^1.19.11",
|
|
381
|
-
"@inquirer/prompts": "^8.2.1",
|
|
382
|
-
"@earendil-works/pi-ai": "^0.74.0",
|
|
383
|
-
"cmd-ts": "^0.14.3",
|
|
384
|
-
dotenv: "^16.4.5",
|
|
385
|
-
"fast-glob": "^3.3.3",
|
|
386
|
-
hono: "^4.12.9",
|
|
387
|
-
json5: "^2.2.3",
|
|
388
|
-
micromatch: "^4.0.8",
|
|
389
|
-
semver: "^7.7.4",
|
|
390
|
-
yaml: "^2.8.3"
|
|
391
|
-
},
|
|
392
|
-
peerDependencies: {
|
|
393
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.89",
|
|
394
|
-
"@github/copilot-sdk": "^1.0.3",
|
|
395
|
-
"@openai/codex-sdk": "^0.136.0",
|
|
396
|
-
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
397
|
-
},
|
|
398
|
-
peerDependenciesMeta: {
|
|
399
|
-
"@anthropic-ai/claude-agent-sdk": {
|
|
400
|
-
optional: true
|
|
401
|
-
},
|
|
402
|
-
"@github/copilot-sdk": {
|
|
403
|
-
optional: true
|
|
404
|
-
},
|
|
405
|
-
"@openai/codex-sdk": {
|
|
406
|
-
optional: true
|
|
407
|
-
},
|
|
408
|
-
"@earendil-works/pi-coding-agent": {
|
|
409
|
-
optional: true
|
|
410
|
-
}
|
|
411
|
-
},
|
|
412
|
-
optionalDependencies: {
|
|
413
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.89",
|
|
414
|
-
"@github/copilot-sdk": "^1.0.3",
|
|
415
|
-
"@openai/codex-sdk": "^0.136.0",
|
|
416
|
-
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
417
|
-
},
|
|
418
|
-
devDependencies: {
|
|
419
|
-
"@agentv/core": "workspace:*",
|
|
420
|
-
"@agentv/sdk": "workspace:*",
|
|
421
|
-
"@types/semver": "^7.7.1",
|
|
422
|
-
execa: "^9.3.0"
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
|
|
426
352
|
// src/commands/eval/result-layout.ts
|
|
427
353
|
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
428
354
|
import path2 from "node:path";
|
|
@@ -560,11 +486,17 @@ function relativeRunPathFromCwd(cwd, runDir) {
|
|
|
560
486
|
return parts.join(path2.posix.sep);
|
|
561
487
|
}
|
|
562
488
|
|
|
563
|
-
// src/utils/
|
|
489
|
+
// src/utils/providers.ts
|
|
564
490
|
import { constants as constants2 } from "node:fs";
|
|
565
|
-
import { access as access2 } from "node:fs/promises";
|
|
491
|
+
import { access as access2, stat as stat2 } from "node:fs/promises";
|
|
566
492
|
import path3 from "node:path";
|
|
567
|
-
var
|
|
493
|
+
var PROVIDER_FILE_CANDIDATES = [
|
|
494
|
+
"providers.yaml",
|
|
495
|
+
"providers.yml",
|
|
496
|
+
path3.join(".agentv", "providers.yaml"),
|
|
497
|
+
path3.join(".agentv", "providers.yml")
|
|
498
|
+
];
|
|
499
|
+
var LEGACY_TARGET_FILE_CANDIDATES = [
|
|
568
500
|
"targets.yaml",
|
|
569
501
|
"targets.yml",
|
|
570
502
|
path3.join(".agentv", "targets.yaml"),
|
|
@@ -578,20 +510,71 @@ async function fileExists(filePath) {
|
|
|
578
510
|
return false;
|
|
579
511
|
}
|
|
580
512
|
}
|
|
581
|
-
async function
|
|
582
|
-
|
|
513
|
+
async function pathKind(filePath) {
|
|
514
|
+
try {
|
|
515
|
+
const info = await stat2(filePath);
|
|
516
|
+
if (info.isDirectory()) {
|
|
517
|
+
return "directory";
|
|
518
|
+
}
|
|
519
|
+
if (info.isFile()) {
|
|
520
|
+
return "file";
|
|
521
|
+
}
|
|
522
|
+
return void 0;
|
|
523
|
+
} catch {
|
|
524
|
+
return void 0;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function isLegacyTargetFile(filePath) {
|
|
528
|
+
return /^targets\.ya?ml$/i.test(path3.basename(filePath));
|
|
529
|
+
}
|
|
530
|
+
function removedTargetsFileError(filePath) {
|
|
531
|
+
return new Error(
|
|
532
|
+
`Authored targets.yaml files were removed. Rename ${filePath} to providers.yaml and use --providers to specify it explicitly.`
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
async function findProviderFileInDirectory(directory) {
|
|
536
|
+
for (const candidate of PROVIDER_FILE_CANDIDATES) {
|
|
537
|
+
const fullPath = path3.join(directory, candidate);
|
|
538
|
+
if (await pathKind(fullPath) === "file") {
|
|
539
|
+
return fullPath;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return void 0;
|
|
543
|
+
}
|
|
544
|
+
async function findLegacyGeneratedTargetFileInDirectory(directory) {
|
|
545
|
+
for (const candidate of LEGACY_TARGET_FILE_CANDIDATES) {
|
|
546
|
+
const fullPath = path3.join(directory, candidate);
|
|
547
|
+
if (await pathKind(fullPath) === "file") {
|
|
548
|
+
return fullPath;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return void 0;
|
|
552
|
+
}
|
|
553
|
+
async function discoverProvidersFile(options) {
|
|
554
|
+
const { explicitPath, testFilePath, repoRoot, cwd, allowLegacyTargetFiles = false } = options;
|
|
583
555
|
if (explicitPath) {
|
|
584
556
|
const resolvedExplicit = path3.resolve(explicitPath);
|
|
585
|
-
|
|
557
|
+
const kind = await pathKind(resolvedExplicit);
|
|
558
|
+
if (kind === "file") {
|
|
559
|
+
if (!allowLegacyTargetFiles && isLegacyTargetFile(resolvedExplicit)) {
|
|
560
|
+
throw removedTargetsFileError(resolvedExplicit);
|
|
561
|
+
}
|
|
586
562
|
return resolvedExplicit;
|
|
587
563
|
}
|
|
588
|
-
|
|
589
|
-
const
|
|
590
|
-
if (
|
|
591
|
-
return
|
|
564
|
+
if (kind === "directory") {
|
|
565
|
+
const providerFile = await findProviderFileInDirectory(resolvedExplicit);
|
|
566
|
+
if (providerFile) {
|
|
567
|
+
return providerFile;
|
|
568
|
+
}
|
|
569
|
+
const legacyTargetFile = await findLegacyGeneratedTargetFileInDirectory(resolvedExplicit);
|
|
570
|
+
if (legacyTargetFile) {
|
|
571
|
+
if (allowLegacyTargetFiles) {
|
|
572
|
+
return legacyTargetFile;
|
|
573
|
+
}
|
|
574
|
+
throw removedTargetsFileError(legacyTargetFile);
|
|
592
575
|
}
|
|
593
576
|
}
|
|
594
|
-
throw new Error(`
|
|
577
|
+
throw new Error(`providers.yaml not found at provided path: ${resolvedExplicit}`);
|
|
595
578
|
}
|
|
596
579
|
const directories = [...buildDirectoryChain(testFilePath, repoRoot)];
|
|
597
580
|
const resolvedCwd = path3.resolve(cwd);
|
|
@@ -599,14 +582,23 @@ async function discoverTargetsFile(options) {
|
|
|
599
582
|
directories.push(resolvedCwd);
|
|
600
583
|
}
|
|
601
584
|
for (const directory of directories) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
585
|
+
const providerFile = await findProviderFileInDirectory(directory);
|
|
586
|
+
if (providerFile) {
|
|
587
|
+
return providerFile;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
for (const directory of directories) {
|
|
591
|
+
const legacyTargetFile = await findLegacyGeneratedTargetFileInDirectory(directory);
|
|
592
|
+
if (legacyTargetFile) {
|
|
593
|
+
if (allowLegacyTargetFiles) {
|
|
594
|
+
return legacyTargetFile;
|
|
606
595
|
}
|
|
596
|
+
throw removedTargetsFileError(legacyTargetFile);
|
|
607
597
|
}
|
|
608
598
|
}
|
|
609
|
-
throw new Error(
|
|
599
|
+
throw new Error(
|
|
600
|
+
"Unable to locate providers.yaml. Use --providers to specify the file explicitly."
|
|
601
|
+
);
|
|
610
602
|
}
|
|
611
603
|
|
|
612
604
|
// src/commands/eval/discover.ts
|
|
@@ -650,7 +642,7 @@ function filterByCategory(files, category) {
|
|
|
650
642
|
import { constants as constants4, existsSync as existsSync5, mkdirSync } from "node:fs";
|
|
651
643
|
import { access as access5, readFile as readFile8 } from "node:fs/promises";
|
|
652
644
|
import { createRequire as createNodeRequire } from "node:module";
|
|
653
|
-
import
|
|
645
|
+
import path13 from "node:path";
|
|
654
646
|
import { pathToFileURL } from "node:url";
|
|
655
647
|
|
|
656
648
|
// ../../node_modules/.bun/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
|
|
@@ -794,6 +786,110 @@ function validateConcurrency(concurrency) {
|
|
|
794
786
|
|
|
795
787
|
// src/version-check.ts
|
|
796
788
|
import { coerce, satisfies, validRange } from "semver";
|
|
789
|
+
|
|
790
|
+
// package.json
|
|
791
|
+
var package_default = {
|
|
792
|
+
name: "agentv",
|
|
793
|
+
version: "5.3.3",
|
|
794
|
+
description: "CLI entry point for AgentV",
|
|
795
|
+
type: "module",
|
|
796
|
+
repository: {
|
|
797
|
+
type: "git",
|
|
798
|
+
url: "https://github.com/EntityProcess/agentv.git"
|
|
799
|
+
},
|
|
800
|
+
homepage: "https://agentv.dev",
|
|
801
|
+
bugs: {
|
|
802
|
+
url: "https://github.com/EntityProcess/agentv/issues"
|
|
803
|
+
},
|
|
804
|
+
bin: {
|
|
805
|
+
agentv: "./dist/cli.js"
|
|
806
|
+
},
|
|
807
|
+
main: "./dist/index.js",
|
|
808
|
+
types: "./dist/index.d.ts",
|
|
809
|
+
exports: {
|
|
810
|
+
".": {
|
|
811
|
+
types: "./dist/index.d.ts",
|
|
812
|
+
import: "./dist/index.js"
|
|
813
|
+
},
|
|
814
|
+
"./sdk": {
|
|
815
|
+
types: "./dist/sdk.d.ts",
|
|
816
|
+
import: "./dist/sdk.js"
|
|
817
|
+
},
|
|
818
|
+
"./provider": {
|
|
819
|
+
types: "./dist/provider.d.ts",
|
|
820
|
+
import: "./dist/provider.js"
|
|
821
|
+
},
|
|
822
|
+
"./contracts": {
|
|
823
|
+
types: "./dist/contracts.d.ts",
|
|
824
|
+
import: "./dist/contracts.js"
|
|
825
|
+
},
|
|
826
|
+
"./config": {
|
|
827
|
+
types: "./dist/config.d.ts",
|
|
828
|
+
import: "./dist/config.js"
|
|
829
|
+
},
|
|
830
|
+
"./package.json": "./package.json"
|
|
831
|
+
},
|
|
832
|
+
files: ["dist", "README.md"],
|
|
833
|
+
scripts: {
|
|
834
|
+
dev: "bun src/cli.ts",
|
|
835
|
+
build: "tsup && bun run copy-readme",
|
|
836
|
+
"copy-readme": `bun -e "import { cpSync } from 'fs'; cpSync('../../README.md', 'README.md')"`,
|
|
837
|
+
prepublishOnly: `node -e "if(process.env.ALLOW_PUBLISH!=='1'){console.error('ERROR: Use bun run publish:next, then bun run promote:latest');process.exit(1)}"`,
|
|
838
|
+
typecheck: "tsc --noEmit",
|
|
839
|
+
lint: "biome check .",
|
|
840
|
+
format: "biome format --write .",
|
|
841
|
+
fix: "biome check --write .",
|
|
842
|
+
test: "bun test",
|
|
843
|
+
"test:watch": "bun test --watch"
|
|
844
|
+
},
|
|
845
|
+
dependencies: {
|
|
846
|
+
"@hono/node-server": "^1.19.11",
|
|
847
|
+
"@inquirer/prompts": "^8.2.1",
|
|
848
|
+
"@earendil-works/pi-ai": "^0.74.0",
|
|
849
|
+
"cmd-ts": "^0.14.3",
|
|
850
|
+
dotenv: "^16.4.5",
|
|
851
|
+
"fast-glob": "^3.3.3",
|
|
852
|
+
hono: "^4.12.9",
|
|
853
|
+
json5: "^2.2.3",
|
|
854
|
+
micromatch: "^4.0.8",
|
|
855
|
+
semver: "^7.7.4",
|
|
856
|
+
yaml: "^2.8.3"
|
|
857
|
+
},
|
|
858
|
+
peerDependencies: {
|
|
859
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.89",
|
|
860
|
+
"@github/copilot-sdk": "^1.0.3",
|
|
861
|
+
"@openai/codex-sdk": "^0.136.0",
|
|
862
|
+
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
863
|
+
},
|
|
864
|
+
peerDependenciesMeta: {
|
|
865
|
+
"@anthropic-ai/claude-agent-sdk": {
|
|
866
|
+
optional: true
|
|
867
|
+
},
|
|
868
|
+
"@github/copilot-sdk": {
|
|
869
|
+
optional: true
|
|
870
|
+
},
|
|
871
|
+
"@openai/codex-sdk": {
|
|
872
|
+
optional: true
|
|
873
|
+
},
|
|
874
|
+
"@earendil-works/pi-coding-agent": {
|
|
875
|
+
optional: true
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
optionalDependencies: {
|
|
879
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.89",
|
|
880
|
+
"@github/copilot-sdk": "^1.0.3",
|
|
881
|
+
"@openai/codex-sdk": "^0.136.0",
|
|
882
|
+
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
883
|
+
},
|
|
884
|
+
devDependencies: {
|
|
885
|
+
"@agentv/core": "workspace:*",
|
|
886
|
+
"@agentv/sdk": "workspace:*",
|
|
887
|
+
"@types/semver": "^7.7.1",
|
|
888
|
+
execa: "^9.3.0"
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
// src/version-check.ts
|
|
797
893
|
var ANSI_YELLOW = "\x1B[33m";
|
|
798
894
|
var ANSI_RED = "\x1B[31m";
|
|
799
895
|
var ANSI_RESET = "\x1B[0m";
|
|
@@ -858,24 +954,6 @@ function manifestBaseDir(indexPath) {
|
|
|
858
954
|
const dir = path5.dirname(indexPath);
|
|
859
955
|
return path5.basename(dir) === ".internal" ? path5.dirname(dir) : dir;
|
|
860
956
|
}
|
|
861
|
-
function mapGradingAssertions(value) {
|
|
862
|
-
if (!Array.isArray(value)) {
|
|
863
|
-
return void 0;
|
|
864
|
-
}
|
|
865
|
-
return value.map((assertion) => {
|
|
866
|
-
const record = assertion;
|
|
867
|
-
return {
|
|
868
|
-
text: String(record.text ?? ""),
|
|
869
|
-
passed: Boolean(record.passed),
|
|
870
|
-
evidence: typeof record.evidence === "string" ? record.evidence : void 0
|
|
871
|
-
};
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
function readGradingAssertionResults(record) {
|
|
875
|
-
return mapGradingAssertions(
|
|
876
|
-
Array.isArray(record.assertion_results) ? record.assertion_results : record.assertions
|
|
877
|
-
);
|
|
878
|
-
}
|
|
879
957
|
function readNestedGradingScores(record) {
|
|
880
958
|
if (Array.isArray(record.component_results)) {
|
|
881
959
|
return record.component_results;
|
|
@@ -883,12 +961,6 @@ function readNestedGradingScores(record) {
|
|
|
883
961
|
if (Array.isArray(record.scores)) {
|
|
884
962
|
return record.scores;
|
|
885
963
|
}
|
|
886
|
-
if (Array.isArray(record.graders)) {
|
|
887
|
-
return record.graders;
|
|
888
|
-
}
|
|
889
|
-
if (Array.isArray(record.evaluators)) {
|
|
890
|
-
return record.evaluators;
|
|
891
|
-
}
|
|
892
964
|
return void 0;
|
|
893
965
|
}
|
|
894
966
|
function componentLabel(component) {
|
|
@@ -925,7 +997,7 @@ function collectComponentAssertions(value) {
|
|
|
925
997
|
});
|
|
926
998
|
}
|
|
927
999
|
function mapGradingEvaluator(evaluator) {
|
|
928
|
-
const pass =
|
|
1000
|
+
const pass = evaluator.pass === true;
|
|
929
1001
|
const verdict = pass ? "pass" : "fail";
|
|
930
1002
|
const details = evaluator.details && typeof evaluator.details === "object" && !Array.isArray(evaluator.details) ? evaluator.details : void 0;
|
|
931
1003
|
const assertion = evaluator.assertion && typeof evaluator.assertion === "object" && !Array.isArray(evaluator.assertion) ? evaluator.assertion : void 0;
|
|
@@ -939,7 +1011,7 @@ function mapGradingEvaluator(evaluator) {
|
|
|
939
1011
|
if (nestedAssertions.length > 0) {
|
|
940
1012
|
return nestedAssertions;
|
|
941
1013
|
}
|
|
942
|
-
return
|
|
1014
|
+
return [mapComponentAssertion(evaluator)];
|
|
943
1015
|
})(),
|
|
944
1016
|
scores: mapGradingEvaluators(readNestedGradingScores(evaluator)),
|
|
945
1017
|
weight: typeof evaluator.weight === "number" ? evaluator.weight : void 0,
|
|
@@ -1063,9 +1135,7 @@ function hydrateManifestRecord(baseDir, record, options) {
|
|
|
1063
1135
|
const testId = record.test_id ?? "unknown";
|
|
1064
1136
|
const gradingAssertions = grading ? collectComponentAssertions(grading.component_results) : void 0;
|
|
1065
1137
|
const gradingRecord = grading;
|
|
1066
|
-
const gradingScores = mapGradingEvaluators(
|
|
1067
|
-
gradingRecord?.component_results ?? gradingRecord?.graders ?? gradingRecord?.evaluators
|
|
1068
|
-
);
|
|
1138
|
+
const gradingScores = mapGradingEvaluators(gradingRecord?.component_results);
|
|
1069
1139
|
return {
|
|
1070
1140
|
timestamp: record.timestamp,
|
|
1071
1141
|
testId,
|
|
@@ -1081,11 +1151,7 @@ function hydrateManifestRecord(baseDir, record, options) {
|
|
|
1081
1151
|
passed: assertion.passed,
|
|
1082
1152
|
evidence: assertion.evidence
|
|
1083
1153
|
})),
|
|
1084
|
-
scores:
|
|
1085
|
-
// `evaluators` was renamed to `graders` in v4.13 — read both for backwards compat with old artifacts.
|
|
1086
|
-
// TODO: remove `evaluators` fallback once old run directories are no longer in use.
|
|
1087
|
-
gradingScores ?? record.scores
|
|
1088
|
-
),
|
|
1154
|
+
scores: gradingScores ?? record.scores,
|
|
1089
1155
|
tokenUsage: metrics?.tokens ? {
|
|
1090
1156
|
input: metrics.tokens.input,
|
|
1091
1157
|
output: metrics.tokens.output,
|
|
@@ -1149,8 +1215,16 @@ function loadLightweightResults(sourceFile) {
|
|
|
1149
1215
|
executionStatus: record.execution_status,
|
|
1150
1216
|
error: record.error,
|
|
1151
1217
|
costUsd: record.cost_usd,
|
|
1218
|
+
durationMs: record.duration_ms,
|
|
1219
|
+
tokenUsage: record.token_usage,
|
|
1152
1220
|
timestamp: record.timestamp,
|
|
1153
|
-
runtimeSource: record.runtime_source
|
|
1221
|
+
runtimeSource: record.runtime_source,
|
|
1222
|
+
resultDir: record.result_dir,
|
|
1223
|
+
outputPath: record.output_path,
|
|
1224
|
+
answerPath: record.answer_path,
|
|
1225
|
+
gradingPath: record.grading_path,
|
|
1226
|
+
transcriptPath: record.transcript_path,
|
|
1227
|
+
metricsPath: record.metrics_path
|
|
1154
1228
|
}));
|
|
1155
1229
|
}
|
|
1156
1230
|
|
|
@@ -1890,6 +1964,16 @@ function relativeRunPathFromManifestPath(relativeManifestPath) {
|
|
|
1890
1964
|
const manifestDir = path7.posix.dirname(relativeManifestPath);
|
|
1891
1965
|
return path7.posix.basename(manifestDir) === ".internal" ? path7.posix.dirname(manifestDir) : manifestDir;
|
|
1892
1966
|
}
|
|
1967
|
+
function formatPendingMergeWarnings(pendingMerge) {
|
|
1968
|
+
if (!pendingMerge) {
|
|
1969
|
+
return [];
|
|
1970
|
+
}
|
|
1971
|
+
const { temp_branch, target_branch, compare_url } = pendingMerge;
|
|
1972
|
+
const mergeSuffix = compare_url ? `: ${compare_url}` : ".";
|
|
1973
|
+
return [
|
|
1974
|
+
`Warning: results were pushed to '${temp_branch}' instead \u2014 they are not lost. Merge that branch into ${target_branch} with a pull request${mergeSuffix}`
|
|
1975
|
+
];
|
|
1976
|
+
}
|
|
1893
1977
|
async function maybeAutoExportRunArtifacts(payload) {
|
|
1894
1978
|
const config = await loadNormalizedResultsConfig(
|
|
1895
1979
|
payload.cwd,
|
|
@@ -1914,6 +1998,9 @@ async function maybeAutoExportRunArtifacts(payload) {
|
|
|
1914
1998
|
throw new Error(pushResult.block_reason ?? "Results branch push conflict");
|
|
1915
1999
|
}
|
|
1916
2000
|
console.warn(`Warning: skipping results export: ${pushResult.block_reason}`);
|
|
2001
|
+
for (const line of formatPendingMergeWarnings(pushResult.pending_merge)) {
|
|
2002
|
+
console.warn(line);
|
|
2003
|
+
}
|
|
1917
2004
|
return "failed";
|
|
1918
2005
|
}
|
|
1919
2006
|
if (!pushResult.changed) {
|
|
@@ -2716,10 +2803,13 @@ function formatMatrixSummary(results) {
|
|
|
2716
2803
|
return lines.join("\n");
|
|
2717
2804
|
}
|
|
2718
2805
|
|
|
2806
|
+
// src/commands/eval/targets.ts
|
|
2807
|
+
import path12 from "node:path";
|
|
2808
|
+
|
|
2719
2809
|
// ../../packages/core/dist/evaluation/validation/index.js
|
|
2720
2810
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
2721
2811
|
import path11 from "node:path";
|
|
2722
|
-
import { readFile as readFile22, readdir, realpath, stat as
|
|
2812
|
+
import { readFile as readFile22, readdir, realpath, stat as stat3 } from "node:fs/promises";
|
|
2723
2813
|
import path22 from "node:path";
|
|
2724
2814
|
import fg3 from "fast-glob";
|
|
2725
2815
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
@@ -2740,6 +2830,10 @@ async function detectFileType(filePath) {
|
|
|
2740
2830
|
const content = await readFile2(filePath, "utf8");
|
|
2741
2831
|
const parsed = parseYamlValue(content);
|
|
2742
2832
|
if (Array.isArray(parsed)) {
|
|
2833
|
+
const inferred = inferFileTypeFromPath(filePath);
|
|
2834
|
+
if (inferred === "targets") {
|
|
2835
|
+
return inferred;
|
|
2836
|
+
}
|
|
2743
2837
|
return "cases";
|
|
2744
2838
|
}
|
|
2745
2839
|
if (typeof parsed !== "object" || parsed === null) {
|
|
@@ -2774,7 +2868,7 @@ function inferFileTypeFromPath(filePath) {
|
|
|
2774
2868
|
if (isAgentVConfigFileName(basename)) {
|
|
2775
2869
|
return "config";
|
|
2776
2870
|
}
|
|
2777
|
-
if (basename === "
|
|
2871
|
+
if (basename === "providers.yaml" || basename === "providers.yml") {
|
|
2778
2872
|
return "targets";
|
|
2779
2873
|
}
|
|
2780
2874
|
}
|
|
@@ -2801,6 +2895,7 @@ var ASSERTION_TYPES_WITH_ARRAY_VALUE = /* @__PURE__ */ new Set([
|
|
|
2801
2895
|
var PROMPTFOO_ASSERTION_TYPES = /* @__PURE__ */ new Set([
|
|
2802
2896
|
"assert-set",
|
|
2803
2897
|
"llm-rubric",
|
|
2898
|
+
"agent-rubric",
|
|
2804
2899
|
"javascript",
|
|
2805
2900
|
"python",
|
|
2806
2901
|
"webhook",
|
|
@@ -2814,11 +2909,9 @@ var REMOVED_ASSERTION_TYPE_REPLACEMENTS = /* @__PURE__ */ new Map([
|
|
|
2814
2909
|
["rubrics", "llm-rubric with value"],
|
|
2815
2910
|
["rubric", "llm-rubric with value"],
|
|
2816
2911
|
["script-grader", "script"],
|
|
2817
|
-
["code-judge", "script"]
|
|
2818
|
-
["llm-judge", "llm-grader"]
|
|
2912
|
+
["code-judge", "script"]
|
|
2819
2913
|
]);
|
|
2820
2914
|
var UNSUPPORTED_PROMPTFOO_ASSERTION_TYPES = /* @__PURE__ */ new Set([
|
|
2821
|
-
"agent-rubric",
|
|
2822
2915
|
"answer-relevance",
|
|
2823
2916
|
"bleu",
|
|
2824
2917
|
"classifier",
|
|
@@ -2911,6 +3004,9 @@ function staleToolTrajectoryMessage(value) {
|
|
|
2911
3004
|
function staleAuthoredAssertionMessage(value) {
|
|
2912
3005
|
if (typeof value.type !== "string") return void 0;
|
|
2913
3006
|
const type = value.type.replace(/_/g, "-");
|
|
3007
|
+
if (type === "llm-grader" || type === "llm-judge") {
|
|
3008
|
+
return "Authored assertion type 'llm-grader' has been removed. Use 'llm-rubric' for free-form rubric checks or 'agent-rubric' for agentic rubric checks.";
|
|
3009
|
+
}
|
|
2914
3010
|
if (type === "skill-trigger") return staleSkillTriggerMessage(value);
|
|
2915
3011
|
if (type === "tool-trajectory") return staleToolTrajectoryMessage(value);
|
|
2916
3012
|
return void 0;
|
|
@@ -2941,6 +3037,7 @@ var KNOWN_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Set([
|
|
|
2941
3037
|
"input_files",
|
|
2942
3038
|
"prompts",
|
|
2943
3039
|
"tests",
|
|
3040
|
+
"providers",
|
|
2944
3041
|
"graders",
|
|
2945
3042
|
"defaults",
|
|
2946
3043
|
"environment",
|
|
@@ -2976,7 +3073,6 @@ var KNOWN_DEFAULT_TEST_FIELDS = /* @__PURE__ */ new Set([
|
|
|
2976
3073
|
"provider",
|
|
2977
3074
|
"providers",
|
|
2978
3075
|
"prompts",
|
|
2979
|
-
"provider_output",
|
|
2980
3076
|
"assert",
|
|
2981
3077
|
"assert_scoring_function",
|
|
2982
3078
|
"options",
|
|
@@ -2994,8 +3090,6 @@ var KNOWN_EVALUATE_OPTION_FIELDS = /* @__PURE__ */ new Set([
|
|
|
2994
3090
|
"max_eval_time_ms",
|
|
2995
3091
|
"filter_range"
|
|
2996
3092
|
]);
|
|
2997
|
-
var KNOWN_REPEAT_FIELDS = /* @__PURE__ */ new Set(["count", "strategy", "early_exit", "cost_limit_usd"]);
|
|
2998
|
-
var KNOWN_REPEAT_STRATEGIES = /* @__PURE__ */ new Set(["pass_any", "pass_all", "mean", "confidence_interval"]);
|
|
2999
3093
|
var KNOWN_TEST_EXECUTION_FIELDS = /* @__PURE__ */ new Set([
|
|
3000
3094
|
"assert",
|
|
3001
3095
|
"skip_defaults",
|
|
@@ -3009,9 +3103,13 @@ var KNOWN_TEST_EXECUTION_FIELDS = /* @__PURE__ */ new Set([
|
|
|
3009
3103
|
"workspace"
|
|
3010
3104
|
]);
|
|
3011
3105
|
var REMOVED_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Map([
|
|
3106
|
+
[
|
|
3107
|
+
"experiment",
|
|
3108
|
+
"Top-level 'experiment' has been removed from authored eval YAML. Use tags.experiment in the eval file or CLI --experiment at run time."
|
|
3109
|
+
],
|
|
3012
3110
|
[
|
|
3013
3111
|
"imports",
|
|
3014
|
-
"Top-level 'imports' is not supported. Run eval files directly with CLI multi-file selection and tags for grouping. For raw case files, use tests: file://... or string entries under tests. For reusable config, use prompts: file://..., default_test: file://..., and environment: file://... for coding-agent testbeds."
|
|
3112
|
+
"Top-level 'imports' is not supported. Run eval files directly with CLI multi-file selection and tags for grouping. For raw case files, use tests: file://... or string entries under tests. For reusable scenarios, use scenarios: [file://...]. For reusable config, use prompts: file://..., default_test: file://..., and environment: file://... for coding-agent testbeds."
|
|
3015
3113
|
],
|
|
3016
3114
|
[
|
|
3017
3115
|
"expected_output",
|
|
@@ -3025,14 +3123,15 @@ var REMOVED_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Map([
|
|
|
3025
3123
|
"workers",
|
|
3026
3124
|
"'workers' has been removed from eval YAML. Set authored eval concurrency with evaluate_options.max_concurrency."
|
|
3027
3125
|
],
|
|
3028
|
-
["model", "Top-level 'model' is not part of eval YAML. Put model inside
|
|
3126
|
+
["model", "Top-level 'model' is not part of eval YAML. Put model inside providers[].config."],
|
|
3029
3127
|
[
|
|
3030
3128
|
"policy",
|
|
3031
3129
|
"Top-level 'policy' is not part of eval YAML. Put repeat under evaluate_options.repeat, timeout_seconds and threshold at the top level, and budget_usd under evaluate_options."
|
|
3032
3130
|
],
|
|
3131
|
+
["target", "Top-level 'target' has been removed. Use top-level 'providers' instead."],
|
|
3033
3132
|
[
|
|
3034
|
-
"
|
|
3035
|
-
"Top-level '
|
|
3133
|
+
"targets",
|
|
3134
|
+
"Top-level 'targets' has been removed. Use 'providers'; map targets[].id to providers[].label and targets[].provider to providers[].id."
|
|
3036
3135
|
],
|
|
3037
3136
|
[
|
|
3038
3137
|
"eval_cases",
|
|
@@ -3043,10 +3142,10 @@ var REMOVED_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Map([
|
|
|
3043
3142
|
"Top-level 'evalcases' has been removed from authored eval YAML. Use 'tests' instead."
|
|
3044
3143
|
],
|
|
3045
3144
|
["repeat", "Top-level 'repeat' has been removed. Use evaluate_options.repeat instead."],
|
|
3046
|
-
["runs", "Top-level 'runs' has been removed. Use evaluate_options.repeat.
|
|
3145
|
+
["runs", "Top-level 'runs' has been removed. Use a positive integer evaluate_options.repeat."],
|
|
3047
3146
|
[
|
|
3048
3147
|
"early_exit",
|
|
3049
|
-
"Top-level 'early_exit' has been removed. Use evaluate_options.repeat.
|
|
3148
|
+
"Top-level 'early_exit' has been removed. Use a positive integer evaluate_options.repeat."
|
|
3050
3149
|
],
|
|
3051
3150
|
["budget_usd", "Top-level 'budget_usd' has been removed. Use evaluate_options.budget_usd."],
|
|
3052
3151
|
[
|
|
@@ -3057,8 +3156,8 @@ var REMOVED_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Map([
|
|
|
3057
3156
|
"preprocessors",
|
|
3058
3157
|
"Top-level 'preprocessors' has been removed from authored eval YAML. Use default_test.options.transform or assertion-level transform instead."
|
|
3059
3158
|
],
|
|
3060
|
-
["providerPromptMap", "Top-level 'providerPromptMap' is not supported. Use '
|
|
3061
|
-
["provider_prompt_map", "Top-level 'provider_prompt_map' is not supported. Use '
|
|
3159
|
+
["providerPromptMap", "Top-level 'providerPromptMap' is not supported. Use 'providers'."],
|
|
3160
|
+
["provider_prompt_map", "Top-level 'provider_prompt_map' is not supported. Use 'providers'."]
|
|
3062
3161
|
]);
|
|
3063
3162
|
var DEPRECATED_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Map([
|
|
3064
3163
|
["evaluator", "'evaluator' is deprecated. Use 'assert' instead."]
|
|
@@ -3071,7 +3170,6 @@ var KNOWN_TEST_FIELDS = /* @__PURE__ */ new Set([
|
|
|
3071
3170
|
"provider",
|
|
3072
3171
|
"providers",
|
|
3073
3172
|
"prompts",
|
|
3074
|
-
"provider_output",
|
|
3075
3173
|
"input",
|
|
3076
3174
|
"input_files",
|
|
3077
3175
|
"assert",
|
|
@@ -3111,6 +3209,10 @@ REMOVED_TEST_FIELDS.set(
|
|
|
3111
3209
|
"input",
|
|
3112
3210
|
"tests[].input has been removed from authored eval YAML. Put prompt text or chat/system/user messages in top-level 'prompts' and put row-specific data in tests[].vars."
|
|
3113
3211
|
);
|
|
3212
|
+
REMOVED_TEST_FIELDS.set(
|
|
3213
|
+
"provider_output",
|
|
3214
|
+
"tests[].provider_output is not supported in authored AgentV YAML. Use an explicit deterministic target such as provider: cli for fixed outputs, or use a replay/fixture target for captured provider responses."
|
|
3215
|
+
);
|
|
3114
3216
|
REMOVED_TEST_FIELDS.set(
|
|
3115
3217
|
"preprocessors",
|
|
3116
3218
|
"tests[].preprocessors has been removed from authored eval YAML. Use tests[].options.transform or assertion-level transform instead."
|
|
@@ -3215,14 +3317,6 @@ async function validateEvalFile(filePath) {
|
|
|
3215
3317
|
};
|
|
3216
3318
|
}
|
|
3217
3319
|
validateMetadata(parsed, absolutePath, errors);
|
|
3218
|
-
if (parsed.experiment !== void 0 && typeof parsed.experiment !== "string") {
|
|
3219
|
-
errors.push({
|
|
3220
|
-
severity: "error",
|
|
3221
|
-
filePath: absolutePath,
|
|
3222
|
-
location: "experiment",
|
|
3223
|
-
message: "Top-level 'experiment' must be a string run/result grouping label."
|
|
3224
|
-
});
|
|
3225
|
-
}
|
|
3226
3320
|
for (const key of Object.keys(parsed)) {
|
|
3227
3321
|
const removedMessage = REMOVED_TOP_LEVEL_FIELDS.get(key);
|
|
3228
3322
|
if (removedMessage) {
|
|
@@ -3252,6 +3346,7 @@ async function validateEvalFile(filePath) {
|
|
|
3252
3346
|
}
|
|
3253
3347
|
}
|
|
3254
3348
|
await validateEnvironmentConfig(parsed.environment, absolutePath, errors, "environment");
|
|
3349
|
+
await validateProviderEnvironmentFields(parsed.providers, "providers", absolutePath, errors);
|
|
3255
3350
|
await validateSuiteWorkspaceConfigs(parsed, absolutePath, errors);
|
|
3256
3351
|
validateTargetTestbedFields(parsed.target, "target", absolutePath, errors);
|
|
3257
3352
|
validateTargetsTestbedFields(parsed.targets, "targets", absolutePath, errors);
|
|
@@ -3260,10 +3355,15 @@ async function validateEvalFile(filePath) {
|
|
|
3260
3355
|
validateEvaluateOptions(parsed.evaluate_options, "evaluate_options", absolutePath, errors);
|
|
3261
3356
|
validateAssertArray(parsed.assert, "assert", absolutePath, errors, customAssertionTypes);
|
|
3262
3357
|
validateDefaultTest(parsed.default_test, absolutePath, errors, customAssertionTypes);
|
|
3263
|
-
|
|
3358
|
+
const expandedScenarios = await expandScenariosForValidation(
|
|
3359
|
+
parsed.scenarios,
|
|
3360
|
+
absolutePath,
|
|
3361
|
+
errors
|
|
3362
|
+
);
|
|
3363
|
+
await validateScenarios(expandedScenarios, parsed, absolutePath, errors, customAssertionTypes);
|
|
3264
3364
|
const cases = parsed.tests;
|
|
3265
3365
|
const hasImports = collectImportEntries(parsed).length > 0;
|
|
3266
|
-
const hasScenarios = Array.isArray(
|
|
3366
|
+
const hasScenarios = Array.isArray(expandedScenarios);
|
|
3267
3367
|
if (typeof cases === "string") {
|
|
3268
3368
|
await validateRawCaseImportPath(cases, absolutePath, "tests", errors);
|
|
3269
3369
|
await validateCompositionDiagnostics(absolutePath, parsed, errors);
|
|
@@ -3390,7 +3490,7 @@ async function validateEvalFile(filePath) {
|
|
|
3390
3490
|
suiteInputFiles: skipDefaults ? void 0 : parsed.input_files
|
|
3391
3491
|
}) !== void 0 : false;
|
|
3392
3492
|
validateInputField(evalCase.input, `${location}.input`, absolutePath, errors, {
|
|
3393
|
-
required: !hasPromptMdFallback && evalCase.prompts === void 0 && parsed.prompts === void 0
|
|
3493
|
+
required: !hasPromptMdFallback && evalCase.prompts === void 0 && parsed.prompts === void 0
|
|
3394
3494
|
});
|
|
3395
3495
|
const expectedOutputField = evalCase.expected_output;
|
|
3396
3496
|
if (expectedOutputField !== void 0) {
|
|
@@ -3436,7 +3536,7 @@ async function validateEvalFile(filePath) {
|
|
|
3436
3536
|
async function validateTypeScriptEvalConfigFile(filePath) {
|
|
3437
3537
|
const absolutePath = path22.resolve(filePath);
|
|
3438
3538
|
try {
|
|
3439
|
-
const { loadTsEvalSuite } = await import("./ts-eval-loader-
|
|
3539
|
+
const { loadTsEvalSuite } = await import("./ts-eval-loader-3G5GEAEC-6F52JLPP.js");
|
|
3440
3540
|
await loadTsEvalSuite(absolutePath, process.cwd());
|
|
3441
3541
|
return {
|
|
3442
3542
|
valid: true,
|
|
@@ -3501,6 +3601,31 @@ function validateTargetTestbedFields(target, location, filePath, errors) {
|
|
|
3501
3601
|
});
|
|
3502
3602
|
}
|
|
3503
3603
|
}
|
|
3604
|
+
async function validateProviderEnvironmentFields(providers, location, filePath, errors) {
|
|
3605
|
+
const entries = Array.isArray(providers) ? providers : providers === void 0 ? [] : [providers];
|
|
3606
|
+
for (let index = 0; index < entries.length; index++) {
|
|
3607
|
+
const entry = entries[index];
|
|
3608
|
+
if (!isObject(entry)) {
|
|
3609
|
+
continue;
|
|
3610
|
+
}
|
|
3611
|
+
await validateEnvironmentConfig(
|
|
3612
|
+
entry.environment,
|
|
3613
|
+
filePath,
|
|
3614
|
+
errors,
|
|
3615
|
+
`${location}[${index}].environment`
|
|
3616
|
+
);
|
|
3617
|
+
for (const field of ["container", "install"]) {
|
|
3618
|
+
if (entry[field] !== void 0) {
|
|
3619
|
+
errors.push({
|
|
3620
|
+
severity: "error",
|
|
3621
|
+
filePath,
|
|
3622
|
+
location: `${location}[${index}].${field}`,
|
|
3623
|
+
message: `Provider definitions cannot include ${field}; use an environment recipe for testbed setup.`
|
|
3624
|
+
});
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
}
|
|
3504
3629
|
function validateTargetsTestbedFields(targets, location, filePath, errors) {
|
|
3505
3630
|
const entries = Array.isArray(targets) ? targets : targets === void 0 ? [] : [targets];
|
|
3506
3631
|
entries.forEach((entry, index) => {
|
|
@@ -3688,7 +3813,7 @@ async function validateCompositionDiagnostics(filePath, parsed, errors) {
|
|
|
3688
3813
|
severity: "warning",
|
|
3689
3814
|
filePath,
|
|
3690
3815
|
location: entry.location,
|
|
3691
|
-
message: parentHasRuntime ? `Imported suite '${resolvedSuite.displayPath}' defines ${runtimeFields.join(", ")}, but child
|
|
3816
|
+
message: parentHasRuntime ? `Imported suite '${resolvedSuite.displayPath}' defines ${runtimeFields.join(", ")}, but child providers and run controls are ignored by legacy tests[].include suite imports. Prefer running eval files directly with CLI multi-file selection and tags.` : `Imported suite '${resolvedSuite.displayPath}' defines ${runtimeFields.join(", ")}, but child providers and run controls are ignored by legacy tests[].include suite imports. Prefer running eval files directly with CLI multi-file selection and tags.`
|
|
3692
3817
|
});
|
|
3693
3818
|
}
|
|
3694
3819
|
continue;
|
|
@@ -3710,7 +3835,9 @@ async function validateCompositionDiagnostics(filePath, parsed, errors) {
|
|
|
3710
3835
|
}
|
|
3711
3836
|
var WRAPPER_RUNTIME_CONTROL_FIELDS = [
|
|
3712
3837
|
"experiment",
|
|
3838
|
+
"providers",
|
|
3713
3839
|
"target",
|
|
3840
|
+
"targets",
|
|
3714
3841
|
"repeat",
|
|
3715
3842
|
"timeout_seconds",
|
|
3716
3843
|
"evaluate_options",
|
|
@@ -3906,10 +4033,18 @@ function validateDefaultTest(defaultTest, filePath, errors, customAssertionTypes
|
|
|
3906
4033
|
severity: "error",
|
|
3907
4034
|
filePath,
|
|
3908
4035
|
location: `default_test.${key}`,
|
|
3909
|
-
message: "Invalid default_test field. Supported fields: vars, provider, providers, prompts,
|
|
4036
|
+
message: "Invalid default_test field. Supported fields: vars, provider, providers, prompts, assert, assert_scoring_function, options, threshold, metadata."
|
|
3910
4037
|
});
|
|
3911
4038
|
}
|
|
3912
4039
|
}
|
|
4040
|
+
if (defaultTest.provider_output !== void 0) {
|
|
4041
|
+
errors.push({
|
|
4042
|
+
severity: "error",
|
|
4043
|
+
filePath,
|
|
4044
|
+
location: "default_test.provider_output",
|
|
4045
|
+
message: "default_test.provider_output is not supported in authored AgentV YAML. Use an explicit deterministic target such as provider: cli for fixed outputs, or use a replay/fixture target for captured provider responses."
|
|
4046
|
+
});
|
|
4047
|
+
}
|
|
3913
4048
|
if (defaultTest.expected_output !== void 0) {
|
|
3914
4049
|
errors.push({
|
|
3915
4050
|
severity: "error",
|
|
@@ -4011,10 +4146,8 @@ async function validateScenarios(scenarios, parsed, filePath, errors, customAsse
|
|
|
4011
4146
|
}
|
|
4012
4147
|
for (let testIndex = 0; testIndex < scenario.tests.length; testIndex++) {
|
|
4013
4148
|
const test = scenario.tests[testIndex];
|
|
4014
|
-
const everyConfigProvidesInput = scenarioConfigs.length > 0 && scenarioConfigs.every(
|
|
4015
|
-
|
|
4016
|
-
);
|
|
4017
|
-
const requireInput = isObject(test) && parsed.prompts === void 0 && test.prompts === void 0 && test.provider_output === void 0 && !everyConfigProvidesInput;
|
|
4149
|
+
const everyConfigProvidesInput = scenarioConfigs.length > 0 && scenarioConfigs.every((config) => isObject(config) && config.prompts !== void 0);
|
|
4150
|
+
const requireInput = isObject(test) && parsed.prompts === void 0 && test.prompts === void 0 && !everyConfigProvidesInput;
|
|
4018
4151
|
await validateScenarioTestLikeRow(
|
|
4019
4152
|
test,
|
|
4020
4153
|
`${scenarioLocation}.tests[${testIndex}]`,
|
|
@@ -4026,6 +4159,35 @@ async function validateScenarios(scenarios, parsed, filePath, errors, customAsse
|
|
|
4026
4159
|
}
|
|
4027
4160
|
}
|
|
4028
4161
|
}
|
|
4162
|
+
async function expandScenariosForValidation(scenarios, filePath, errors) {
|
|
4163
|
+
if (!Array.isArray(scenarios)) {
|
|
4164
|
+
return scenarios;
|
|
4165
|
+
}
|
|
4166
|
+
const expanded = [];
|
|
4167
|
+
for (let scenarioIndex = 0; scenarioIndex < scenarios.length; scenarioIndex++) {
|
|
4168
|
+
const scenario = scenarios[scenarioIndex];
|
|
4169
|
+
if (!isScenarioFileReference(scenario)) {
|
|
4170
|
+
expanded.push(scenario);
|
|
4171
|
+
continue;
|
|
4172
|
+
}
|
|
4173
|
+
try {
|
|
4174
|
+
const externalScenarios = await resolveScenarioFileReference(
|
|
4175
|
+
scenario,
|
|
4176
|
+
path22.dirname(filePath)
|
|
4177
|
+
);
|
|
4178
|
+
expanded.push(...externalScenarios);
|
|
4179
|
+
} catch (error) {
|
|
4180
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4181
|
+
errors.push({
|
|
4182
|
+
severity: "error",
|
|
4183
|
+
filePath,
|
|
4184
|
+
location: `scenarios[${scenarioIndex}]`,
|
|
4185
|
+
message
|
|
4186
|
+
});
|
|
4187
|
+
}
|
|
4188
|
+
}
|
|
4189
|
+
return expanded;
|
|
4190
|
+
}
|
|
4029
4191
|
async function validateScenarioTestLikeRow(row, location, filePath, errors, customAssertionTypes, options) {
|
|
4030
4192
|
if (!isObject(row)) {
|
|
4031
4193
|
errors.push({
|
|
@@ -4118,7 +4280,7 @@ async function validateScenarioTestLikeRow(row, location, filePath, errors, cust
|
|
|
4118
4280
|
}
|
|
4119
4281
|
const targets = row.providers !== void 0 ? row.providers : row.provider;
|
|
4120
4282
|
if (targets !== void 0) {
|
|
4121
|
-
|
|
4283
|
+
await validateProviderEnvironmentFields(targets, `${location}.providers`, filePath, errors);
|
|
4122
4284
|
}
|
|
4123
4285
|
}
|
|
4124
4286
|
function validateEvaluateOptions(evaluateOptions, location, filePath, errors) {
|
|
@@ -4208,7 +4370,12 @@ function validateEvaluateOptionsRepeat(repeat, location, filePath, errors) {
|
|
|
4208
4370
|
}
|
|
4209
4371
|
return;
|
|
4210
4372
|
}
|
|
4211
|
-
|
|
4373
|
+
errors.push({
|
|
4374
|
+
severity: "error",
|
|
4375
|
+
filePath,
|
|
4376
|
+
location,
|
|
4377
|
+
message: `Invalid '${location}' field (must be a positive integer). The repeat object shape has been removed; use ${location}: 2.`
|
|
4378
|
+
});
|
|
4212
4379
|
}
|
|
4213
4380
|
function validateFilterRange(filterRange, location, filePath, errors) {
|
|
4214
4381
|
if (filterRange === void 0 || typeof filterRange === "string") {
|
|
@@ -4227,57 +4394,12 @@ function validateRepeatOverride(repeat, location, filePath, errors) {
|
|
|
4227
4394
|
if (repeat === void 0) {
|
|
4228
4395
|
return;
|
|
4229
4396
|
}
|
|
4230
|
-
if (!
|
|
4397
|
+
if (typeof repeat !== "number" || !Number.isInteger(repeat) || repeat < 1) {
|
|
4231
4398
|
errors.push({
|
|
4232
4399
|
severity: "error",
|
|
4233
4400
|
filePath,
|
|
4234
4401
|
location,
|
|
4235
|
-
message: "Invalid 'repeat' field (must be
|
|
4236
|
-
});
|
|
4237
|
-
return;
|
|
4238
|
-
}
|
|
4239
|
-
for (const key of Object.keys(repeat)) {
|
|
4240
|
-
if (!KNOWN_REPEAT_FIELDS.has(key)) {
|
|
4241
|
-
errors.push({
|
|
4242
|
-
severity: "error",
|
|
4243
|
-
filePath,
|
|
4244
|
-
location: `${location}.${key}`,
|
|
4245
|
-
message: "Invalid repeat field. Supported fields: count, strategy, early_exit, cost_limit_usd."
|
|
4246
|
-
});
|
|
4247
|
-
}
|
|
4248
|
-
}
|
|
4249
|
-
if (typeof repeat.count !== "number" || !Number.isInteger(repeat.count) || repeat.count < 1) {
|
|
4250
|
-
errors.push({
|
|
4251
|
-
severity: "error",
|
|
4252
|
-
filePath,
|
|
4253
|
-
location: `${location}.count`,
|
|
4254
|
-
message: "Invalid 'count' field (must be a positive integer)"
|
|
4255
|
-
});
|
|
4256
|
-
}
|
|
4257
|
-
if (repeat.strategy !== void 0 && (typeof repeat.strategy !== "string" || !KNOWN_REPEAT_STRATEGIES.has(repeat.strategy))) {
|
|
4258
|
-
errors.push({
|
|
4259
|
-
severity: "error",
|
|
4260
|
-
filePath,
|
|
4261
|
-
location: `${location}.strategy`,
|
|
4262
|
-
message: "Invalid 'strategy' field (must be pass_any, pass_all, mean, or confidence_interval; use pass_any instead of removed pass_at_k)"
|
|
4263
|
-
});
|
|
4264
|
-
}
|
|
4265
|
-
const earlyExit = repeat.early_exit;
|
|
4266
|
-
if (earlyExit !== void 0 && typeof earlyExit !== "boolean") {
|
|
4267
|
-
errors.push({
|
|
4268
|
-
severity: "error",
|
|
4269
|
-
filePath,
|
|
4270
|
-
location: `${location}.early_exit`,
|
|
4271
|
-
message: "Invalid 'early_exit' field (must be a boolean)"
|
|
4272
|
-
});
|
|
4273
|
-
}
|
|
4274
|
-
const costLimit = repeat.cost_limit_usd;
|
|
4275
|
-
if (costLimit !== void 0 && (typeof costLimit !== "number" || costLimit < 0)) {
|
|
4276
|
-
errors.push({
|
|
4277
|
-
severity: "error",
|
|
4278
|
-
filePath,
|
|
4279
|
-
location: `${location}.cost_limit_usd`,
|
|
4280
|
-
message: "Invalid 'cost_limit_usd' field (must be a non-negative number)"
|
|
4402
|
+
message: "Invalid 'repeat' field (must be a positive integer). The repeat object shape has been removed; use repeat: 2."
|
|
4281
4403
|
});
|
|
4282
4404
|
}
|
|
4283
4405
|
}
|
|
@@ -4719,7 +4841,7 @@ async function validateRawCaseImportPath(testsPath, filePath, location, errors)
|
|
|
4719
4841
|
let caseIndex = 0;
|
|
4720
4842
|
for (const casePath of caseFiles) {
|
|
4721
4843
|
const statPath = casePath.match(/\.(?:mjs|cjs|js|py):[^/\\:]+$/i) ? casePath.slice(0, casePath.lastIndexOf(":")) : casePath;
|
|
4722
|
-
const pathStat = await
|
|
4844
|
+
const pathStat = await stat3(statPath).catch(() => void 0);
|
|
4723
4845
|
const externalCases = pathStat?.isDirectory() ? await loadCasesFromDirectory(casePath) : await loadCasesFromFile(casePath);
|
|
4724
4846
|
for (const externalCase of externalCases) {
|
|
4725
4847
|
await validateWorkspaceConfig(
|
|
@@ -5155,6 +5277,11 @@ async function validateCasesFile(filePath) {
|
|
|
5155
5277
|
};
|
|
5156
5278
|
}
|
|
5157
5279
|
var LEGACY_ENV_PATTERN = /\$\{\{\s*([A-Z_][A-Z0-9_]*)\s*\}\}/g;
|
|
5280
|
+
var REMOVED_RUNNER_BATCHING_FIELDS = /* @__PURE__ */ new Set([
|
|
5281
|
+
"batch_requests",
|
|
5282
|
+
"provider_batching",
|
|
5283
|
+
"providerBatching"
|
|
5284
|
+
]);
|
|
5158
5285
|
function isObject3(value) {
|
|
5159
5286
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5160
5287
|
}
|
|
@@ -5189,7 +5316,7 @@ function validateLegacyEnvTemplates(value, filePath, location, errors) {
|
|
|
5189
5316
|
}
|
|
5190
5317
|
}
|
|
5191
5318
|
}
|
|
5192
|
-
var COMMON_SETTINGS = new Set(
|
|
5319
|
+
var COMMON_SETTINGS = new Set(COMMON_PROVIDER_SETTINGS);
|
|
5193
5320
|
var RETRY_SETTINGS = /* @__PURE__ */ new Set([
|
|
5194
5321
|
"max_retries",
|
|
5195
5322
|
"retry_initial_delay_ms",
|
|
@@ -5435,6 +5562,7 @@ function validateUnknownSettings(target, provider, absolutePath, location, error
|
|
|
5435
5562
|
"name",
|
|
5436
5563
|
"label",
|
|
5437
5564
|
"provider",
|
|
5565
|
+
"provider_spec",
|
|
5438
5566
|
"config",
|
|
5439
5567
|
"prompts",
|
|
5440
5568
|
"transform",
|
|
@@ -5458,6 +5586,9 @@ function validateUnknownSettings(target, provider, absolutePath, location, error
|
|
|
5458
5586
|
};
|
|
5459
5587
|
const removedForProvider = removedPerProvider[provider];
|
|
5460
5588
|
for (const key of Object.keys(target)) {
|
|
5589
|
+
if (REMOVED_RUNNER_BATCHING_FIELDS.has(key)) {
|
|
5590
|
+
continue;
|
|
5591
|
+
}
|
|
5461
5592
|
if (removedFields.has(key)) {
|
|
5462
5593
|
errors.push({
|
|
5463
5594
|
severity: "warning",
|
|
@@ -5476,15 +5607,6 @@ function validateUnknownSettings(target, provider, absolutePath, location, error
|
|
|
5476
5607
|
});
|
|
5477
5608
|
continue;
|
|
5478
5609
|
}
|
|
5479
|
-
if (key === "provider_batching") {
|
|
5480
|
-
errors.push({
|
|
5481
|
-
severity: "error",
|
|
5482
|
-
filePath: absolutePath,
|
|
5483
|
-
location: `${location}.${key}`,
|
|
5484
|
-
message: "The 'provider_batching' field has been removed. Use 'batch_requests' instead."
|
|
5485
|
-
});
|
|
5486
|
-
continue;
|
|
5487
|
-
}
|
|
5488
5610
|
if (removedForProvider?.has(key)) {
|
|
5489
5611
|
errors.push({
|
|
5490
5612
|
severity: "error",
|
|
@@ -5504,6 +5626,22 @@ function validateUnknownSettings(target, provider, absolutePath, location, error
|
|
|
5504
5626
|
}
|
|
5505
5627
|
}
|
|
5506
5628
|
}
|
|
5629
|
+
function buildRemovedRunnerBatchingMessage(field) {
|
|
5630
|
+
return `The '${field}' field has been removed. Runner-level batching was removed; providers should implement internal queueing/batching behind per-request invocation.`;
|
|
5631
|
+
}
|
|
5632
|
+
function validateRemovedRunnerBatchingFields(target, absolutePath, location, errors) {
|
|
5633
|
+
for (const key of Object.keys(target)) {
|
|
5634
|
+
if (!REMOVED_RUNNER_BATCHING_FIELDS.has(key)) {
|
|
5635
|
+
continue;
|
|
5636
|
+
}
|
|
5637
|
+
errors.push({
|
|
5638
|
+
severity: "error",
|
|
5639
|
+
filePath: absolutePath,
|
|
5640
|
+
location: `${location}.${key}`,
|
|
5641
|
+
message: buildRemovedRunnerBatchingMessage(key)
|
|
5642
|
+
});
|
|
5643
|
+
}
|
|
5644
|
+
}
|
|
5507
5645
|
async function validateTargetsFile(filePath) {
|
|
5508
5646
|
const errors = [];
|
|
5509
5647
|
const absolutePath = path42.resolve(filePath);
|
|
@@ -5619,11 +5757,11 @@ async function validateTargetsFile(filePath) {
|
|
|
5619
5757
|
}
|
|
5620
5758
|
return result;
|
|
5621
5759
|
}
|
|
5622
|
-
if (!isObject3(parsed)) {
|
|
5760
|
+
if (!Array.isArray(parsed) && !isObject3(parsed)) {
|
|
5623
5761
|
errors.push({
|
|
5624
5762
|
severity: "error",
|
|
5625
5763
|
filePath: absolutePath,
|
|
5626
|
-
message: "File must contain a YAML object"
|
|
5764
|
+
message: "File must contain a YAML array or an object with a providers array"
|
|
5627
5765
|
});
|
|
5628
5766
|
return {
|
|
5629
5767
|
valid: false,
|
|
@@ -5632,22 +5770,22 @@ async function validateTargetsFile(filePath) {
|
|
|
5632
5770
|
errors
|
|
5633
5771
|
};
|
|
5634
5772
|
}
|
|
5635
|
-
if (Array.isArray(parsed.
|
|
5773
|
+
if (isObject3(parsed) && Array.isArray(parsed.targets)) {
|
|
5636
5774
|
errors.push({
|
|
5637
5775
|
severity: "error",
|
|
5638
5776
|
filePath: absolutePath,
|
|
5639
|
-
location: "
|
|
5640
|
-
message: "Top-level '
|
|
5777
|
+
location: "targets",
|
|
5778
|
+
message: "Top-level 'targets' has been removed. Use 'providers'; map targets[].id to providers[].label and targets[].provider to providers[].id."
|
|
5641
5779
|
});
|
|
5642
5780
|
}
|
|
5643
|
-
const
|
|
5644
|
-
const rawTargets = isObject3(rawParsed) && Array.isArray(rawParsed.
|
|
5645
|
-
if (!Array.isArray(
|
|
5781
|
+
const providers = Array.isArray(parsed) ? parsed : parsed.providers;
|
|
5782
|
+
const rawTargets = Array.isArray(rawParsed) ? rawParsed : isObject3(rawParsed) && Array.isArray(rawParsed.providers) ? rawParsed.providers : [];
|
|
5783
|
+
if (!Array.isArray(providers)) {
|
|
5646
5784
|
errors.push({
|
|
5647
5785
|
severity: "error",
|
|
5648
5786
|
filePath: absolutePath,
|
|
5649
|
-
location: "
|
|
5650
|
-
message: "Missing or invalid '
|
|
5787
|
+
location: "providers",
|
|
5788
|
+
message: "Missing or invalid 'providers' field (must be an array)"
|
|
5651
5789
|
});
|
|
5652
5790
|
return {
|
|
5653
5791
|
valid: errors.length === 0,
|
|
@@ -5657,22 +5795,24 @@ async function validateTargetsFile(filePath) {
|
|
|
5657
5795
|
};
|
|
5658
5796
|
}
|
|
5659
5797
|
const knownProviders = [...KNOWN_PROVIDERS];
|
|
5660
|
-
for (let i = 0; i <
|
|
5661
|
-
const
|
|
5662
|
-
const location = `
|
|
5663
|
-
if (!isObject3(
|
|
5798
|
+
for (let i = 0; i < providers.length; i++) {
|
|
5799
|
+
const providerEntry = providers[i];
|
|
5800
|
+
const location = `providers[${i}]`;
|
|
5801
|
+
if (!isObject3(providerEntry)) {
|
|
5664
5802
|
errors.push({
|
|
5665
5803
|
severity: "error",
|
|
5666
5804
|
filePath: absolutePath,
|
|
5667
5805
|
location,
|
|
5668
|
-
message: "
|
|
5806
|
+
message: "Provider must be an object"
|
|
5669
5807
|
});
|
|
5670
5808
|
continue;
|
|
5671
5809
|
}
|
|
5672
|
-
validateLegacyEnvTemplates(rawTargets[i] ??
|
|
5810
|
+
validateLegacyEnvTemplates(rawTargets[i] ?? providerEntry, absolutePath, location, errors);
|
|
5673
5811
|
let normalizedTarget;
|
|
5674
5812
|
try {
|
|
5675
|
-
normalizedTarget =
|
|
5813
|
+
normalizedTarget = normalizeProviderDefinition(providerEntry, {
|
|
5814
|
+
location
|
|
5815
|
+
});
|
|
5676
5816
|
} catch (error) {
|
|
5677
5817
|
errors.push({
|
|
5678
5818
|
severity: "error",
|
|
@@ -5682,7 +5822,7 @@ async function validateTargetsFile(filePath) {
|
|
|
5682
5822
|
});
|
|
5683
5823
|
}
|
|
5684
5824
|
for (const warning of findDeprecatedCamelCaseTargetWarnings(
|
|
5685
|
-
normalizedTarget ??
|
|
5825
|
+
normalizedTarget ?? providerEntry,
|
|
5686
5826
|
location
|
|
5687
5827
|
)) {
|
|
5688
5828
|
const fieldMatch = warning.message.match(/field '([^']+)'/);
|
|
@@ -5693,10 +5833,10 @@ async function validateTargetsFile(filePath) {
|
|
|
5693
5833
|
severity: "error",
|
|
5694
5834
|
filePath: absolutePath,
|
|
5695
5835
|
location: warning.location,
|
|
5696
|
-
message: `camelCase field '${field}' is no longer supported in
|
|
5836
|
+
message: `camelCase field '${field}' is no longer supported in providers.yaml. Use '${replacement}' instead.`
|
|
5697
5837
|
});
|
|
5698
5838
|
}
|
|
5699
|
-
const id =
|
|
5839
|
+
const id = providerEntry.id;
|
|
5700
5840
|
if (typeof id !== "string" || id.trim().length === 0) {
|
|
5701
5841
|
errors.push({
|
|
5702
5842
|
severity: "error",
|
|
@@ -5705,23 +5845,15 @@ async function validateTargetsFile(filePath) {
|
|
|
5705
5845
|
message: "Missing or invalid 'id' field (must be a non-empty string)"
|
|
5706
5846
|
});
|
|
5707
5847
|
}
|
|
5708
|
-
if (typeof
|
|
5709
|
-
errors.push({
|
|
5710
|
-
severity: "error",
|
|
5711
|
-
filePath: absolutePath,
|
|
5712
|
-
location: `${location}.label`,
|
|
5713
|
-
message: "The target 'label' field has been removed. Use 'id' instead."
|
|
5714
|
-
});
|
|
5715
|
-
}
|
|
5716
|
-
if (typeof target.name === "string" && target.name.trim().length > 0) {
|
|
5848
|
+
if (typeof providerEntry.name === "string" && providerEntry.name.trim().length > 0) {
|
|
5717
5849
|
errors.push({
|
|
5718
5850
|
severity: "error",
|
|
5719
5851
|
filePath: absolutePath,
|
|
5720
5852
|
location: `${location}.name`,
|
|
5721
|
-
message: "The
|
|
5853
|
+
message: "The provider 'name' field has been removed. Use 'label' instead."
|
|
5722
5854
|
});
|
|
5723
5855
|
}
|
|
5724
|
-
const effectiveTarget = normalizedTarget ??
|
|
5856
|
+
const effectiveTarget = normalizedTarget ?? providerEntry;
|
|
5725
5857
|
const provider = effectiveTarget.provider;
|
|
5726
5858
|
const rawTarget = rawTargets[i];
|
|
5727
5859
|
const rawUseTarget = isObject3(rawTarget) ? rawTarget.use_target : void 0;
|
|
@@ -5730,7 +5862,7 @@ async function validateTargetsFile(filePath) {
|
|
|
5730
5862
|
severity: "error",
|
|
5731
5863
|
filePath: absolutePath,
|
|
5732
5864
|
location: `${location}.use_target`,
|
|
5733
|
-
message: "The 'use_target' field has been removed from authored
|
|
5865
|
+
message: "The 'use_target' field has been removed from authored providers.yaml definitions. Define a concrete provider entry instead."
|
|
5734
5866
|
});
|
|
5735
5867
|
}
|
|
5736
5868
|
const providerValue = typeof provider === "string" ? provider.trim().toLowerCase() : void 0;
|
|
@@ -5739,24 +5871,25 @@ async function validateTargetsFile(filePath) {
|
|
|
5739
5871
|
errors.push({
|
|
5740
5872
|
severity: "error",
|
|
5741
5873
|
filePath: absolutePath,
|
|
5742
|
-
location: `${location}.
|
|
5743
|
-
message: "Missing or invalid '
|
|
5874
|
+
location: `${location}.id`,
|
|
5875
|
+
message: "Missing or invalid 'id' field (must be a non-empty provider backend string)"
|
|
5744
5876
|
});
|
|
5745
5877
|
} else if (!isTemplated && (providerValue === "claude" || providerValue === "copilot")) {
|
|
5746
5878
|
errors.push({
|
|
5747
5879
|
severity: "error",
|
|
5748
5880
|
filePath: absolutePath,
|
|
5749
|
-
location: `${location}.
|
|
5881
|
+
location: `${location}.id`,
|
|
5750
5882
|
message: `Ambiguous provider '${providerValue}' is not supported. Choose an explicit provider such as '${providerValue}-cli' or '${providerValue}-sdk'.`
|
|
5751
5883
|
});
|
|
5752
5884
|
} else if (typeof provider === "string" && !isTemplated && !knownProviders.includes(provider)) {
|
|
5753
5885
|
errors.push({
|
|
5754
5886
|
severity: "warning",
|
|
5755
5887
|
filePath: absolutePath,
|
|
5756
|
-
location: `${location}.
|
|
5888
|
+
location: `${location}.id`,
|
|
5757
5889
|
message: `Unknown provider '${provider}'. Known providers: ${knownProviders.join(", ")}`
|
|
5758
5890
|
});
|
|
5759
5891
|
}
|
|
5892
|
+
validateRemovedRunnerBatchingFields(effectiveTarget, absolutePath, location, errors);
|
|
5760
5893
|
if (providerValue === "cli") {
|
|
5761
5894
|
validateCliSettings(effectiveTarget, absolutePath, location, errors);
|
|
5762
5895
|
}
|
|
@@ -5906,6 +6039,7 @@ async function validateConfigFile(filePath, options = {}) {
|
|
|
5906
6039
|
"results",
|
|
5907
6040
|
"repo_resolvers",
|
|
5908
6041
|
"refs",
|
|
6042
|
+
"providers",
|
|
5909
6043
|
"targets",
|
|
5910
6044
|
"graders",
|
|
5911
6045
|
"tests",
|
|
@@ -5942,7 +6076,7 @@ async function validateConfigFile(filePath, options = {}) {
|
|
|
5942
6076
|
}
|
|
5943
6077
|
function validateComposableGraph(errors, filePath, config) {
|
|
5944
6078
|
try {
|
|
5945
|
-
normalizeComposableConfigGraph(config, filePath);
|
|
6079
|
+
normalizeComposableConfigGraph(config, filePath, { allowExecutionDefaultFields: true });
|
|
5946
6080
|
} catch (error) {
|
|
5947
6081
|
addError(errors, filePath, void 0, error.message);
|
|
5948
6082
|
}
|
|
@@ -6453,13 +6587,13 @@ var ANSI_RESET3 = "\x1B[0m";
|
|
|
6453
6587
|
function isTTY() {
|
|
6454
6588
|
return process.stdout.isTTY ?? false;
|
|
6455
6589
|
}
|
|
6456
|
-
function resolveUseTarget(name, definitions, env,
|
|
6590
|
+
function resolveUseTarget(name, definitions, env, providersFilePath) {
|
|
6457
6591
|
const maxDepth = 5;
|
|
6458
6592
|
let current = definitions.find((d) => d.name === name);
|
|
6459
6593
|
if (!current) {
|
|
6460
|
-
const available =
|
|
6594
|
+
const available = listProviderLabels(definitions).join(", ");
|
|
6461
6595
|
throw new Error(
|
|
6462
|
-
`
|
|
6596
|
+
`Provider '${name}' not found in ${providersFilePath}. Available providers: ${available}`
|
|
6463
6597
|
);
|
|
6464
6598
|
}
|
|
6465
6599
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
@@ -6470,27 +6604,82 @@ function resolveUseTarget(name, definitions, env, targetsFilePath) {
|
|
|
6470
6604
|
const envMatch = raw.match(/^\$\{\{\s*([A-Z0-9_]+)\s*\}\}$/i);
|
|
6471
6605
|
const resolved = envMatch ? env[envMatch[1]] ?? "" : raw;
|
|
6472
6606
|
if (resolved.trim().length === 0) break;
|
|
6473
|
-
const next = definitions.find(
|
|
6607
|
+
const next = definitions.find(
|
|
6608
|
+
(d) => d.name === resolved.trim()
|
|
6609
|
+
);
|
|
6474
6610
|
if (!next) {
|
|
6475
|
-
const available =
|
|
6611
|
+
const available = listProviderLabels(definitions).join(", ");
|
|
6476
6612
|
throw new Error(
|
|
6477
|
-
`
|
|
6613
|
+
`Provider '${name}' use_target '${resolved.trim()}' not found in ${providersFilePath}. Available providers: ${available}`
|
|
6478
6614
|
);
|
|
6479
6615
|
}
|
|
6480
6616
|
current = next;
|
|
6481
6617
|
}
|
|
6482
6618
|
return current;
|
|
6483
6619
|
}
|
|
6484
|
-
async function
|
|
6620
|
+
async function readTestSuiteProvider(testFilePath) {
|
|
6485
6621
|
const metadata = await readTestSuiteMetadata(testFilePath);
|
|
6486
6622
|
return metadata.target;
|
|
6487
6623
|
}
|
|
6488
|
-
function
|
|
6489
|
-
|
|
6624
|
+
async function readProviderCatalog(options) {
|
|
6625
|
+
if (!options.explicitProvidersPath && options.providerDefinitions) {
|
|
6626
|
+
return {
|
|
6627
|
+
definitions: options.providerDefinitions,
|
|
6628
|
+
sourcePath: options.providerDefinitionsSource ?? ".agentv/config.yaml:providers"
|
|
6629
|
+
};
|
|
6630
|
+
}
|
|
6631
|
+
if (!options.explicitProvidersPath && options.requireExplicitProviderCatalog) {
|
|
6632
|
+
throw new Error(
|
|
6633
|
+
"No provider catalog configured. Add `providers:` to .agentv/config.yaml, use `providers: file://providers.yaml`, or pass --providers <path>."
|
|
6634
|
+
);
|
|
6635
|
+
}
|
|
6636
|
+
const providersFilePath = await discoverProvidersFile({
|
|
6637
|
+
explicitPath: options.explicitProvidersPath,
|
|
6638
|
+
testFilePath: options.testFilePath,
|
|
6639
|
+
repoRoot: options.repoRoot,
|
|
6640
|
+
cwd: options.cwd,
|
|
6641
|
+
allowLegacyTargetFiles: options.allowLegacyTargetFiles
|
|
6642
|
+
});
|
|
6643
|
+
await validateProviderCatalogFile(providersFilePath);
|
|
6644
|
+
return {
|
|
6645
|
+
definitions: await readProviderDefinitions(providersFilePath),
|
|
6646
|
+
sourcePath: providersFilePath
|
|
6647
|
+
};
|
|
6648
|
+
}
|
|
6649
|
+
async function validateProviderCatalogFile(providersFilePath) {
|
|
6650
|
+
const validationResult = await validateTargetsFile(providersFilePath);
|
|
6651
|
+
const warnings = validationResult.errors.filter((e) => e.severity === "warning");
|
|
6652
|
+
const useColors2 = isTTY();
|
|
6653
|
+
if (warnings.length > 0) {
|
|
6654
|
+
console.warn(`
|
|
6655
|
+
Warnings in ${providersFilePath}:`);
|
|
6656
|
+
for (const warning of warnings) {
|
|
6657
|
+
const location = warning.location ? ` [${warning.location}]` : "";
|
|
6658
|
+
const prefix = useColors2 ? `${ANSI_YELLOW3} \u26A0${ANSI_RESET3}` : " \u26A0";
|
|
6659
|
+
const message = useColors2 ? `${ANSI_YELLOW3}${warning.message}${ANSI_RESET3}` : warning.message;
|
|
6660
|
+
console.warn(`${prefix}${location} ${message}`);
|
|
6661
|
+
}
|
|
6662
|
+
console.warn("");
|
|
6663
|
+
}
|
|
6664
|
+
const errors = validationResult.errors.filter((e) => e.severity === "error");
|
|
6665
|
+
if (errors.length > 0) {
|
|
6666
|
+
console.error(`
|
|
6667
|
+
Errors in ${providersFilePath}:`);
|
|
6668
|
+
for (const error of errors) {
|
|
6669
|
+
const location = error.location ? ` [${error.location}]` : "";
|
|
6670
|
+
const prefix = useColors2 ? `${ANSI_RED3} \u2717${ANSI_RESET3}` : " \u2717";
|
|
6671
|
+
const message = useColors2 ? `${ANSI_RED3}${error.message}${ANSI_RESET3}` : error.message;
|
|
6672
|
+
console.error(`${prefix}${location} ${message}`);
|
|
6673
|
+
}
|
|
6674
|
+
throw new Error(`Providers file validation failed with ${errors.length} error(s)`);
|
|
6675
|
+
}
|
|
6676
|
+
}
|
|
6677
|
+
function pickProviderLabel(options) {
|
|
6678
|
+
const cliName = options.cliProviderLabel?.trim();
|
|
6490
6679
|
if (cliName && cliName !== "default") {
|
|
6491
6680
|
return { name: cliName, source: "cli" };
|
|
6492
6681
|
}
|
|
6493
|
-
const fileName = options.
|
|
6682
|
+
const fileName = options.fileProviderLabel?.trim();
|
|
6494
6683
|
if (fileName && fileName.length > 0) {
|
|
6495
6684
|
return { name: fileName, source: "test-file" };
|
|
6496
6685
|
}
|
|
@@ -6501,12 +6690,12 @@ function withModelOverride(target, modelOverride) {
|
|
|
6501
6690
|
return model && model.length > 0 ? { ...target, model } : target;
|
|
6502
6691
|
}
|
|
6503
6692
|
function overlayTargetDefinition(params) {
|
|
6504
|
-
const { spec, definitions, env,
|
|
6693
|
+
const { spec, definitions, env, providersFilePath } = params;
|
|
6505
6694
|
if (!spec?.definition) {
|
|
6506
6695
|
return void 0;
|
|
6507
6696
|
}
|
|
6508
6697
|
if (spec.extends) {
|
|
6509
|
-
const base = resolveUseTarget(spec.extends, definitions, env,
|
|
6698
|
+
const base = resolveUseTarget(spec.extends, definitions, env, providersFilePath);
|
|
6510
6699
|
return {
|
|
6511
6700
|
...base,
|
|
6512
6701
|
...spec.definition,
|
|
@@ -6518,82 +6707,86 @@ function overlayTargetDefinition(params) {
|
|
|
6518
6707
|
function definitionsWithEffectiveTarget(definitions, effective) {
|
|
6519
6708
|
return [effective, ...definitions.filter((definition) => definition.name !== effective.name)];
|
|
6520
6709
|
}
|
|
6521
|
-
async function
|
|
6522
|
-
const
|
|
6523
|
-
|
|
6524
|
-
|
|
6710
|
+
async function resolveInlineDefinitionEnvironment(definition, testFilePath, location) {
|
|
6711
|
+
const [resolved] = await resolveProviderDefinitionEnvironments(
|
|
6712
|
+
[definition],
|
|
6713
|
+
path12.dirname(path12.resolve(testFilePath)),
|
|
6714
|
+
{ location }
|
|
6715
|
+
);
|
|
6716
|
+
return resolved ?? definition;
|
|
6717
|
+
}
|
|
6718
|
+
async function selectProvider(options) {
|
|
6719
|
+
const {
|
|
6525
6720
|
testFilePath,
|
|
6526
6721
|
repoRoot,
|
|
6527
|
-
cwd
|
|
6722
|
+
cwd,
|
|
6723
|
+
explicitProvidersPath,
|
|
6724
|
+
providerDefinitions,
|
|
6725
|
+
providerDefinitionsSource,
|
|
6726
|
+
requireExplicitProviderCatalog,
|
|
6727
|
+
allowLegacyTargetFiles,
|
|
6728
|
+
cliProviderLabel,
|
|
6729
|
+
modelOverride,
|
|
6730
|
+
env
|
|
6731
|
+
} = options;
|
|
6732
|
+
const providerCatalog = await readProviderCatalog({
|
|
6733
|
+
explicitProvidersPath,
|
|
6734
|
+
providerDefinitions,
|
|
6735
|
+
providerDefinitionsSource,
|
|
6736
|
+
requireExplicitProviderCatalog,
|
|
6737
|
+
testFilePath,
|
|
6738
|
+
repoRoot,
|
|
6739
|
+
cwd,
|
|
6740
|
+
allowLegacyTargetFiles
|
|
6528
6741
|
});
|
|
6529
|
-
const
|
|
6530
|
-
const
|
|
6531
|
-
const useColors2 = isTTY();
|
|
6532
|
-
if (warnings.length > 0) {
|
|
6533
|
-
console.warn(`
|
|
6534
|
-
Warnings in ${targetsFilePath}:`);
|
|
6535
|
-
for (const warning of warnings) {
|
|
6536
|
-
const location = warning.location ? ` [${warning.location}]` : "";
|
|
6537
|
-
const prefix = useColors2 ? `${ANSI_YELLOW3} \u26A0${ANSI_RESET3}` : " \u26A0";
|
|
6538
|
-
const message = useColors2 ? `${ANSI_YELLOW3}${warning.message}${ANSI_RESET3}` : warning.message;
|
|
6539
|
-
console.warn(`${prefix}${location} ${message}`);
|
|
6540
|
-
}
|
|
6541
|
-
console.warn("");
|
|
6542
|
-
}
|
|
6543
|
-
const errors = validationResult.errors.filter((e) => e.severity === "error");
|
|
6544
|
-
if (errors.length > 0) {
|
|
6545
|
-
console.error(`
|
|
6546
|
-
Errors in ${targetsFilePath}:`);
|
|
6547
|
-
for (const error of errors) {
|
|
6548
|
-
const location = error.location ? ` [${error.location}]` : "";
|
|
6549
|
-
const prefix = useColors2 ? `${ANSI_RED3} \u2717${ANSI_RESET3}` : " \u2717";
|
|
6550
|
-
const message = useColors2 ? `${ANSI_RED3}${error.message}${ANSI_RESET3}` : error.message;
|
|
6551
|
-
console.error(`${prefix}${location} ${message}`);
|
|
6552
|
-
}
|
|
6553
|
-
throw new Error(`Targets file validation failed with ${errors.length} error(s)`);
|
|
6554
|
-
}
|
|
6555
|
-
const definitions = await readTargetDefinitions(targetsFilePath);
|
|
6742
|
+
const definitions = providerCatalog.definitions;
|
|
6743
|
+
const providersFilePath = providerCatalog.sourcePath;
|
|
6556
6744
|
const fileTargetSpec = options.fileTargetSpec;
|
|
6557
|
-
const
|
|
6558
|
-
const
|
|
6559
|
-
const
|
|
6745
|
+
const fileProviderLabel = options.fileProviderLabel ?? fileTargetSpec?.name ?? await readTestSuiteProvider(testFilePath);
|
|
6746
|
+
const providerChoice = pickProviderLabel({ cliProviderLabel, fileProviderLabel });
|
|
6747
|
+
const rawOverlayDefinition = providerChoice.source === "test-file" ? overlayTargetDefinition({ spec: fileTargetSpec, definitions, env, providersFilePath }) : void 0;
|
|
6748
|
+
const overlayDefinition = rawOverlayDefinition ? await resolveInlineDefinitionEnvironment(rawOverlayDefinition, testFilePath, "providers") : void 0;
|
|
6560
6749
|
const targetDefinition = withModelOverride(
|
|
6561
|
-
overlayDefinition ?? resolveUseTarget(
|
|
6750
|
+
overlayDefinition ?? resolveUseTarget(providerChoice.name, definitions, env, providersFilePath),
|
|
6562
6751
|
modelOverride
|
|
6563
6752
|
);
|
|
6564
6753
|
const effectiveDefinitions = overlayDefinition !== void 0 ? definitionsWithEffectiveTarget(definitions, targetDefinition) : definitions;
|
|
6565
6754
|
try {
|
|
6566
|
-
const
|
|
6755
|
+
const resolvedProvider = resolveProviderDefinition(targetDefinition, env, testFilePath, {
|
|
6567
6756
|
emitDeprecationWarnings: false
|
|
6568
6757
|
});
|
|
6569
6758
|
return {
|
|
6570
6759
|
definitions: effectiveDefinitions,
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
...
|
|
6760
|
+
resolvedProvider,
|
|
6761
|
+
providerLabel: providerChoice.name,
|
|
6762
|
+
providerSource: providerChoice.source,
|
|
6763
|
+
providersFilePath,
|
|
6764
|
+
...providerChoice.source === "test-file" && fileTargetSpec?.hooks ? { providerHooks: fileTargetSpec.hooks } : {}
|
|
6576
6765
|
};
|
|
6577
6766
|
} catch (error) {
|
|
6578
6767
|
const message = error instanceof Error ? error.message : String(error);
|
|
6579
|
-
throw new Error(`Failed to resolve
|
|
6768
|
+
throw new Error(`Failed to resolve provider '${providerChoice.name}': ${message}`);
|
|
6580
6769
|
}
|
|
6581
6770
|
}
|
|
6582
|
-
async function
|
|
6771
|
+
async function selectMultipleProviders(options) {
|
|
6583
6772
|
const {
|
|
6584
6773
|
testFilePath,
|
|
6585
6774
|
repoRoot,
|
|
6586
6775
|
cwd,
|
|
6587
|
-
|
|
6776
|
+
explicitProvidersPath,
|
|
6777
|
+
providerDefinitions,
|
|
6778
|
+
providerDefinitionsSource,
|
|
6779
|
+
requireExplicitProviderCatalog,
|
|
6780
|
+
allowLegacyTargetFiles,
|
|
6588
6781
|
env,
|
|
6589
|
-
|
|
6590
|
-
|
|
6782
|
+
providerLabels,
|
|
6783
|
+
providerRefs,
|
|
6591
6784
|
modelOverride
|
|
6592
6785
|
} = options;
|
|
6593
6786
|
const hooksMap = /* @__PURE__ */ new Map();
|
|
6594
6787
|
const labelsMap = /* @__PURE__ */ new Map();
|
|
6595
|
-
if (
|
|
6596
|
-
for (const ref of
|
|
6788
|
+
if (providerRefs) {
|
|
6789
|
+
for (const ref of providerRefs) {
|
|
6597
6790
|
if (ref.hooks) {
|
|
6598
6791
|
hooksMap.set(ref.name, ref.hooks);
|
|
6599
6792
|
}
|
|
@@ -6602,73 +6795,54 @@ async function selectMultipleTargets(options) {
|
|
|
6602
6795
|
}
|
|
6603
6796
|
}
|
|
6604
6797
|
}
|
|
6605
|
-
const
|
|
6606
|
-
|
|
6798
|
+
const providerCatalog = await readProviderCatalog({
|
|
6799
|
+
explicitProvidersPath,
|
|
6800
|
+
providerDefinitions,
|
|
6801
|
+
providerDefinitionsSource,
|
|
6802
|
+
requireExplicitProviderCatalog,
|
|
6607
6803
|
testFilePath,
|
|
6608
6804
|
repoRoot,
|
|
6609
|
-
cwd
|
|
6805
|
+
cwd,
|
|
6806
|
+
allowLegacyTargetFiles
|
|
6610
6807
|
});
|
|
6611
|
-
const
|
|
6612
|
-
const
|
|
6613
|
-
const useColors2 = isTTY();
|
|
6614
|
-
if (warnings.length > 0) {
|
|
6615
|
-
console.warn(`
|
|
6616
|
-
Warnings in ${targetsFilePath}:`);
|
|
6617
|
-
for (const warning of warnings) {
|
|
6618
|
-
const location = warning.location ? ` [${warning.location}]` : "";
|
|
6619
|
-
const prefix = useColors2 ? `${ANSI_YELLOW3} \u26A0${ANSI_RESET3}` : " \u26A0";
|
|
6620
|
-
const message = useColors2 ? `${ANSI_YELLOW3}${warning.message}${ANSI_RESET3}` : warning.message;
|
|
6621
|
-
console.warn(`${prefix}${location} ${message}`);
|
|
6622
|
-
}
|
|
6623
|
-
console.warn("");
|
|
6624
|
-
}
|
|
6625
|
-
const errors = validationResult.errors.filter((e) => e.severity === "error");
|
|
6626
|
-
if (errors.length > 0) {
|
|
6627
|
-
console.error(`
|
|
6628
|
-
Errors in ${targetsFilePath}:`);
|
|
6629
|
-
for (const error of errors) {
|
|
6630
|
-
const location = error.location ? ` [${error.location}]` : "";
|
|
6631
|
-
const prefix = useColors2 ? `${ANSI_RED3} \u2717${ANSI_RESET3}` : " \u2717";
|
|
6632
|
-
const message = useColors2 ? `${ANSI_RED3}${error.message}${ANSI_RESET3}` : error.message;
|
|
6633
|
-
console.error(`${prefix}${location} ${message}`);
|
|
6634
|
-
}
|
|
6635
|
-
throw new Error(`Targets file validation failed with ${errors.length} error(s)`);
|
|
6636
|
-
}
|
|
6637
|
-
const fileDefinitions = await readTargetDefinitions(targetsFilePath);
|
|
6808
|
+
const providersFilePath = providerCatalog.sourcePath;
|
|
6809
|
+
const fileDefinitions = providerCatalog.definitions;
|
|
6638
6810
|
const definitions = [...fileDefinitions];
|
|
6639
|
-
if (
|
|
6640
|
-
for (const ref of
|
|
6811
|
+
if (providerRefs) {
|
|
6812
|
+
for (const ref of providerRefs) {
|
|
6641
6813
|
if (ref.definition && !fileDefinitions.some((d) => d.name === ref.name)) {
|
|
6642
|
-
definitions.push(
|
|
6814
|
+
definitions.push(
|
|
6815
|
+
await resolveInlineDefinitionEnvironment(ref.definition, testFilePath, "providers")
|
|
6816
|
+
);
|
|
6643
6817
|
} else if (ref.use_target && !fileDefinitions.some((d) => d.name === ref.name)) {
|
|
6644
6818
|
definitions.push({ name: ref.name, use_target: ref.use_target });
|
|
6645
6819
|
}
|
|
6646
6820
|
}
|
|
6647
6821
|
}
|
|
6648
6822
|
const results = [];
|
|
6649
|
-
for (const name of
|
|
6823
|
+
for (const name of providerLabels) {
|
|
6650
6824
|
const targetDefinition = withModelOverride(
|
|
6651
|
-
resolveUseTarget(name, definitions, env,
|
|
6825
|
+
resolveUseTarget(name, definitions, env, providersFilePath),
|
|
6652
6826
|
modelOverride
|
|
6653
6827
|
);
|
|
6654
6828
|
const hooks = hooksMap.get(name);
|
|
6655
|
-
const
|
|
6829
|
+
const providerDisplayLabel = labelsMap.get(name);
|
|
6656
6830
|
try {
|
|
6657
|
-
const
|
|
6831
|
+
const resolvedProvider = resolveProviderDefinition(targetDefinition, env, testFilePath, {
|
|
6658
6832
|
emitDeprecationWarnings: false
|
|
6659
6833
|
});
|
|
6660
6834
|
results.push({
|
|
6661
6835
|
definitions,
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
...
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
...hooks && {
|
|
6836
|
+
resolvedProvider,
|
|
6837
|
+
providerLabel: name,
|
|
6838
|
+
...providerDisplayLabel ? { providerDisplayLabel } : {},
|
|
6839
|
+
providerSource: options.providerSource ?? "cli",
|
|
6840
|
+
providersFilePath,
|
|
6841
|
+
...hooks && { providerHooks: hooks }
|
|
6668
6842
|
});
|
|
6669
6843
|
} catch (error) {
|
|
6670
6844
|
const message = error instanceof Error ? error.message : String(error);
|
|
6671
|
-
throw new Error(`Failed to resolve
|
|
6845
|
+
throw new Error(`Failed to resolve provider '${name}': ${message}`);
|
|
6672
6846
|
}
|
|
6673
6847
|
}
|
|
6674
6848
|
return results;
|
|
@@ -6767,7 +6941,7 @@ var DEFAULT_WORKERS = 3;
|
|
|
6767
6941
|
var loadCjsModule = createNodeRequire(import.meta.url);
|
|
6768
6942
|
var micromatch = loadCjsModule("micromatch");
|
|
6769
6943
|
async function loadCliEvalSuite(testFilePath, repoRoot, options) {
|
|
6770
|
-
if (
|
|
6944
|
+
if (path13.extname(testFilePath).toLowerCase() === ".json") {
|
|
6771
6945
|
const adapterSuite = readAgentSkillsEvalsFile(testFilePath);
|
|
6772
6946
|
return loadTestSuiteFromYamlObject(
|
|
6773
6947
|
testFilePath,
|
|
@@ -6883,8 +7057,8 @@ function resultsRepoOverride(value) {
|
|
|
6883
7057
|
if (!value) {
|
|
6884
7058
|
return {};
|
|
6885
7059
|
}
|
|
6886
|
-
if (value === "current" || value === "." || value.startsWith("./") || value.startsWith("../") || value.startsWith("/") || value.startsWith("~/") || value.startsWith("~\\") || /^[A-Za-z]:[/\\]/.test(value)) {
|
|
6887
|
-
return { repo_path: value === "current" ? "." : value };
|
|
7060
|
+
if (value === "current" || value === "current/." || value === "." || value.startsWith("./") || value.startsWith("../") || value.startsWith("/") || value.startsWith("~/") || value.startsWith("~\\") || /^[A-Za-z]:[/\\]/.test(value)) {
|
|
7061
|
+
return { repo_path: value === "current" || value === "current/." ? "." : value };
|
|
6888
7062
|
}
|
|
6889
7063
|
return { repo: value };
|
|
6890
7064
|
}
|
|
@@ -6921,13 +7095,32 @@ function normalizeSourceMetadataByEvalFile(value) {
|
|
|
6921
7095
|
const entries = [...value.entries()].filter(
|
|
6922
7096
|
(entry) => typeof entry[0] === "string" && typeof entry[1] === "object" && entry[1] !== null && !Array.isArray(entry[1])
|
|
6923
7097
|
);
|
|
6924
|
-
return entries.length > 0 ? new Map(entries.map(([key, metadata]) => [
|
|
7098
|
+
return entries.length > 0 ? new Map(entries.map(([key, metadata]) => [path13.resolve(key), metadata])) : void 0;
|
|
6925
7099
|
}
|
|
6926
7100
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
6927
7101
|
const entries = Object.entries(value).filter(
|
|
6928
7102
|
(entry) => typeof entry[1] === "object" && entry[1] !== null && !Array.isArray(entry[1])
|
|
6929
7103
|
);
|
|
6930
|
-
return entries.length > 0 ? new Map(entries.map(([key, metadata]) => [
|
|
7104
|
+
return entries.length > 0 ? new Map(entries.map(([key, metadata]) => [path13.resolve(key), metadata])) : void 0;
|
|
7105
|
+
}
|
|
7106
|
+
return void 0;
|
|
7107
|
+
}
|
|
7108
|
+
function normalizeProviderCatalogPathByEvalFile(value) {
|
|
7109
|
+
if (value instanceof Map) {
|
|
7110
|
+
const entries = [...value.entries()].filter(
|
|
7111
|
+
(entry) => typeof entry[0] === "string" && typeof entry[1] === "string" && entry[1].trim().length > 0
|
|
7112
|
+
);
|
|
7113
|
+
return entries.length > 0 ? new Map(
|
|
7114
|
+
entries.map(([key, providerPath]) => [path13.resolve(key), path13.resolve(providerPath)])
|
|
7115
|
+
) : void 0;
|
|
7116
|
+
}
|
|
7117
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
7118
|
+
const entries = Object.entries(value).filter(
|
|
7119
|
+
(entry) => typeof entry[1] === "string" && entry[1].trim().length > 0
|
|
7120
|
+
);
|
|
7121
|
+
return entries.length > 0 ? new Map(
|
|
7122
|
+
entries.map(([key, providerPath]) => [path13.resolve(key), path13.resolve(providerPath)])
|
|
7123
|
+
) : void 0;
|
|
6931
7124
|
}
|
|
6932
7125
|
return void 0;
|
|
6933
7126
|
}
|
|
@@ -6941,10 +7134,10 @@ var LEGACY_OUTPUT_FILE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
6941
7134
|
".htm"
|
|
6942
7135
|
]);
|
|
6943
7136
|
function looksLikeLegacyOutputFilePath(value) {
|
|
6944
|
-
return LEGACY_OUTPUT_FILE_EXTENSIONS.has(
|
|
7137
|
+
return LEGACY_OUTPUT_FILE_EXTENSIONS.has(path13.extname(value).toLowerCase());
|
|
6945
7138
|
}
|
|
6946
7139
|
function outputFileMigrationMessage(value) {
|
|
6947
|
-
const ext =
|
|
7140
|
+
const ext = path13.extname(value).toLowerCase();
|
|
6948
7141
|
const removalHint = ext === ".xml" ? "JUnit XML export from agentv eval has been removed." : "Flat result file export from agentv eval has been removed.";
|
|
6949
7142
|
return `--output expects a run directory, not a file path: ${value}
|
|
6950
7143
|
${removalHint} Set --output <dir> for the canonical run artifacts; AgentV always writes <dir>/${RESULT_INDEX_FILENAME}.`;
|
|
@@ -6952,7 +7145,7 @@ ${removalHint} Set --output <dir> for the canonical run artifacts; AgentV always
|
|
|
6952
7145
|
function artifactsMigrationMessage(artifactsDir, outputDir) {
|
|
6953
7146
|
const lines = [`--artifacts was removed from agentv eval. Use --output ${artifactsDir} instead.`];
|
|
6954
7147
|
if (outputDir && looksLikeLegacyOutputFilePath(outputDir)) {
|
|
6955
|
-
const ext =
|
|
7148
|
+
const ext = path13.extname(outputDir).toLowerCase();
|
|
6956
7149
|
lines.push(
|
|
6957
7150
|
ext === ".xml" ? "JUnit XML export from agentv eval has been removed." : "Flat result file export from agentv eval has been removed."
|
|
6958
7151
|
);
|
|
@@ -7045,17 +7238,19 @@ function normalizeOptions(rawOptions, config, yamlExecution) {
|
|
|
7045
7238
|
const configWorkers = config?.execution?.maxConcurrency ?? yamlExecution?.max_concurrency;
|
|
7046
7239
|
const workers = cliWorkers ?? configWorkers ?? 0;
|
|
7047
7240
|
const cliOutputDir = normalizeString(rawOptions.output);
|
|
7048
|
-
const
|
|
7049
|
-
let
|
|
7050
|
-
let
|
|
7051
|
-
if (Array.isArray(
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7241
|
+
const rawProvider = rawOptions.provider;
|
|
7242
|
+
let cliProviderLabels = [];
|
|
7243
|
+
let singleProvider;
|
|
7244
|
+
if (Array.isArray(rawProvider)) {
|
|
7245
|
+
cliProviderLabels = rawProvider.filter(
|
|
7246
|
+
(v) => typeof v === "string" && v.trim().length > 0
|
|
7247
|
+
);
|
|
7248
|
+
singleProvider = cliProviderLabels.length === 1 ? cliProviderLabels[0] : void 0;
|
|
7249
|
+
} else if (typeof rawProvider === "string") {
|
|
7250
|
+
const trimmed = rawProvider.trim();
|
|
7056
7251
|
if (trimmed.length > 0 && trimmed !== "default") {
|
|
7057
|
-
|
|
7058
|
-
|
|
7252
|
+
cliProviderLabels = [trimmed];
|
|
7253
|
+
singleProvider = trimmed;
|
|
7059
7254
|
}
|
|
7060
7255
|
}
|
|
7061
7256
|
const cliAgentTimeout = normalizeOptionalNumber(rawOptions.agentTimeout);
|
|
@@ -7091,9 +7286,13 @@ function normalizeOptions(rawOptions, config, yamlExecution) {
|
|
|
7091
7286
|
};
|
|
7092
7287
|
const cliTags = splitCliTags(rawOptions.tag);
|
|
7093
7288
|
return {
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7289
|
+
provider: singleProvider,
|
|
7290
|
+
cliProviderLabels,
|
|
7291
|
+
providersPath: normalizeString(rawOptions.providers),
|
|
7292
|
+
allowLegacyTargetFiles: normalizeBoolean(rawOptions.allowLegacyTargetFiles),
|
|
7293
|
+
providerCatalogPathByEvalFile: normalizeProviderCatalogPathByEvalFile(
|
|
7294
|
+
rawOptions.providerCatalogPathByEvalFile
|
|
7295
|
+
),
|
|
7097
7296
|
filter: normalizeFilter(rawOptions.filter),
|
|
7098
7297
|
workers: workers > 0 ? workers : void 0,
|
|
7099
7298
|
outputDir: cliOutputDir ?? configOutputDir,
|
|
@@ -7140,7 +7339,7 @@ function normalizeOptions(rawOptions, config, yamlExecution) {
|
|
|
7140
7339
|
};
|
|
7141
7340
|
}
|
|
7142
7341
|
function withSourceMetadata(result, testFilePath, options) {
|
|
7143
|
-
const sourceMetadata = options.sourceMetadataByEvalFile?.get(
|
|
7342
|
+
const sourceMetadata = options.sourceMetadataByEvalFile?.get(path13.resolve(testFilePath));
|
|
7144
7343
|
if (!sourceMetadata) {
|
|
7145
7344
|
return result;
|
|
7146
7345
|
}
|
|
@@ -7163,11 +7362,11 @@ function deriveEvalResultGroupName(evalFilePath) {
|
|
|
7163
7362
|
if (!evalFilePath) {
|
|
7164
7363
|
return "eval";
|
|
7165
7364
|
}
|
|
7166
|
-
return
|
|
7365
|
+
return path13.basename(evalFilePath).replace(/\.eval\.ya?ml$/i, "").replace(/\.ya?ml$/i, "").replace(/[^A-Za-z0-9._-]/g, "-") || "eval";
|
|
7167
7366
|
}
|
|
7168
7367
|
var CLI_RUNTIME_SOURCE_OPTION_KEYS = [
|
|
7169
|
-
"
|
|
7170
|
-
"
|
|
7368
|
+
"provider",
|
|
7369
|
+
"providers",
|
|
7171
7370
|
"filter",
|
|
7172
7371
|
"tag",
|
|
7173
7372
|
"excludeTag",
|
|
@@ -7210,10 +7409,10 @@ function toRuntimeSourcePath(cwd, filePath) {
|
|
|
7210
7409
|
if (!trimmed) {
|
|
7211
7410
|
return void 0;
|
|
7212
7411
|
}
|
|
7213
|
-
const resolved =
|
|
7214
|
-
const relative =
|
|
7215
|
-
const displayPath = relative && !relative.startsWith("..") && !
|
|
7216
|
-
return displayPath.split(
|
|
7412
|
+
const resolved = path13.isAbsolute(trimmed) ? trimmed : path13.resolve(cwd, trimmed);
|
|
7413
|
+
const relative = path13.relative(cwd, resolved);
|
|
7414
|
+
const displayPath = relative && !relative.startsWith("..") && !path13.isAbsolute(relative) ? relative : trimmed;
|
|
7415
|
+
return displayPath.split(path13.sep).join("/");
|
|
7217
7416
|
}
|
|
7218
7417
|
function uniqueRuntimeSourcePaths(values) {
|
|
7219
7418
|
return [...new Set([...values].filter((value) => Boolean(value)))].sort();
|
|
@@ -7223,7 +7422,7 @@ function testSourceEvalPath(cwd, test) {
|
|
|
7223
7422
|
}
|
|
7224
7423
|
function testSourceEvalPathForComparison(test) {
|
|
7225
7424
|
const sourcePath = test.source?.evalFileAbsolutePath ?? test.source?.evalFilePath;
|
|
7226
|
-
return sourcePath ?
|
|
7425
|
+
return sourcePath ? path13.resolve(sourcePath) : void 0;
|
|
7227
7426
|
}
|
|
7228
7427
|
function buildRuntimeConfigSource(params) {
|
|
7229
7428
|
const inlineFingerprints = /* @__PURE__ */ new Set();
|
|
@@ -7254,7 +7453,7 @@ function buildRuntimeSourceMetadata(params) {
|
|
|
7254
7453
|
params.activeTestFiles.map((filePath) => toRuntimeSourcePath(params.cwd, filePath))
|
|
7255
7454
|
);
|
|
7256
7455
|
const activeResolvedFiles = new Set(
|
|
7257
|
-
params.activeTestFiles.map((filePath) =>
|
|
7456
|
+
params.activeTestFiles.map((filePath) => path13.resolve(filePath))
|
|
7258
7457
|
);
|
|
7259
7458
|
const sourceEvalFiles = uniqueRuntimeSourcePaths(
|
|
7260
7459
|
params.sourceTests.map((test) => testSourceEvalPath(params.cwd, test))
|
|
@@ -7285,22 +7484,21 @@ function applyExperimentOptions(options, experiment) {
|
|
|
7285
7484
|
if (!experiment) {
|
|
7286
7485
|
return options;
|
|
7287
7486
|
}
|
|
7288
|
-
const
|
|
7289
|
-
const
|
|
7487
|
+
const experimentProviderRefs = buildExperimentTargetRefs(experiment);
|
|
7488
|
+
const experimentProviderLabels = experimentProviderRefs?.map((target) => target.name) ?? [];
|
|
7290
7489
|
const experimentTarget = experiment.target && experiment.target.trim().length > 0 ? experiment.target : void 0;
|
|
7291
|
-
const
|
|
7490
|
+
const experimentProviders = options.cliProviderLabels.length === 0 ? experimentProviderLabels.length > 0 ? experimentProviderLabels : experimentTarget ? [experimentTarget] : void 0 : void 0;
|
|
7292
7491
|
return {
|
|
7293
7492
|
...options,
|
|
7294
|
-
target: options.target,
|
|
7295
7493
|
agentTimeoutSeconds: options.agentTimeoutSeconds ?? experiment.timeoutSeconds,
|
|
7296
7494
|
workspacePath: options.workspacePath,
|
|
7297
7495
|
budgetUsd: options.budgetUsd ?? experiment.budgetUsd,
|
|
7298
7496
|
threshold: options.threshold ?? experiment.threshold,
|
|
7299
7497
|
experimentConfig: experiment,
|
|
7300
7498
|
experimentMetadata: buildExperimentArtifactMetadata(experiment),
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7499
|
+
experimentProviderLabels: experimentProviders,
|
|
7500
|
+
experimentProviderRefs: options.cliProviderLabels.length === 0 ? experimentProviderRefs : void 0,
|
|
7501
|
+
providerModelOverride: options.providerModelOverride ?? experiment.model,
|
|
7304
7502
|
experimentTrialsConfig: buildExperimentTrialsConfig(experiment)
|
|
7305
7503
|
};
|
|
7306
7504
|
}
|
|
@@ -7328,11 +7526,7 @@ function buildExperimentTrialsConfig(experiment) {
|
|
|
7328
7526
|
}
|
|
7329
7527
|
return {
|
|
7330
7528
|
count: experiment.repeat.count,
|
|
7331
|
-
strategy: experiment.repeat.strategy
|
|
7332
|
-
...experiment.repeat.costLimitUsd !== void 0 && {
|
|
7333
|
-
costLimitUsd: experiment.repeat.costLimitUsd
|
|
7334
|
-
},
|
|
7335
|
-
...experiment.repeat.earlyExit !== void 0 && { earlyExit: experiment.repeat.earlyExit }
|
|
7529
|
+
strategy: experiment.repeat.strategy
|
|
7336
7530
|
};
|
|
7337
7531
|
}
|
|
7338
7532
|
return void 0;
|
|
@@ -7344,9 +7538,7 @@ function buildRunOverrideTrialsConfig(run) {
|
|
|
7344
7538
|
}
|
|
7345
7539
|
return {
|
|
7346
7540
|
count: repeat.count,
|
|
7347
|
-
strategy: repeat.strategy
|
|
7348
|
-
...repeat.costLimitUsd !== void 0 && { costLimitUsd: repeat.costLimitUsd },
|
|
7349
|
-
...repeat.earlyExit !== void 0 && { earlyExit: repeat.earlyExit }
|
|
7541
|
+
strategy: repeat.strategy
|
|
7350
7542
|
};
|
|
7351
7543
|
}
|
|
7352
7544
|
function resolveEffectiveRunPolicy(params) {
|
|
@@ -7408,7 +7600,7 @@ function createProgressReporter(maxWorkers, options) {
|
|
|
7408
7600
|
};
|
|
7409
7601
|
}
|
|
7410
7602
|
function makeTestCaseKey(testFilePath, testId) {
|
|
7411
|
-
return `${
|
|
7603
|
+
return `${path13.resolve(testFilePath)}::${testId}`;
|
|
7412
7604
|
}
|
|
7413
7605
|
function resolveTargetLabel(requestedName, resolvedName) {
|
|
7414
7606
|
if (resolvedName !== requestedName) {
|
|
@@ -7447,23 +7639,23 @@ function buildTargetLabelSuffix(providerLabel, target) {
|
|
|
7447
7639
|
return `[${parts.join(", ")}]`;
|
|
7448
7640
|
}
|
|
7449
7641
|
function applyVerboseOverride(selection, cliVerbose) {
|
|
7450
|
-
const {
|
|
7451
|
-
if (
|
|
7642
|
+
const { resolvedProvider } = selection;
|
|
7643
|
+
if (resolvedProvider.kind !== "cli") {
|
|
7452
7644
|
return selection;
|
|
7453
7645
|
}
|
|
7454
7646
|
return {
|
|
7455
7647
|
...selection,
|
|
7456
|
-
|
|
7457
|
-
...
|
|
7648
|
+
resolvedProvider: {
|
|
7649
|
+
...resolvedProvider,
|
|
7458
7650
|
config: {
|
|
7459
|
-
...
|
|
7651
|
+
...resolvedProvider.config,
|
|
7460
7652
|
verbose: cliVerbose
|
|
7461
7653
|
}
|
|
7462
7654
|
}
|
|
7463
7655
|
};
|
|
7464
7656
|
}
|
|
7465
7657
|
function targetVariantForSelection(selection) {
|
|
7466
|
-
const target = selection.
|
|
7658
|
+
const target = selection.resolvedProvider;
|
|
7467
7659
|
if (target.kind === "replay") {
|
|
7468
7660
|
return target.config.variant;
|
|
7469
7661
|
}
|
|
@@ -7505,20 +7697,24 @@ async function readExistingResultsFromRunDir(runDir) {
|
|
|
7505
7697
|
}
|
|
7506
7698
|
return results;
|
|
7507
7699
|
}
|
|
7700
|
+
async function collectTerminalSummaryResults(params) {
|
|
7701
|
+
const rawResults = params.isResumeAppend ? await (params.readExistingResults ?? readExistingResultsFromRunDir)(params.runDir) : params.allResults;
|
|
7702
|
+
return deduplicateByTestIdTarget(rawResults);
|
|
7703
|
+
}
|
|
7508
7704
|
async function resolveRerunFailedRunDir(cwd, source) {
|
|
7509
7705
|
const trimmed = source.trim();
|
|
7510
7706
|
if (!trimmed) {
|
|
7511
7707
|
throw new Error("--rerun-failed requires a run ID, run workspace, or index.jsonl path.");
|
|
7512
7708
|
}
|
|
7513
|
-
const candidate =
|
|
7709
|
+
const candidate = path13.isAbsolute(trimmed) ? trimmed : path13.resolve(cwd, trimmed);
|
|
7514
7710
|
if (existsSync5(candidate)) {
|
|
7515
|
-
if (
|
|
7711
|
+
if (path13.basename(candidate) !== RESULT_INDEX_FILENAME) {
|
|
7516
7712
|
return candidate;
|
|
7517
7713
|
}
|
|
7518
|
-
const manifestDir =
|
|
7519
|
-
return
|
|
7714
|
+
const manifestDir = path13.dirname(candidate);
|
|
7715
|
+
return path13.basename(manifestDir) === ".internal" ? path13.dirname(manifestDir) : manifestDir;
|
|
7520
7716
|
}
|
|
7521
|
-
const runIdCandidate =
|
|
7717
|
+
const runIdCandidate = path13.join(cwd, ".agentv", "results", trimmed);
|
|
7522
7718
|
if (existsSync5(runIdCandidate)) {
|
|
7523
7719
|
return runIdCandidate;
|
|
7524
7720
|
}
|
|
@@ -7527,14 +7723,23 @@ async function resolveRerunFailedRunDir(cwd, source) {
|
|
|
7527
7723
|
);
|
|
7528
7724
|
}
|
|
7529
7725
|
async function prepareFileMetadata(params) {
|
|
7530
|
-
const {
|
|
7726
|
+
const {
|
|
7727
|
+
testFilePath,
|
|
7728
|
+
repoRoot,
|
|
7729
|
+
cwd,
|
|
7730
|
+
options,
|
|
7731
|
+
providerCatalogPath,
|
|
7732
|
+
providerDefinitions,
|
|
7733
|
+
providerDefinitionsSource,
|
|
7734
|
+
suiteFilter
|
|
7735
|
+
} = params;
|
|
7531
7736
|
await ensureFileExists(testFilePath, "Test file");
|
|
7532
7737
|
await loadEnvFromHierarchy({
|
|
7533
7738
|
testFilePath,
|
|
7534
7739
|
repoRoot,
|
|
7535
7740
|
verbose: options.verbose
|
|
7536
7741
|
});
|
|
7537
|
-
const relativePath =
|
|
7742
|
+
const relativePath = path13.relative(cwd, testFilePath);
|
|
7538
7743
|
const category = deriveCategory(relativePath);
|
|
7539
7744
|
const suite = await loadCliEvalSuite(testFilePath, repoRoot, {
|
|
7540
7745
|
verbose: options.verbose,
|
|
@@ -7543,21 +7748,24 @@ async function prepareFileMetadata(params) {
|
|
|
7543
7748
|
});
|
|
7544
7749
|
const experimentOptions = applyExperimentOptions(options, suite.experimentConfig);
|
|
7545
7750
|
const effectiveOptions = experimentOptions.workers === void 0 && suite.workers !== void 0 ? { ...experimentOptions, workers: suite.workers } : experimentOptions;
|
|
7751
|
+
const effectiveProviderCatalogPath = effectiveOptions.providersPath ?? providerCatalogPath;
|
|
7546
7752
|
const testCases = suiteFilter && effectiveOptions.filter ? suite.tests.filter(
|
|
7547
7753
|
(testCase) => matchesTestFilter(testCase.id, effectiveOptions.filter ?? "")
|
|
7548
7754
|
) : suite.tests;
|
|
7549
7755
|
const testIds = testCases.map((value) => value.id);
|
|
7550
7756
|
const suiteTargetSpec = suite.targetSpec;
|
|
7757
|
+
const suiteDefaults = suite.defaults;
|
|
7551
7758
|
const suiteTargets = suiteTargetSpec ? [suiteTargetSpec.name] : suite.targets;
|
|
7759
|
+
const fileOptions = suiteDefaults?.grader && !effectiveOptions.graderTarget ? { ...effectiveOptions, defaultGraderTarget: suiteDefaults.grader } : effectiveOptions;
|
|
7552
7760
|
const defaultBudgetUsd = effectiveOptions.cliBudgetUsd === void 0 ? effectiveOptions.budgetUsd ?? suite.budgetUsd : void 0;
|
|
7553
7761
|
const suiteDefaultThreshold = suite.defaultTest?.threshold ?? suite.threshold;
|
|
7554
7762
|
if (testCases.length === 0) {
|
|
7555
7763
|
return {
|
|
7556
|
-
options:
|
|
7764
|
+
options: fileOptions,
|
|
7557
7765
|
testIds,
|
|
7558
7766
|
testCases,
|
|
7559
7767
|
selections: [],
|
|
7560
|
-
trialsConfig:
|
|
7768
|
+
trialsConfig: fileOptions.experimentTrialsConfig,
|
|
7561
7769
|
suiteTargets,
|
|
7562
7770
|
yamlCache: suite.cacheConfig?.enabled,
|
|
7563
7771
|
yamlCachePath: suite.cacheConfig?.cachePath,
|
|
@@ -7569,42 +7777,47 @@ async function prepareFileMetadata(params) {
|
|
|
7569
7777
|
};
|
|
7570
7778
|
}
|
|
7571
7779
|
let selections;
|
|
7572
|
-
if (
|
|
7780
|
+
if (fileOptions.transcript) {
|
|
7573
7781
|
const transcriptSelection = {
|
|
7574
7782
|
definitions: [],
|
|
7575
|
-
|
|
7783
|
+
resolvedProvider: {
|
|
7576
7784
|
kind: "transcript",
|
|
7577
7785
|
name: "transcript",
|
|
7578
7786
|
config: {}
|
|
7579
7787
|
},
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7788
|
+
providerLabel: "transcript",
|
|
7789
|
+
providerSource: "cli",
|
|
7790
|
+
providersFilePath: fileOptions.transcript
|
|
7583
7791
|
};
|
|
7584
7792
|
selections = [
|
|
7585
7793
|
{
|
|
7586
7794
|
selection: transcriptSelection,
|
|
7587
|
-
inlineTargetLabel: `transcript (${
|
|
7795
|
+
inlineTargetLabel: `transcript (${path13.basename(fileOptions.transcript)})`
|
|
7588
7796
|
}
|
|
7589
7797
|
];
|
|
7590
|
-
} else if (suite.inlineTarget &&
|
|
7798
|
+
} else if (suite.inlineTarget && fileOptions.cliProviderLabels.length === 0) {
|
|
7591
7799
|
const targetDefinition = suite.inlineTarget;
|
|
7592
|
-
const
|
|
7593
|
-
|
|
7594
|
-
|
|
7800
|
+
const resolvedProvider = resolveProviderDefinition(
|
|
7801
|
+
targetDefinition,
|
|
7802
|
+
process.env,
|
|
7803
|
+
testFilePath,
|
|
7804
|
+
{
|
|
7805
|
+
emitDeprecationWarnings: false
|
|
7806
|
+
}
|
|
7807
|
+
);
|
|
7595
7808
|
selections = [
|
|
7596
7809
|
{
|
|
7597
7810
|
selection: {
|
|
7598
7811
|
definitions: [targetDefinition],
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7812
|
+
resolvedProvider,
|
|
7813
|
+
providerLabel: targetDefinition.name,
|
|
7814
|
+
providerSource: "test-file",
|
|
7815
|
+
providersFilePath: testFilePath
|
|
7603
7816
|
},
|
|
7604
|
-
inlineTargetLabel: resolveTargetLabel(targetDefinition.name,
|
|
7817
|
+
inlineTargetLabel: resolveTargetLabel(targetDefinition.name, resolvedProvider.name)
|
|
7605
7818
|
}
|
|
7606
7819
|
];
|
|
7607
|
-
} else if (suite.providerFactory &&
|
|
7820
|
+
} else if (suite.providerFactory && fileOptions.cliProviderLabels.length === 0) {
|
|
7608
7821
|
const taskTarget = {
|
|
7609
7822
|
kind: "mock",
|
|
7610
7823
|
name: "custom-task",
|
|
@@ -7615,89 +7828,100 @@ async function prepareFileMetadata(params) {
|
|
|
7615
7828
|
{
|
|
7616
7829
|
selection: {
|
|
7617
7830
|
definitions: [],
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7831
|
+
resolvedProvider: taskTarget,
|
|
7832
|
+
providerLabel: "custom-task",
|
|
7833
|
+
providerSource: "test-file",
|
|
7834
|
+
providersFilePath: testFilePath
|
|
7622
7835
|
},
|
|
7623
7836
|
inlineTargetLabel: "custom-task"
|
|
7624
7837
|
}
|
|
7625
7838
|
];
|
|
7626
7839
|
} else {
|
|
7627
|
-
const
|
|
7628
|
-
const
|
|
7840
|
+
const cliProviderLabels = fileOptions.cliProviderLabels;
|
|
7841
|
+
const experimentProviderLabels = fileOptions.experimentProviderLabels ?? [];
|
|
7629
7842
|
const suiteTargetSpec2 = suite.targetSpec;
|
|
7630
|
-
const
|
|
7631
|
-
const
|
|
7632
|
-
const
|
|
7633
|
-
let
|
|
7634
|
-
let
|
|
7635
|
-
let
|
|
7636
|
-
if (
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
} else if (
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
} else if (
|
|
7644
|
-
|
|
7645
|
-
|
|
7843
|
+
const suiteProviderLabels = suiteTargetSpec2 ? [suiteTargetSpec2.name] : suite.targets;
|
|
7844
|
+
const suiteProviderRefs = suite.targetRefs;
|
|
7845
|
+
const experimentProviderRefs = fileOptions.experimentProviderRefs;
|
|
7846
|
+
let providerLabels;
|
|
7847
|
+
let providerRefs;
|
|
7848
|
+
let providerSource = "test-file";
|
|
7849
|
+
if (cliProviderLabels.length > 0) {
|
|
7850
|
+
providerLabels = cliProviderLabels;
|
|
7851
|
+
providerRefs = experimentProviderRefs;
|
|
7852
|
+
providerSource = "cli";
|
|
7853
|
+
} else if (experimentProviderLabels.length > 0) {
|
|
7854
|
+
providerLabels = experimentProviderLabels;
|
|
7855
|
+
providerRefs = experimentProviderRefs;
|
|
7856
|
+
} else if (suiteProviderLabels && suiteProviderLabels.length > 0) {
|
|
7857
|
+
providerLabels = suiteProviderLabels;
|
|
7858
|
+
providerRefs = suiteProviderRefs;
|
|
7859
|
+
} else if (suiteDefaults?.provider) {
|
|
7860
|
+
providerLabels = [suiteDefaults.provider];
|
|
7861
|
+
providerRefs = void 0;
|
|
7646
7862
|
} else {
|
|
7647
|
-
|
|
7648
|
-
|
|
7863
|
+
providerLabels = [];
|
|
7864
|
+
providerRefs = void 0;
|
|
7649
7865
|
}
|
|
7650
|
-
if (
|
|
7651
|
-
const multiSelections = await
|
|
7866
|
+
if (providerLabels.length > 1 || providerLabels.length === 1 && providerRefs) {
|
|
7867
|
+
const multiSelections = await selectMultipleProviders({
|
|
7652
7868
|
testFilePath,
|
|
7653
7869
|
repoRoot,
|
|
7654
7870
|
cwd,
|
|
7655
|
-
|
|
7871
|
+
explicitProvidersPath: effectiveProviderCatalogPath,
|
|
7872
|
+
providerDefinitions,
|
|
7873
|
+
providerDefinitionsSource,
|
|
7874
|
+
requireExplicitProviderCatalog: true,
|
|
7875
|
+
allowLegacyTargetFiles: fileOptions.allowLegacyTargetFiles,
|
|
7656
7876
|
env: process.env,
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
modelOverride:
|
|
7877
|
+
providerLabels,
|
|
7878
|
+
providerRefs,
|
|
7879
|
+
providerSource,
|
|
7880
|
+
modelOverride: fileOptions.providerModelOverride
|
|
7661
7881
|
});
|
|
7662
7882
|
selections = multiSelections.map((sel) => ({
|
|
7663
7883
|
selection: sel,
|
|
7664
|
-
inlineTargetLabel: sel.
|
|
7884
|
+
inlineTargetLabel: sel.providerDisplayLabel ?? resolveTargetLabel(sel.providerLabel, sel.resolvedProvider.name)
|
|
7665
7885
|
}));
|
|
7666
7886
|
} else {
|
|
7667
|
-
const selection = await
|
|
7887
|
+
const selection = await selectProvider({
|
|
7668
7888
|
testFilePath,
|
|
7669
7889
|
repoRoot,
|
|
7670
7890
|
cwd,
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7891
|
+
explicitProvidersPath: effectiveProviderCatalogPath,
|
|
7892
|
+
providerDefinitions,
|
|
7893
|
+
providerDefinitionsSource,
|
|
7894
|
+
requireExplicitProviderCatalog: true,
|
|
7895
|
+
allowLegacyTargetFiles: fileOptions.allowLegacyTargetFiles,
|
|
7896
|
+
cliProviderLabel: providerSource === "cli" ? providerLabels.length === 1 ? providerLabels[0] : fileOptions.provider : fileOptions.provider,
|
|
7897
|
+
fileProviderLabel: providerSource === "test-file" && providerLabels.length === 1 ? providerLabels[0] : void 0,
|
|
7898
|
+
fileTargetSpec: providerSource === "test-file" && providerLabels.length === 1 ? suiteTargetSpec2 : void 0,
|
|
7899
|
+
modelOverride: fileOptions.providerModelOverride,
|
|
7676
7900
|
env: process.env
|
|
7677
7901
|
});
|
|
7678
|
-
const
|
|
7902
|
+
const singleProviderRef = providerRefs?.find((ref) => ref.name === selection.providerLabel);
|
|
7679
7903
|
const augmentedSelection = {
|
|
7680
7904
|
...selection,
|
|
7681
|
-
...
|
|
7682
|
-
...
|
|
7905
|
+
...singleProviderRef?.label ? { providerDisplayLabel: singleProviderRef.label } : {},
|
|
7906
|
+
...singleProviderRef?.hooks ? { providerHooks: singleProviderRef.hooks } : {}
|
|
7683
7907
|
};
|
|
7684
7908
|
selections = [
|
|
7685
7909
|
{
|
|
7686
7910
|
selection: augmentedSelection,
|
|
7687
|
-
inlineTargetLabel: augmentedSelection.
|
|
7688
|
-
augmentedSelection.
|
|
7689
|
-
augmentedSelection.
|
|
7911
|
+
inlineTargetLabel: augmentedSelection.providerDisplayLabel ?? resolveTargetLabel(
|
|
7912
|
+
augmentedSelection.providerLabel,
|
|
7913
|
+
augmentedSelection.resolvedProvider.name
|
|
7690
7914
|
)
|
|
7691
7915
|
}
|
|
7692
7916
|
];
|
|
7693
7917
|
}
|
|
7694
7918
|
}
|
|
7695
7919
|
return {
|
|
7696
|
-
options:
|
|
7920
|
+
options: fileOptions,
|
|
7697
7921
|
testIds,
|
|
7698
7922
|
testCases,
|
|
7699
7923
|
selections,
|
|
7700
|
-
trialsConfig:
|
|
7924
|
+
trialsConfig: fileOptions.experimentTrialsConfig,
|
|
7701
7925
|
suiteTargets,
|
|
7702
7926
|
yamlCache: suite.cacheConfig?.enabled,
|
|
7703
7927
|
yamlCachePath: suite.cacheConfig?.cachePath,
|
|
@@ -7708,7 +7932,7 @@ async function prepareFileMetadata(params) {
|
|
|
7708
7932
|
providerFactory: suite.providerFactory
|
|
7709
7933
|
};
|
|
7710
7934
|
}
|
|
7711
|
-
function
|
|
7935
|
+
function buildTaskBundleProviderSelections(activeTestFiles, fileMetadata) {
|
|
7712
7936
|
return activeTestFiles.flatMap((testFilePath) => {
|
|
7713
7937
|
const meta = fileMetadata.get(testFilePath);
|
|
7714
7938
|
if (!meta) {
|
|
@@ -7716,8 +7940,8 @@ function buildTaskBundleTargetSelections(activeTestFiles, fileMetadata) {
|
|
|
7716
7940
|
}
|
|
7717
7941
|
return meta.selections.map(({ selection }) => ({
|
|
7718
7942
|
evalFileAbsolutePath: testFilePath,
|
|
7719
|
-
|
|
7720
|
-
|
|
7943
|
+
providerLabel: selection.providerLabel,
|
|
7944
|
+
resolvedProviderName: selection.resolvedProvider.name,
|
|
7721
7945
|
definitions: selection.definitions
|
|
7722
7946
|
}));
|
|
7723
7947
|
});
|
|
@@ -7746,22 +7970,22 @@ async function runSingleEvalFile(params) {
|
|
|
7746
7970
|
failOnError,
|
|
7747
7971
|
providerFactory
|
|
7748
7972
|
} = params;
|
|
7749
|
-
const
|
|
7973
|
+
const providerLabel = selection.providerLabel;
|
|
7750
7974
|
const replayRecording = options.recordReplay ? {
|
|
7751
|
-
fixturesPath:
|
|
7752
|
-
sourceTarget:
|
|
7975
|
+
fixturesPath: path13.resolve(options.recordReplay),
|
|
7976
|
+
sourceTarget: providerLabel,
|
|
7753
7977
|
variant: options.recordReplayVariant
|
|
7754
7978
|
} : void 0;
|
|
7755
7979
|
await ensureFileExists(testFilePath, "Test file");
|
|
7756
|
-
const
|
|
7757
|
-
const explicitVariant = targetVariantForSelection(
|
|
7758
|
-
const
|
|
7759
|
-
const targetMessage = options.verbose ? `Using
|
|
7980
|
+
const resolvedProviderSelection = applyVerboseOverride(selection, options.verbose);
|
|
7981
|
+
const explicitVariant = targetVariantForSelection(resolvedProviderSelection);
|
|
7982
|
+
const providerId = resolvedProviderSelection.resolvedProvider.kind;
|
|
7983
|
+
const targetMessage = options.verbose ? `Using provider (${resolvedProviderSelection.providerSource}): ${resolvedProviderSelection.providerLabel} ${buildTargetLabelSuffix(providerId, resolvedProviderSelection.resolvedProvider)} via ${resolvedProviderSelection.providersFilePath}` : `Using provider: ${inlineTargetLabel}`;
|
|
7760
7984
|
if (!progressReporter.isInteractive || options.verbose) {
|
|
7761
7985
|
console.log(`${targetMessage}`);
|
|
7762
7986
|
}
|
|
7763
|
-
const
|
|
7764
|
-
if (
|
|
7987
|
+
const providerKind = resolvedProviderSelection.resolvedProvider.kind;
|
|
7988
|
+
if (providerKind === "claude-cli" || providerKind === "copilot-cli") {
|
|
7765
7989
|
console.log("");
|
|
7766
7990
|
console.log(" TIP: For subagent-mode evals, use `agentv pipeline` instead of `eval run`.");
|
|
7767
7991
|
console.log(" The agent orchestrates executor + grader subagents directly.");
|
|
@@ -7770,12 +7994,12 @@ async function runSingleEvalFile(params) {
|
|
|
7770
7994
|
}
|
|
7771
7995
|
const agentTimeoutMs = agentTimeoutSeconds != null ? Math.max(0, agentTimeoutSeconds) * 1e3 : void 0;
|
|
7772
7996
|
const workerPreference = workersOverride ?? options.workers;
|
|
7773
|
-
let resolvedWorkers = workerPreference ??
|
|
7997
|
+
let resolvedWorkers = workerPreference ?? resolvedProviderSelection.resolvedProvider.workers ?? DEFAULT_WORKERS;
|
|
7774
7998
|
if (resolvedWorkers < 1 || resolvedWorkers > 50) {
|
|
7775
7999
|
throw new Error(`Workers must be between 1 and 50, got: ${resolvedWorkers}`);
|
|
7776
8000
|
}
|
|
7777
8001
|
const isVSCodeProvider = ["vscode", "vscode-insiders"].includes(
|
|
7778
|
-
|
|
8002
|
+
resolvedProviderSelection.resolvedProvider.kind
|
|
7779
8003
|
);
|
|
7780
8004
|
if (isVSCodeProvider && resolvedWorkers > 1) {
|
|
7781
8005
|
console.warn(
|
|
@@ -7784,9 +8008,9 @@ async function runSingleEvalFile(params) {
|
|
|
7784
8008
|
resolvedWorkers = 1;
|
|
7785
8009
|
}
|
|
7786
8010
|
if (isVSCodeProvider) {
|
|
7787
|
-
const vsConfig =
|
|
8011
|
+
const vsConfig = resolvedProviderSelection.resolvedProvider.config;
|
|
7788
8012
|
await ensureVSCodeSubagents({
|
|
7789
|
-
kind:
|
|
8013
|
+
kind: resolvedProviderSelection.resolvedProvider.kind,
|
|
7790
8014
|
count: resolvedWorkers,
|
|
7791
8015
|
verbose: options.verbose,
|
|
7792
8016
|
vscodeCmd: vsConfig.executable
|
|
@@ -7795,15 +8019,15 @@ async function runSingleEvalFile(params) {
|
|
|
7795
8019
|
const results = await evaluationRunner({
|
|
7796
8020
|
testFilePath,
|
|
7797
8021
|
repoRoot,
|
|
7798
|
-
target:
|
|
7799
|
-
targets:
|
|
8022
|
+
target: resolvedProviderSelection.resolvedProvider,
|
|
8023
|
+
targets: resolvedProviderSelection.definitions,
|
|
7800
8024
|
env: process.env,
|
|
7801
8025
|
maxRetries: Math.max(0, options.maxRetries),
|
|
7802
8026
|
agentTimeoutMs,
|
|
7803
8027
|
cache,
|
|
7804
8028
|
useCache: (() => {
|
|
7805
8029
|
if (!cache) return false;
|
|
7806
|
-
const targetConfig =
|
|
8030
|
+
const targetConfig = resolvedProviderSelection.resolvedProvider.config;
|
|
7807
8031
|
if (shouldSkipCacheForTemperature(targetConfig)) {
|
|
7808
8032
|
if (options.verbose) {
|
|
7809
8033
|
console.log("Cache skipped: target temperature > 0");
|
|
@@ -7823,9 +8047,10 @@ async function runSingleEvalFile(params) {
|
|
|
7823
8047
|
runBudgetTracker,
|
|
7824
8048
|
failOnError,
|
|
7825
8049
|
graderTarget: options.graderTarget,
|
|
8050
|
+
defaultGraderTarget: options.defaultGraderTarget,
|
|
7826
8051
|
model: options.model,
|
|
7827
8052
|
threshold: params.threshold,
|
|
7828
|
-
targetHooks:
|
|
8053
|
+
targetHooks: resolvedProviderSelection.providerHooks,
|
|
7829
8054
|
replayRecording,
|
|
7830
8055
|
providerFactory,
|
|
7831
8056
|
onResult: async (result) => {
|
|
@@ -7835,7 +8060,7 @@ async function runSingleEvalFile(params) {
|
|
|
7835
8060
|
await outputWriter.append(trimmedResult);
|
|
7836
8061
|
},
|
|
7837
8062
|
onProgress: async (event) => {
|
|
7838
|
-
const testCaseKeyId = matrixMode ? `${event.testId}@${
|
|
8063
|
+
const testCaseKeyId = matrixMode ? `${event.testId}@${providerLabel}` : event.testId;
|
|
7839
8064
|
const testCaseKey = makeTestCaseKey(testFilePath, testCaseKeyId);
|
|
7840
8065
|
if (event.status === "pending" && !seenTestCases.has(testCaseKey)) {
|
|
7841
8066
|
seenTestCases.add(testCaseKey);
|
|
@@ -7848,7 +8073,7 @@ async function runSingleEvalFile(params) {
|
|
|
7848
8073
|
else if (event.executionStatus === "execution_error") verdict = "ERROR";
|
|
7849
8074
|
progressReporter.update(displayId, {
|
|
7850
8075
|
workerId: displayId,
|
|
7851
|
-
testId: matrixMode ? `${event.testId}@${
|
|
8076
|
+
testId: matrixMode ? `${event.testId}@${providerLabel}` : event.testId,
|
|
7852
8077
|
status: event.status,
|
|
7853
8078
|
startedAt: event.startedAt,
|
|
7854
8079
|
completedAt: event.completedAt,
|
|
@@ -7882,7 +8107,7 @@ async function runEvalCommand(input) {
|
|
|
7882
8107
|
);
|
|
7883
8108
|
}
|
|
7884
8109
|
const repoRoot = await findRepoRoot(cwd);
|
|
7885
|
-
const yamlConfig = await loadConfig(
|
|
8110
|
+
const yamlConfig = await loadConfig(path13.join(cwd, "_"), repoRoot);
|
|
7886
8111
|
let requiredVersionCheck;
|
|
7887
8112
|
if (yamlConfig?.required_version) {
|
|
7888
8113
|
requiredVersionCheck = await enforceRequiredVersion(yamlConfig.required_version, {
|
|
@@ -7890,10 +8115,19 @@ async function runEvalCommand(input) {
|
|
|
7890
8115
|
});
|
|
7891
8116
|
}
|
|
7892
8117
|
let options = normalizeOptions(input.rawOptions, config, yamlConfig?.execution);
|
|
8118
|
+
if (yamlConfig?.defaults?.provider && options.cliProviderLabels.length === 0 && !options.provider) {
|
|
8119
|
+
options = { ...options, provider: yamlConfig.defaults.provider };
|
|
8120
|
+
}
|
|
8121
|
+
if (yamlConfig?.defaults?.grader) {
|
|
8122
|
+
options = { ...options, defaultGraderTarget: yamlConfig.defaults.grader };
|
|
8123
|
+
}
|
|
8124
|
+
const providerCatalogPath = yamlConfig?.providerCatalogPath;
|
|
8125
|
+
const providerDefinitions = yamlConfig?.providerDefinitions;
|
|
8126
|
+
const providerDefinitionsSource = providerDefinitions ? providerCatalogPath ?? ".agentv/config.yaml:providers" : void 0;
|
|
7893
8127
|
const resolvedExperiment = resolveExperimentForRun(options.experiment);
|
|
7894
8128
|
const evalPathInputs = input.testFiles.length > 0 ? [...input.testFiles] : [];
|
|
7895
8129
|
if (evalPathInputs.length === 0 && process.stdin.isTTY) {
|
|
7896
|
-
const { launchInteractiveWizard } = await import("./interactive-
|
|
8130
|
+
const { launchInteractiveWizard } = await import("./interactive-WPQJDJKZ.js");
|
|
7897
8131
|
await launchInteractiveWizard();
|
|
7898
8132
|
return void 0;
|
|
7899
8133
|
}
|
|
@@ -7904,7 +8138,7 @@ async function runEvalCommand(input) {
|
|
|
7904
8138
|
const primarySuite = resolvedTestFiles.length > 0 ? await loadCliEvalSuite(resolvedTestFiles[0], repoRoot, {
|
|
7905
8139
|
verbose: options.verbose,
|
|
7906
8140
|
filter: options.filter,
|
|
7907
|
-
category: deriveCategory(
|
|
8141
|
+
category: deriveCategory(path13.relative(cwd, resolvedTestFiles[0]))
|
|
7908
8142
|
}) : void 0;
|
|
7909
8143
|
const resultGroupName = resolvedTestFiles.length === 1 ? primarySuite?.metadata?.name ?? fallbackResultGroupName : fallbackResultGroupName;
|
|
7910
8144
|
const resolvedTags = resolveEffectiveTags({
|
|
@@ -7933,7 +8167,7 @@ async function runEvalCommand(input) {
|
|
|
7933
8167
|
process.env.AGENTV_EXPERIMENT = normalizedExperiment;
|
|
7934
8168
|
}
|
|
7935
8169
|
if (options.graderTarget === "agentv" && !options.model) {
|
|
7936
|
-
throw new Error("--grader-
|
|
8170
|
+
throw new Error("--grader-provider agentv requires --model (e.g., --model openai:gpt-5-mini)");
|
|
7937
8171
|
}
|
|
7938
8172
|
if (options.removedOut) {
|
|
7939
8173
|
throw new Error(
|
|
@@ -7957,7 +8191,7 @@ async function runEvalCommand(input) {
|
|
|
7957
8191
|
}
|
|
7958
8192
|
let retryNonErrorResults;
|
|
7959
8193
|
if (options.retryErrors) {
|
|
7960
|
-
const retryPath =
|
|
8194
|
+
const retryPath = path13.resolve(options.retryErrors);
|
|
7961
8195
|
await ensureFileExists(retryPath, "Retry-errors JSONL file");
|
|
7962
8196
|
const completedIds = await loadFullyCompletedTestIds(retryPath);
|
|
7963
8197
|
const errorIds = await loadErrorTestIds(retryPath);
|
|
@@ -7974,7 +8208,7 @@ async function runEvalCommand(input) {
|
|
|
7974
8208
|
const cachedDir = await resolveCachedRunDir(cwd);
|
|
7975
8209
|
if (cachedDir) {
|
|
7976
8210
|
options = { ...options, outputDir: cachedDir };
|
|
7977
|
-
const displayDir =
|
|
8211
|
+
const displayDir = path13.relative(cwd, cachedDir) || cachedDir;
|
|
7978
8212
|
console.log(`Auto-detected last run dir for --resume: ${displayDir}`);
|
|
7979
8213
|
}
|
|
7980
8214
|
}
|
|
@@ -7982,7 +8216,7 @@ async function runEvalCommand(input) {
|
|
|
7982
8216
|
let rerunIncludeKeys;
|
|
7983
8217
|
let isResumeAppend = false;
|
|
7984
8218
|
if (options.resume && !options.retryErrors) {
|
|
7985
|
-
const sourceRunDir = options.rerunFailedSource ? await resolveRerunFailedRunDir(cwd, options.rerunFailedSource) : options.outputDir ?
|
|
8219
|
+
const sourceRunDir = options.rerunFailedSource ? await resolveRerunFailedRunDir(cwd, options.rerunFailedSource) : options.outputDir ? path13.resolve(options.outputDir) : void 0;
|
|
7986
8220
|
if (sourceRunDir) {
|
|
7987
8221
|
if (options.rerunFailedSource && !options.outputDir) {
|
|
7988
8222
|
options = { ...options, outputDir: sourceRunDir };
|
|
@@ -8001,7 +8235,7 @@ async function runEvalCommand(input) {
|
|
|
8001
8235
|
addResumeIdentityEntry(rerunIncludeKeys, entry);
|
|
8002
8236
|
}
|
|
8003
8237
|
}
|
|
8004
|
-
isResumeAppend = options.outputDir !== void 0 &&
|
|
8238
|
+
isResumeAppend = options.outputDir !== void 0 && path13.resolve(options.outputDir) === path13.resolve(sourceRunDir);
|
|
8005
8239
|
const modeLabel = options.rerunFailed ? "Rerun-failed" : "Resume";
|
|
8006
8240
|
console.log(
|
|
8007
8241
|
`${modeLabel}: found ${existingResults.length} existing result(s), skipping ${completedResultCount} completed.`
|
|
@@ -8019,10 +8253,10 @@ async function runEvalCommand(input) {
|
|
|
8019
8253
|
}
|
|
8020
8254
|
}
|
|
8021
8255
|
if (options.workspacePath) {
|
|
8022
|
-
const resolvedWorkspace =
|
|
8256
|
+
const resolvedWorkspace = path13.resolve(options.workspacePath);
|
|
8023
8257
|
try {
|
|
8024
|
-
const { stat:
|
|
8025
|
-
const stats = await
|
|
8258
|
+
const { stat: stat4 } = await import("node:fs/promises");
|
|
8259
|
+
const stats = await stat4(resolvedWorkspace);
|
|
8026
8260
|
if (!stats.isDirectory()) {
|
|
8027
8261
|
throw new Error(`--workspace-path is not a directory: ${resolvedWorkspace}`);
|
|
8028
8262
|
}
|
|
@@ -8042,7 +8276,7 @@ async function runEvalCommand(input) {
|
|
|
8042
8276
|
let outputPath;
|
|
8043
8277
|
let runDirName = process.env.AGENTV_RUN_TIMESTAMP?.trim() || createRunDirName();
|
|
8044
8278
|
if (explicitDir) {
|
|
8045
|
-
runDir =
|
|
8279
|
+
runDir = path13.resolve(explicitDir);
|
|
8046
8280
|
mkdirSync(runDir, { recursive: true });
|
|
8047
8281
|
outputPath = runDir;
|
|
8048
8282
|
} else {
|
|
@@ -8057,7 +8291,7 @@ async function runEvalCommand(input) {
|
|
|
8057
8291
|
outputPath = runDir;
|
|
8058
8292
|
}
|
|
8059
8293
|
if (!process.env.AGENTV_RUN_TIMESTAMP) {
|
|
8060
|
-
process.env.AGENTV_RUN_TIMESTAMP =
|
|
8294
|
+
process.env.AGENTV_RUN_TIMESTAMP = path13.basename(runDir);
|
|
8061
8295
|
}
|
|
8062
8296
|
process.env.AGENTV_RUN_DIR = runDir;
|
|
8063
8297
|
console.log(`Artifact directory: ${runDir}`);
|
|
@@ -8072,11 +8306,15 @@ async function runEvalCommand(input) {
|
|
|
8072
8306
|
}
|
|
8073
8307
|
const fileMetadata = /* @__PURE__ */ new Map();
|
|
8074
8308
|
for (const testFilePath of resolvedTestFiles) {
|
|
8309
|
+
const fileProviderCatalogPath = options.providerCatalogPathByEvalFile?.get(path13.resolve(testFilePath)) ?? providerCatalogPath;
|
|
8075
8310
|
const meta = await prepareFileMetadata({
|
|
8076
8311
|
testFilePath,
|
|
8077
8312
|
repoRoot,
|
|
8078
8313
|
cwd,
|
|
8079
8314
|
options,
|
|
8315
|
+
providerCatalogPath: fileProviderCatalogPath,
|
|
8316
|
+
providerDefinitions,
|
|
8317
|
+
providerDefinitionsSource: fileProviderCatalogPath ? fileProviderCatalogPath === providerCatalogPath ? providerDefinitionsSource : void 0 : providerDefinitionsSource,
|
|
8080
8318
|
suiteFilter: void 0
|
|
8081
8319
|
});
|
|
8082
8320
|
fileMetadata.set(testFilePath, meta);
|
|
@@ -8087,7 +8325,7 @@ async function runEvalCommand(input) {
|
|
|
8087
8325
|
for (const [testFilePath, meta] of fileMetadata.entries()) {
|
|
8088
8326
|
if (!matchesTagFilters(meta.tags, options.tags, options.excludeTags)) {
|
|
8089
8327
|
fileMetadata.delete(testFilePath);
|
|
8090
|
-
skippedFiles.push(
|
|
8328
|
+
skippedFiles.push(path13.relative(cwd, testFilePath));
|
|
8091
8329
|
}
|
|
8092
8330
|
}
|
|
8093
8331
|
if (skippedFiles.length > 0 && options.verbose) {
|
|
@@ -8110,12 +8348,12 @@ async function runEvalCommand(input) {
|
|
|
8110
8348
|
tsConfigCache: options.tsConfigCache
|
|
8111
8349
|
});
|
|
8112
8350
|
const activeCachePath = options.cachePath ?? yamlCachePath ?? options.tsConfigCachePath;
|
|
8113
|
-
const cache = cacheEnabled ? new ResponseCache(activeCachePath ?
|
|
8351
|
+
const cache = cacheEnabled ? new ResponseCache(activeCachePath ? path13.resolve(activeCachePath) : void 0) : void 0;
|
|
8114
8352
|
if (cache) {
|
|
8115
8353
|
console.log(`Response cache: enabled (${cache.cachePath})`);
|
|
8116
8354
|
}
|
|
8117
8355
|
if (options.recordReplay) {
|
|
8118
|
-
console.log(`Replay recording: ${
|
|
8356
|
+
console.log(`Replay recording: ${path13.resolve(options.recordReplay)}`);
|
|
8119
8357
|
}
|
|
8120
8358
|
const yamlThreshold = firstMeta?.threshold;
|
|
8121
8359
|
const resolvedThreshold = options.threshold ?? yamlThreshold;
|
|
@@ -8129,7 +8367,7 @@ async function runEvalCommand(input) {
|
|
|
8129
8367
|
for (const meta of fileMetadata.values()) {
|
|
8130
8368
|
for (const test of meta.testCases) {
|
|
8131
8369
|
for (const { selection } of meta.selections) {
|
|
8132
|
-
const target = selection.
|
|
8370
|
+
const target = selection.providerLabel;
|
|
8133
8371
|
const variant = targetVariantForSelection(selection);
|
|
8134
8372
|
if (rerunIncludeKeys) {
|
|
8135
8373
|
if (resumeIdentityMatches(rerunIncludeKeys, test, target, variant)) {
|
|
@@ -8201,13 +8439,13 @@ async function runEvalCommand(input) {
|
|
|
8201
8439
|
for (const testId of meta.testIds) {
|
|
8202
8440
|
const testCaseKey = makeTestCaseKey(
|
|
8203
8441
|
testFilePath,
|
|
8204
|
-
meta.selections.length > 1 ? `${testId}@${selection.
|
|
8442
|
+
meta.selections.length > 1 ? `${testId}@${selection.providerLabel}` : testId
|
|
8205
8443
|
);
|
|
8206
8444
|
seenTestCases.add(testCaseKey);
|
|
8207
8445
|
const displayId = displayIdTracker.getOrAssign(testCaseKey);
|
|
8208
8446
|
progressReporter.update(displayId, {
|
|
8209
8447
|
workerId: displayId,
|
|
8210
|
-
testId: meta.selections.length > 1 ? `${testId}@${selection.
|
|
8448
|
+
testId: meta.selections.length > 1 ? `${testId}@${selection.providerLabel}` : testId,
|
|
8211
8449
|
status: "pending",
|
|
8212
8450
|
targetLabel: inlineTargetLabel
|
|
8213
8451
|
});
|
|
@@ -8233,7 +8471,7 @@ async function runEvalCommand(input) {
|
|
|
8233
8471
|
});
|
|
8234
8472
|
let transcriptProviderFactory;
|
|
8235
8473
|
if (options.transcript) {
|
|
8236
|
-
const { TranscriptProvider } = await import("./dist-
|
|
8474
|
+
const { TranscriptProvider } = await import("./dist-A3SGR7TW.js");
|
|
8237
8475
|
const transcriptProvider = await TranscriptProvider.fromFile(options.transcript);
|
|
8238
8476
|
const totalTests = [...fileMetadata.values()].reduce(
|
|
8239
8477
|
(sum, meta) => sum + meta.testCases.length,
|
|
@@ -8266,12 +8504,12 @@ async function runEvalCommand(input) {
|
|
|
8266
8504
|
);
|
|
8267
8505
|
}
|
|
8268
8506
|
if (!isResumeAppend && totalEvalCount > 0) {
|
|
8269
|
-
const evalFile = activeTestFiles.length === 1 ? activeTestFiles[0] : "";
|
|
8507
|
+
const evalFile = activeTestFiles.length === 1 ? path13.relative(cwd, activeTestFiles[0]) : "";
|
|
8270
8508
|
await writeInitialRunSummaryArtifact(runDir, {
|
|
8271
8509
|
evalFile,
|
|
8272
8510
|
plannedTestCount: totalEvalCount,
|
|
8273
8511
|
experiment: normalizeExperimentName(options.experiment),
|
|
8274
|
-
runId:
|
|
8512
|
+
runId: path13.basename(runDir),
|
|
8275
8513
|
experimentMetadata: runExperimentMetadata,
|
|
8276
8514
|
runtimeSource: runtimeSourceMetadata,
|
|
8277
8515
|
tags: emittedTags
|
|
@@ -8307,7 +8545,7 @@ async function runEvalCommand(input) {
|
|
|
8307
8545
|
if (fileBudgetTracker?.isExceeded()) {
|
|
8308
8546
|
const budgetMsg = `Run budget exceeded ($${fileBudgetTracker.currentCostUsd.toFixed(4)} / $${fileBudgetTracker.budgetCapUsd.toFixed(4)})`;
|
|
8309
8547
|
console.log(`
|
|
8310
|
-
\u26A0 ${budgetMsg} \u2014 skipping ${
|
|
8548
|
+
\u26A0 ${budgetMsg} \u2014 skipping ${path13.basename(testFilePath)}`);
|
|
8311
8549
|
for (const { selection } of targetPrep.selections) {
|
|
8312
8550
|
const explicitVariant = targetVariantForSelection(selection);
|
|
8313
8551
|
const skippedResults = targetPrep.testCases.map((testCase) => ({
|
|
@@ -8321,7 +8559,7 @@ async function runEvalCommand(input) {
|
|
|
8321
8559
|
input: testCase.input,
|
|
8322
8560
|
output: [{ role: "assistant", content: budgetMsg }],
|
|
8323
8561
|
finalOutput: budgetMsg,
|
|
8324
|
-
target: selection.
|
|
8562
|
+
target: selection.providerLabel,
|
|
8325
8563
|
testId: testCase.testId ?? testCase.id,
|
|
8326
8564
|
conversationId: testCase.conversation_id,
|
|
8327
8565
|
error: budgetMsg
|
|
@@ -8332,7 +8570,7 @@ async function runEvalCommand(input) {
|
|
|
8332
8570
|
failureStage: "setup",
|
|
8333
8571
|
failureReasonCode: "budget_exceeded",
|
|
8334
8572
|
executionError: { message: budgetMsg, stage: "setup" },
|
|
8335
|
-
target: selection.
|
|
8573
|
+
target: selection.providerLabel,
|
|
8336
8574
|
variant: explicitVariant
|
|
8337
8575
|
}));
|
|
8338
8576
|
for (const r of skippedResults) {
|
|
@@ -8351,18 +8589,18 @@ async function runEvalCommand(input) {
|
|
|
8351
8589
|
const targetResults = await Promise.all(
|
|
8352
8590
|
targetPrep.selections.map(
|
|
8353
8591
|
({ selection, inlineTargetLabel }) => limitTarget(async () => {
|
|
8354
|
-
const
|
|
8592
|
+
const providerLabel = selection.providerLabel;
|
|
8355
8593
|
const applicableTestCases = targetPrep.testCases;
|
|
8356
8594
|
const filteredTestCases = rerunIncludeKeys ? applicableTestCases.filter(
|
|
8357
8595
|
(test) => resumeIdentityMatches(
|
|
8358
8596
|
rerunIncludeKeys,
|
|
8359
8597
|
test,
|
|
8360
|
-
|
|
8598
|
+
providerLabel,
|
|
8361
8599
|
targetVariantForSelection(selection)
|
|
8362
8600
|
)
|
|
8363
8601
|
) : resumeSkipKeys ? applicableTestCases.filter((test) => {
|
|
8364
8602
|
const variant = targetVariantForSelection(selection);
|
|
8365
|
-
return !resumeIdentityMatches(resumeSkipKeys, test,
|
|
8603
|
+
return !resumeIdentityMatches(resumeSkipKeys, test, providerLabel, variant);
|
|
8366
8604
|
}) : applicableTestCases;
|
|
8367
8605
|
if (filteredTestCases.length === 0) {
|
|
8368
8606
|
return [];
|
|
@@ -8405,7 +8643,7 @@ async function runEvalCommand(input) {
|
|
|
8405
8643
|
});
|
|
8406
8644
|
groupResults.push(...result.results);
|
|
8407
8645
|
}
|
|
8408
|
-
const evalFile =
|
|
8646
|
+
const evalFile = path13.relative(cwd, testFilePath);
|
|
8409
8647
|
const existingSummary = remoteEvalSummaries.find(
|
|
8410
8648
|
(summary2) => summary2.evalFile === evalFile
|
|
8411
8649
|
);
|
|
@@ -8422,7 +8660,7 @@ async function runEvalCommand(input) {
|
|
|
8422
8660
|
const message = fileError instanceof Error ? fileError.message : String(fileError);
|
|
8423
8661
|
console.error(
|
|
8424
8662
|
`
|
|
8425
|
-
[ERROR] \u26A0 Eval file failed: ${
|
|
8663
|
+
[ERROR] \u26A0 Eval file failed: ${path13.basename(testFilePath)} \u2014 ${message}
|
|
8426
8664
|
`
|
|
8427
8665
|
);
|
|
8428
8666
|
const explicitVariant = targetVariantForSelection(selection);
|
|
@@ -8439,7 +8677,7 @@ async function runEvalCommand(input) {
|
|
|
8439
8677
|
input: testCase.input,
|
|
8440
8678
|
output: [{ role: "assistant", content: message }],
|
|
8441
8679
|
finalOutput: message,
|
|
8442
|
-
target: selection.
|
|
8680
|
+
target: selection.providerLabel,
|
|
8443
8681
|
testId: testCase.testId ?? testCase.id,
|
|
8444
8682
|
conversationId: testCase.conversation_id,
|
|
8445
8683
|
error: message
|
|
@@ -8451,7 +8689,7 @@ async function runEvalCommand(input) {
|
|
|
8451
8689
|
failureReasonCode: "setup_error",
|
|
8452
8690
|
durationMs: 0,
|
|
8453
8691
|
tokenUsage: { input: 0, output: 0 },
|
|
8454
|
-
target: selection.
|
|
8692
|
+
target: selection.providerLabel,
|
|
8455
8693
|
variant: explicitVariant
|
|
8456
8694
|
},
|
|
8457
8695
|
testFilePath,
|
|
@@ -8481,7 +8719,11 @@ async function runEvalCommand(input) {
|
|
|
8481
8719
|
);
|
|
8482
8720
|
}
|
|
8483
8721
|
await outputWriter.close().catch(() => void 0);
|
|
8484
|
-
const summaryResults =
|
|
8722
|
+
const summaryResults = await collectTerminalSummaryResults({
|
|
8723
|
+
allResults,
|
|
8724
|
+
isResumeAppend,
|
|
8725
|
+
runDir
|
|
8726
|
+
});
|
|
8485
8727
|
const thresholdOpts = hasScopedRunPolicies || hasPerFileRuntimeThresholds ? { thresholdLabel: "configured threshold(s)", useExecutionStatus: true } : resolvedThreshold !== void 0 ? { threshold: resolvedThreshold } : void 0;
|
|
8486
8728
|
const summary = calculateEvaluationSummary(summaryResults, thresholdOpts);
|
|
8487
8729
|
console.log(formatEvaluationSummary(summary, thresholdOpts));
|
|
@@ -8495,14 +8737,14 @@ ${formatRequiredVersionFailureNote(requiredVersionCheck)}`);
|
|
|
8495
8737
|
console.log(formatMatrixSummary(summaryResults));
|
|
8496
8738
|
}
|
|
8497
8739
|
if (allResults.length > 0) {
|
|
8498
|
-
const evalFile = activeTestFiles.length === 1 ? activeTestFiles[0] : "";
|
|
8740
|
+
const evalFile = activeTestFiles.length === 1 ? path13.relative(cwd, activeTestFiles[0]) : "";
|
|
8499
8741
|
const sourceTests = activeSourceTests;
|
|
8500
|
-
const taskBundleTargets =
|
|
8742
|
+
const taskBundleTargets = buildTaskBundleProviderSelections(activeTestFiles, fileMetadata);
|
|
8501
8743
|
if (isResumeAppend) {
|
|
8502
|
-
const { writePerTestArtifacts } = await import("./artifact-writer-
|
|
8744
|
+
const { writePerTestArtifacts } = await import("./artifact-writer-KJEOROKQ.js");
|
|
8503
8745
|
await writePerTestArtifacts(allResults, runDir, {
|
|
8504
8746
|
experiment: normalizeExperimentName(options.experiment),
|
|
8505
|
-
runId:
|
|
8747
|
+
runId: path13.basename(runDir),
|
|
8506
8748
|
resultGroup: resultGroupName,
|
|
8507
8749
|
cwd,
|
|
8508
8750
|
repoRoot,
|
|
@@ -8514,7 +8756,7 @@ ${formatRequiredVersionFailureNote(requiredVersionCheck)}`);
|
|
|
8514
8756
|
const { summaryPath } = await aggregateRunDir(runDir, {
|
|
8515
8757
|
evalFile,
|
|
8516
8758
|
experiment: normalizeExperimentName(options.experiment),
|
|
8517
|
-
runId:
|
|
8759
|
+
runId: path13.basename(runDir),
|
|
8518
8760
|
experimentMetadata: runExperimentMetadata,
|
|
8519
8761
|
runtimeSource: runtimeSourceMetadata,
|
|
8520
8762
|
tags: emittedTags
|
|
@@ -8531,7 +8773,7 @@ ${formatRequiredVersionFailureNote(requiredVersionCheck)}`);
|
|
|
8531
8773
|
{
|
|
8532
8774
|
evalFile,
|
|
8533
8775
|
experiment: normalizeExperimentName(options.experiment),
|
|
8534
|
-
runId:
|
|
8776
|
+
runId: path13.basename(runDir),
|
|
8535
8777
|
experimentMetadata: runExperimentMetadata,
|
|
8536
8778
|
resultGroup: resultGroupName,
|
|
8537
8779
|
cwd,
|
|
@@ -8594,9 +8836,9 @@ Results written under: ${runDir}`);
|
|
|
8594
8836
|
});
|
|
8595
8837
|
}
|
|
8596
8838
|
if (summary.executionErrorCount > 0 && !options.retryErrors && !options.resume) {
|
|
8597
|
-
const evalFileArgs = activeTestFiles.map((f) =>
|
|
8598
|
-
const targetFlag = options.
|
|
8599
|
-
const relativeRunDir =
|
|
8839
|
+
const evalFileArgs = activeTestFiles.map((f) => path13.relative(cwd, f)).join(" ");
|
|
8840
|
+
const targetFlag = options.provider ? ` --provider ${options.provider}` : "";
|
|
8841
|
+
const relativeRunDir = path13.relative(cwd, runDir);
|
|
8600
8842
|
console.log(
|
|
8601
8843
|
`
|
|
8602
8844
|
Tip: ${summary.executionErrorCount} execution error(s) detected. Re-run failed tests with:
|
|
@@ -8618,7 +8860,7 @@ Tip: ${summary.executionErrorCount} execution error(s) detected. Re-run failed t
|
|
|
8618
8860
|
executionErrorCount: summary.executionErrorCount,
|
|
8619
8861
|
outputPath,
|
|
8620
8862
|
testFiles: activeTestFiles,
|
|
8621
|
-
|
|
8863
|
+
provider: options.provider,
|
|
8622
8864
|
thresholdFailed,
|
|
8623
8865
|
allExecutionErrors,
|
|
8624
8866
|
budgetExceeded: runBudgetExceeded || void 0
|
|
@@ -8639,7 +8881,7 @@ async function resolveEvaluationRunner() {
|
|
|
8639
8881
|
if (!overridePath) {
|
|
8640
8882
|
return runEvaluation;
|
|
8641
8883
|
}
|
|
8642
|
-
const resolved =
|
|
8884
|
+
const resolved = path13.isAbsolute(overridePath) ? overridePath : path13.resolve(process.cwd(), overridePath);
|
|
8643
8885
|
const moduleUrl = pathToFileURL(resolved).href;
|
|
8644
8886
|
const mod = await import(moduleUrl);
|
|
8645
8887
|
const candidate = mod.runEvaluation;
|
|
@@ -8673,9 +8915,9 @@ export {
|
|
|
8673
8915
|
normalizeTagMap,
|
|
8674
8916
|
loadLightweightResults,
|
|
8675
8917
|
Mutex,
|
|
8676
|
-
|
|
8918
|
+
PROVIDER_FILE_CANDIDATES,
|
|
8677
8919
|
fileExists,
|
|
8678
|
-
|
|
8920
|
+
discoverProvidersFile,
|
|
8679
8921
|
loadEnvFromHierarchy,
|
|
8680
8922
|
detectFileType,
|
|
8681
8923
|
validateEvalFile,
|
|
@@ -8685,9 +8927,9 @@ export {
|
|
|
8685
8927
|
validateConfigFile,
|
|
8686
8928
|
validateFileReferences,
|
|
8687
8929
|
validateWorkspacePaths,
|
|
8688
|
-
|
|
8689
|
-
|
|
8690
|
-
|
|
8930
|
+
readTestSuiteProvider,
|
|
8931
|
+
selectProvider,
|
|
8932
|
+
selectMultipleProviders,
|
|
8691
8933
|
enforceRequiredVersion,
|
|
8692
8934
|
c,
|
|
8693
8935
|
padRight,
|
|
@@ -8718,4 +8960,4 @@ export {
|
|
|
8718
8960
|
filterByCategory,
|
|
8719
8961
|
runEvalCommand
|
|
8720
8962
|
};
|
|
8721
|
-
//# sourceMappingURL=chunk-
|
|
8963
|
+
//# sourceMappingURL=chunk-6RFRY7X2.js.map
|