agentv 5.1.0-next.1 → 5.3.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -12
- package/dist/{artifact-writer-IORG7CW5.js → artifact-writer-JFNIPMKW.js} +5 -5
- package/dist/{chunk-ZGPCX334.js → chunk-6ZZCDZPD.js} +4101 -1204
- package/dist/chunk-6ZZCDZPD.js.map +1 -0
- package/dist/{chunk-CBBBRTQ3.js → chunk-BHKQHG26.js} +64 -3
- package/dist/chunk-BHKQHG26.js.map +1 -0
- package/dist/{chunk-AM2IPHKS.js → chunk-FVR4RQFK.js} +302 -162
- package/dist/chunk-FVR4RQFK.js.map +1 -0
- package/dist/{chunk-GIRUNQGP.js → chunk-T32NL3E6.js} +262 -154
- package/dist/chunk-T32NL3E6.js.map +1 -0
- package/dist/{chunk-GJWPQXHN.js → chunk-V52ATPTT.js} +104 -188
- package/dist/chunk-V52ATPTT.js.map +1 -0
- package/dist/cli.js +6 -6
- package/dist/dashboard/assets/{index-BSHoWrdr.js → index-DNgf3qJ2.js} +1 -1
- package/dist/dashboard/assets/{index-zvUKAkKn.css → index-D_bokML8.css} +1 -1
- package/dist/dashboard/assets/index-r_jSJmlw.js +121 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/{dist-2D2GBHZV.js → dist-6Z7U473R.js} +14 -8
- package/dist/index.js +6 -6
- package/dist/{interactive-V4SEHLNY.js → interactive-RUY3OCBI.js} +6 -6
- package/dist/skills/agentv-bench/SKILL.md +17 -13
- package/dist/skills/agentv-bench/agents/analyzer.md +1 -1
- package/dist/skills/agentv-bench/agents/comparator.md +3 -3
- package/dist/skills/agentv-bench/agents/grader.md +4 -2
- package/dist/skills/agentv-bench/references/description-optimization.md +5 -6
- package/dist/skills/agentv-bench/references/environment-adaptation.md +2 -2
- package/dist/skills/agentv-bench/references/eval-yaml-spec.md +35 -19
- package/dist/skills/agentv-bench/references/migrating-from-skill-creator.md +1 -1
- package/dist/skills/agentv-eval-migrations/references/breaking-changes.md +125 -28
- package/dist/skills/agentv-eval-writer/SKILL.md +113 -87
- package/dist/skills/agentv-eval-writer/references/eval.schema.json +772 -1367
- package/dist/{ts-eval-loader-SSPJVEHD-AL2A3V5Z.js → ts-eval-loader-DQDYRULE-V3377FOL.js} +3 -2
- package/package.json +8 -2
- package/dist/chunk-AM2IPHKS.js.map +0 -1
- package/dist/chunk-CBBBRTQ3.js.map +0 -1
- package/dist/chunk-GIRUNQGP.js.map +0 -1
- package/dist/chunk-GJWPQXHN.js.map +0 -1
- package/dist/chunk-ZGPCX334.js.map +0 -1
- package/dist/dashboard/assets/index-BaLLxmVO.js +0 -121
- /package/dist/{artifact-writer-IORG7CW5.js.map → artifact-writer-JFNIPMKW.js.map} +0 -0
- /package/dist/{dist-2D2GBHZV.js.map → dist-6Z7U473R.js.map} +0 -0
- /package/dist/{interactive-V4SEHLNY.js.map → interactive-RUY3OCBI.js.map} +0 -0
- /package/dist/{ts-eval-loader-SSPJVEHD-AL2A3V5Z.js.map → ts-eval-loader-DQDYRULE-V3377FOL.js.map} +0 -0
|
@@ -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-BHKQHG26.js";
|
|
5
5
|
import {
|
|
6
6
|
RunBudgetTracker,
|
|
7
7
|
buildWipBranchName,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
resolveResultsRepoRunsDir,
|
|
19
19
|
setupWipWorktree,
|
|
20
20
|
syncResultsRepoForProject
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-V52ATPTT.js";
|
|
22
22
|
import {
|
|
23
23
|
AGENTV_LOCAL_CONFIG_FILE_NAME,
|
|
24
24
|
AGENTV_LOCAL_CONFIG_YML_FILE_NAME,
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
loadTestSuite,
|
|
60
60
|
loadTestSuiteFromYamlObject,
|
|
61
61
|
normalizeComposableConfigGraph,
|
|
62
|
+
normalizeMetricsArtifactWire,
|
|
62
63
|
normalizeResultRow,
|
|
63
64
|
normalizeTargetDefinition,
|
|
64
65
|
parseJsonlResults,
|
|
@@ -66,6 +67,7 @@ import {
|
|
|
66
67
|
readTargetDefinitions,
|
|
67
68
|
readTestSuiteMetadata,
|
|
68
69
|
resolveConfigFieldReferences,
|
|
70
|
+
resolveEnvironmentRecipe,
|
|
69
71
|
resolveFileReference,
|
|
70
72
|
resolveResultsConfigForProject,
|
|
71
73
|
resolveTargetDefinition,
|
|
@@ -82,7 +84,7 @@ import {
|
|
|
82
84
|
traceEnvelopeToTraceSummary,
|
|
83
85
|
traceEnvelopeToTranscriptMessages,
|
|
84
86
|
writeInitialRunSummaryArtifact
|
|
85
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-6ZZCDZPD.js";
|
|
86
88
|
|
|
87
89
|
// src/commands/eval/shared.ts
|
|
88
90
|
import { constants } from "node:fs";
|
|
@@ -345,7 +347,7 @@ async function findRepoRoot(start) {
|
|
|
345
347
|
// package.json
|
|
346
348
|
var package_default = {
|
|
347
349
|
name: "agentv",
|
|
348
|
-
version: "5.
|
|
350
|
+
version: "5.3.0-next.1",
|
|
349
351
|
description: "CLI entry point for AgentV",
|
|
350
352
|
type: "module",
|
|
351
353
|
repository: {
|
|
@@ -386,7 +388,7 @@ var package_default = {
|
|
|
386
388
|
yaml: "^2.8.3"
|
|
387
389
|
},
|
|
388
390
|
peerDependencies: {
|
|
389
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.
|
|
391
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.89",
|
|
390
392
|
"@github/copilot-sdk": "^1.0.3",
|
|
391
393
|
"@openai/codex-sdk": "^0.136.0",
|
|
392
394
|
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
@@ -405,6 +407,12 @@ var package_default = {
|
|
|
405
407
|
optional: true
|
|
406
408
|
}
|
|
407
409
|
},
|
|
410
|
+
optionalDependencies: {
|
|
411
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.89",
|
|
412
|
+
"@github/copilot-sdk": "^1.0.3",
|
|
413
|
+
"@openai/codex-sdk": "^0.136.0",
|
|
414
|
+
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
415
|
+
},
|
|
408
416
|
devDependencies: {
|
|
409
417
|
"@agentv/core": "workspace:*",
|
|
410
418
|
"@agentv/sdk": "workspace:*",
|
|
@@ -867,6 +875,9 @@ function readGradingAssertionResults(record) {
|
|
|
867
875
|
);
|
|
868
876
|
}
|
|
869
877
|
function readNestedGradingScores(record) {
|
|
878
|
+
if (Array.isArray(record.component_results)) {
|
|
879
|
+
return record.component_results;
|
|
880
|
+
}
|
|
870
881
|
if (Array.isArray(record.scores)) {
|
|
871
882
|
return record.scores;
|
|
872
883
|
}
|
|
@@ -878,14 +889,56 @@ function readNestedGradingScores(record) {
|
|
|
878
889
|
}
|
|
879
890
|
return void 0;
|
|
880
891
|
}
|
|
892
|
+
function componentLabel(component) {
|
|
893
|
+
const assertion = component.assertion;
|
|
894
|
+
if (assertion && typeof assertion === "object" && !Array.isArray(assertion)) {
|
|
895
|
+
const record = assertion;
|
|
896
|
+
for (const key of ["value", "name", "id", "type"]) {
|
|
897
|
+
const value = record[key];
|
|
898
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
899
|
+
return value;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
return typeof component.reason === "string" ? component.reason : "grading component";
|
|
904
|
+
}
|
|
905
|
+
function mapComponentAssertion(component) {
|
|
906
|
+
return {
|
|
907
|
+
text: componentLabel(component),
|
|
908
|
+
passed: component.pass === true,
|
|
909
|
+
evidence: typeof component.reason === "string" ? component.reason : void 0
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
function collectComponentAssertions(value) {
|
|
913
|
+
if (!Array.isArray(value)) {
|
|
914
|
+
return [];
|
|
915
|
+
}
|
|
916
|
+
return value.flatMap((component) => {
|
|
917
|
+
if (!component || typeof component !== "object" || Array.isArray(component)) {
|
|
918
|
+
return [];
|
|
919
|
+
}
|
|
920
|
+
const record = component;
|
|
921
|
+
const nested = collectComponentAssertions(record.component_results);
|
|
922
|
+
return nested.length > 0 ? nested : [mapComponentAssertion(record)];
|
|
923
|
+
});
|
|
924
|
+
}
|
|
881
925
|
function mapGradingEvaluator(evaluator) {
|
|
882
|
-
const
|
|
926
|
+
const pass = typeof evaluator.pass === "boolean" ? evaluator.pass : evaluator.verdict === "pass" || typeof evaluator.score === "number" && evaluator.score >= 0.8;
|
|
927
|
+
const verdict = pass ? "pass" : "fail";
|
|
883
928
|
const details = evaluator.details && typeof evaluator.details === "object" && !Array.isArray(evaluator.details) ? evaluator.details : void 0;
|
|
929
|
+
const assertion = evaluator.assertion && typeof evaluator.assertion === "object" && !Array.isArray(evaluator.assertion) ? evaluator.assertion : void 0;
|
|
884
930
|
return {
|
|
885
|
-
name: String(evaluator.name ??
|
|
886
|
-
type: String(evaluator.type ?? ""),
|
|
931
|
+
name: String(assertion?.name ?? assertion?.id ?? evaluator.name ?? componentLabel(evaluator)),
|
|
932
|
+
type: String(assertion?.type ?? evaluator.type ?? "llm-grader"),
|
|
887
933
|
score: typeof evaluator.score === "number" ? evaluator.score : 0,
|
|
888
|
-
|
|
934
|
+
reason: typeof evaluator.reason === "string" ? evaluator.reason : void 0,
|
|
935
|
+
assertions: (() => {
|
|
936
|
+
const nestedAssertions = collectComponentAssertions(evaluator.component_results);
|
|
937
|
+
if (nestedAssertions.length > 0) {
|
|
938
|
+
return nestedAssertions;
|
|
939
|
+
}
|
|
940
|
+
return readGradingAssertionResults(evaluator) ?? [mapComponentAssertion(evaluator)];
|
|
941
|
+
})(),
|
|
889
942
|
scores: mapGradingEvaluators(readNestedGradingScores(evaluator)),
|
|
890
943
|
weight: typeof evaluator.weight === "number" ? evaluator.weight : void 0,
|
|
891
944
|
verdict,
|
|
@@ -1001,12 +1054,15 @@ function hydrateTrace(baseDir, record, options) {
|
|
|
1001
1054
|
}
|
|
1002
1055
|
function hydrateManifestRecord(baseDir, record, options) {
|
|
1003
1056
|
const grading = readOptionalJson(baseDir, record.grading_path);
|
|
1004
|
-
const metrics =
|
|
1057
|
+
const metrics = normalizeMetricsArtifactWire(
|
|
1058
|
+
readOptionalJson(baseDir, record.metrics_path)
|
|
1059
|
+
);
|
|
1005
1060
|
const timing = metrics ?? readOptionalJson(baseDir, record.timing_path);
|
|
1006
1061
|
const testId = record.test_id ?? "unknown";
|
|
1007
|
-
const gradingAssertions = grading ?
|
|
1062
|
+
const gradingAssertions = grading ? collectComponentAssertions(grading.component_results) : void 0;
|
|
1063
|
+
const gradingRecord = grading;
|
|
1008
1064
|
const gradingScores = mapGradingEvaluators(
|
|
1009
|
-
|
|
1065
|
+
gradingRecord?.component_results ?? gradingRecord?.graders ?? gradingRecord?.evaluators
|
|
1010
1066
|
);
|
|
1011
1067
|
return {
|
|
1012
1068
|
timestamp: record.timestamp,
|
|
@@ -2800,18 +2856,63 @@ var UNSUPPORTED_PROMPTFOO_ASSERTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
2800
2856
|
"human",
|
|
2801
2857
|
"max-score",
|
|
2802
2858
|
"tool-call-f1",
|
|
2803
|
-
"skill-used",
|
|
2804
|
-
"trajectory:goal-success",
|
|
2805
|
-
"trajectory:tool-args-match",
|
|
2806
|
-
"trajectory:step-count",
|
|
2807
|
-
"trajectory:tool-sequence",
|
|
2808
|
-
"trajectory:tool-used",
|
|
2809
2859
|
"trace-error-spans",
|
|
2810
2860
|
"trace-span-count",
|
|
2811
2861
|
"trace-span-duration",
|
|
2812
2862
|
"search-rubric",
|
|
2813
2863
|
"word-count"
|
|
2814
2864
|
]);
|
|
2865
|
+
function formatJsonValue(value) {
|
|
2866
|
+
if (typeof value === "string") return value;
|
|
2867
|
+
try {
|
|
2868
|
+
return JSON.stringify(value);
|
|
2869
|
+
} catch {
|
|
2870
|
+
return String(value);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
function hasToolTrajectoryLatencyCheck(value) {
|
|
2874
|
+
const expected = value.expected;
|
|
2875
|
+
return Array.isArray(expected) && expected.some(
|
|
2876
|
+
(item) => isObject(item) && (item.max_duration_ms !== void 0 || item.maxDurationMs !== void 0)
|
|
2877
|
+
);
|
|
2878
|
+
}
|
|
2879
|
+
function staleSkillTriggerMessage(value) {
|
|
2880
|
+
const skill = typeof value.skill === "string" && value.skill.trim() ? value.skill.trim() : "";
|
|
2881
|
+
const shouldTrigger = value.should_trigger !== false;
|
|
2882
|
+
if (!skill) {
|
|
2883
|
+
return "Authored assertion type 'skill-trigger' has been removed. Use 'skill-used' with value: <skill> for expected skill use, or 'not-skill-used' with value: <skill> when the skill must not be used.";
|
|
2884
|
+
}
|
|
2885
|
+
const replacementType = shouldTrigger ? "skill-used" : "not-skill-used";
|
|
2886
|
+
return `Authored assertion type 'skill-trigger' has been removed. Replace skill: ${skill} with type: ${replacementType}, value: ${skill}.`;
|
|
2887
|
+
}
|
|
2888
|
+
function staleToolTrajectoryMessage(value) {
|
|
2889
|
+
const mode = typeof value.mode === "string" ? value.mode : void 0;
|
|
2890
|
+
if (hasToolTrajectoryLatencyCheck(value)) {
|
|
2891
|
+
return "Authored assertion type 'tool-trajectory' has been removed. Per-tool latency checks such as max_duration_ms have no Promptfoo trajectory:* equivalent in AgentV yet; use a custom script assertion or track this as unsupported future scope.";
|
|
2892
|
+
}
|
|
2893
|
+
if (mode === "any_order" && isObject(value.minimums)) {
|
|
2894
|
+
const [toolName, min] = Object.entries(value.minimums)[0] ?? [];
|
|
2895
|
+
const example = typeof toolName === "string" ? ` For example: type: trajectory:tool-used, value: { name: ${toolName}, min: ${formatJsonValue(min)} }.` : "";
|
|
2896
|
+
return `Authored assertion type 'tool-trajectory' has been removed. Replace mode: any_order minimums with one Promptfoo trajectory:tool-used assertion per tool.${example}`;
|
|
2897
|
+
}
|
|
2898
|
+
if ((mode === "in_order" || mode === "exact") && Array.isArray(value.expected)) {
|
|
2899
|
+
const steps = value.expected.filter(isObject).map((item) => item.tool).filter((tool) => typeof tool === "string");
|
|
2900
|
+
const hasArgs = value.expected.some(
|
|
2901
|
+
(item) => isObject(item) && item.args !== void 0 && item.args !== "any"
|
|
2902
|
+
);
|
|
2903
|
+
const sequenceHint = steps.length > 0 ? ` Use type: trajectory:tool-sequence, value: { mode: ${mode}, steps: ${formatJsonValue(steps)} }.` : " Use type: trajectory:tool-sequence with value: { mode, steps }.";
|
|
2904
|
+
const argsHint = hasArgs ? " Move expected args checks to trajectory:tool-args-match with Promptfoo mode: partial or exact." : "";
|
|
2905
|
+
return `Authored assertion type 'tool-trajectory' has been removed.${sequenceHint}${argsHint}`;
|
|
2906
|
+
}
|
|
2907
|
+
return "Authored assertion type 'tool-trajectory' has been removed. Use Promptfoo trajectory:* assertions: trajectory:tool-used for tool presence/counts, trajectory:tool-sequence for in_order/exact steps, and trajectory:tool-args-match for argument checks. AgentV-specific latency checks are unsupported future scope.";
|
|
2908
|
+
}
|
|
2909
|
+
function staleAuthoredAssertionMessage(value) {
|
|
2910
|
+
if (typeof value.type !== "string") return void 0;
|
|
2911
|
+
const type = value.type.replace(/_/g, "-");
|
|
2912
|
+
if (type === "skill-trigger") return staleSkillTriggerMessage(value);
|
|
2913
|
+
if (type === "tool-trajectory") return staleToolTrajectoryMessage(value);
|
|
2914
|
+
return void 0;
|
|
2915
|
+
}
|
|
2815
2916
|
var VALID_TEST_FILE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
2816
2917
|
".csv",
|
|
2817
2918
|
".cjs",
|
|
@@ -2837,10 +2938,10 @@ var KNOWN_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Set([
|
|
|
2837
2938
|
"input",
|
|
2838
2939
|
"input_files",
|
|
2839
2940
|
"prompts",
|
|
2840
|
-
"imports",
|
|
2841
2941
|
"tests",
|
|
2842
2942
|
"graders",
|
|
2843
2943
|
"defaults",
|
|
2944
|
+
"environment",
|
|
2844
2945
|
"target",
|
|
2845
2946
|
"targets",
|
|
2846
2947
|
"model",
|
|
@@ -2867,7 +2968,6 @@ var KNOWN_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Set([
|
|
|
2867
2968
|
"governance"
|
|
2868
2969
|
]);
|
|
2869
2970
|
var KNOWN_INCLUDE_FIELDS = /* @__PURE__ */ new Set(["include", "type", "select", "run"]);
|
|
2870
|
-
var KNOWN_IMPORT_FIELDS = /* @__PURE__ */ new Set(["path", "select", "run"]);
|
|
2871
2971
|
var KNOWN_RUN_OVERRIDE_FIELDS = /* @__PURE__ */ new Set(["threshold", "repeat", "timeout_seconds", "budget_usd"]);
|
|
2872
2972
|
var KNOWN_DEFAULT_TEST_FIELDS = /* @__PURE__ */ new Set([
|
|
2873
2973
|
"vars",
|
|
@@ -2907,6 +3007,10 @@ var KNOWN_TEST_EXECUTION_FIELDS = /* @__PURE__ */ new Set([
|
|
|
2907
3007
|
"workspace"
|
|
2908
3008
|
]);
|
|
2909
3009
|
var REMOVED_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Map([
|
|
3010
|
+
[
|
|
3011
|
+
"imports",
|
|
3012
|
+
"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."
|
|
3013
|
+
],
|
|
2910
3014
|
[
|
|
2911
3015
|
"expected_output",
|
|
2912
3016
|
"Top-level 'expected_output' has been removed from authored eval YAML. Put reference answers in default_test.vars.expected_output or tests[].vars.expected_output and consume them with an explicit assertion such as { type: 'llm-rubric', value: 'Matches the reference answer: {{ expected_output }}' }."
|
|
@@ -2966,6 +3070,7 @@ var KNOWN_TEST_FIELDS = /* @__PURE__ */ new Set([
|
|
|
2966
3070
|
"threshold",
|
|
2967
3071
|
"execution",
|
|
2968
3072
|
"run",
|
|
3073
|
+
"environment",
|
|
2969
3074
|
"workspace",
|
|
2970
3075
|
"metadata",
|
|
2971
3076
|
"conversation_id",
|
|
@@ -2979,6 +3084,17 @@ var KNOWN_TEST_FIELDS = /* @__PURE__ */ new Set([
|
|
|
2979
3084
|
"window_size"
|
|
2980
3085
|
]);
|
|
2981
3086
|
var SUPPORTED_WORKSPACE_REPO_FIELDS = /* @__PURE__ */ new Set(["path", "repo", "commit", "ancestor", "sparse"]);
|
|
3087
|
+
var KNOWN_REMOVED_WORKSPACE_FIELDS = /* @__PURE__ */ new Set([
|
|
3088
|
+
"template",
|
|
3089
|
+
"repos",
|
|
3090
|
+
"scope",
|
|
3091
|
+
"docker",
|
|
3092
|
+
"hooks",
|
|
3093
|
+
"env",
|
|
3094
|
+
"mode",
|
|
3095
|
+
"isolation",
|
|
3096
|
+
"path"
|
|
3097
|
+
]);
|
|
2982
3098
|
var REMOVED_TEST_FIELDS = /* @__PURE__ */ new Map([]);
|
|
2983
3099
|
REMOVED_TEST_FIELDS.set(
|
|
2984
3100
|
"input",
|
|
@@ -3108,13 +3224,15 @@ async function validateEvalFile(filePath) {
|
|
|
3108
3224
|
});
|
|
3109
3225
|
}
|
|
3110
3226
|
}
|
|
3227
|
+
await validateEnvironmentConfig(parsed.environment, absolutePath, errors, "environment");
|
|
3111
3228
|
await validateSuiteWorkspaceConfigs(parsed, absolutePath, errors);
|
|
3229
|
+
validateTargetTestbedFields(parsed.target, "target", absolutePath, errors);
|
|
3230
|
+
validateTargetsTestbedFields(parsed.targets, "targets", absolutePath, errors);
|
|
3112
3231
|
validateAuthoredWorkers(parsed, absolutePath, errors);
|
|
3113
3232
|
validateExecutionPolicy(parsed.execution, "execution", absolutePath, errors);
|
|
3114
3233
|
validateEvaluateOptions(parsed.evaluate_options, "evaluate_options", absolutePath, errors);
|
|
3115
3234
|
validateAssertArray(parsed.assert, "assert", absolutePath, errors, customAssertionTypes);
|
|
3116
3235
|
validateDefaultTest(parsed.default_test, absolutePath, errors, customAssertionTypes);
|
|
3117
|
-
await validateImportsField(parsed.imports, absolutePath, errors);
|
|
3118
3236
|
const cases = parsed.tests;
|
|
3119
3237
|
const hasImports = collectImportEntries(parsed).length > 0;
|
|
3120
3238
|
const hasScenarios = Array.isArray(parsed.scenarios);
|
|
@@ -3144,7 +3262,7 @@ async function validateEvalFile(filePath) {
|
|
|
3144
3262
|
severity: "error",
|
|
3145
3263
|
filePath: absolutePath,
|
|
3146
3264
|
location: "tests",
|
|
3147
|
-
message: "Missing or invalid 'tests' field (must be an array or a file path string, unless
|
|
3265
|
+
message: "Missing or invalid 'tests' field (must be an array or a file path string, unless scenarios are provided)"
|
|
3148
3266
|
});
|
|
3149
3267
|
return {
|
|
3150
3268
|
valid: errors.length === 0,
|
|
@@ -3264,6 +3382,12 @@ async function validateEvalFile(filePath) {
|
|
|
3264
3382
|
);
|
|
3265
3383
|
validateRunOverride(evalCase.run, `${location}.run`, absolutePath, errors);
|
|
3266
3384
|
validateTestOptions(evalCase.options, `${location}.options`, absolutePath, errors);
|
|
3385
|
+
await validateEnvironmentConfig(
|
|
3386
|
+
evalCase.environment,
|
|
3387
|
+
absolutePath,
|
|
3388
|
+
errors,
|
|
3389
|
+
`${location}.environment`
|
|
3390
|
+
);
|
|
3267
3391
|
validateConversationMode(evalCase, location, absolutePath, errors);
|
|
3268
3392
|
await validateWorkspaceConfig(
|
|
3269
3393
|
evalCase.workspace,
|
|
@@ -3292,6 +3416,43 @@ async function validateSuiteWorkspaceConfigs(parsed, absolutePath, errors) {
|
|
|
3292
3416
|
);
|
|
3293
3417
|
}
|
|
3294
3418
|
}
|
|
3419
|
+
async function validateEnvironmentConfig(environment, evalFilePath, errors, location) {
|
|
3420
|
+
if (environment === void 0) {
|
|
3421
|
+
return;
|
|
3422
|
+
}
|
|
3423
|
+
try {
|
|
3424
|
+
await resolveEnvironmentRecipe(environment, path22.dirname(evalFilePath), location);
|
|
3425
|
+
} catch (error) {
|
|
3426
|
+
errors.push({
|
|
3427
|
+
severity: "error",
|
|
3428
|
+
filePath: evalFilePath,
|
|
3429
|
+
location,
|
|
3430
|
+
message: error.message
|
|
3431
|
+
});
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
function validateTargetTestbedFields(target, location, filePath, errors) {
|
|
3435
|
+
if (!isObject(target)) {
|
|
3436
|
+
return;
|
|
3437
|
+
}
|
|
3438
|
+
for (const field of ["environment", "container", "install"]) {
|
|
3439
|
+
if (target[field] === void 0) {
|
|
3440
|
+
continue;
|
|
3441
|
+
}
|
|
3442
|
+
errors.push({
|
|
3443
|
+
severity: "error",
|
|
3444
|
+
filePath,
|
|
3445
|
+
location: `${location}.${field}`,
|
|
3446
|
+
message: field === "environment" ? "Target definitions cannot include environment; author environment at suite/test/case scope." : `Target definitions cannot include ${field}; use an environment recipe for testbed setup.`
|
|
3447
|
+
});
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
function validateTargetsTestbedFields(targets, location, filePath, errors) {
|
|
3451
|
+
const entries = Array.isArray(targets) ? targets : targets === void 0 ? [] : [targets];
|
|
3452
|
+
entries.forEach((entry, index) => {
|
|
3453
|
+
validateTargetTestbedFields(entry, `${location}[${index}]`, filePath, errors);
|
|
3454
|
+
});
|
|
3455
|
+
}
|
|
3295
3456
|
function validateTestExecutionFields(caseExecution, filePath, errors, location) {
|
|
3296
3457
|
for (const key of Object.keys(caseExecution)) {
|
|
3297
3458
|
if (key === "workers") {
|
|
@@ -3413,87 +3574,11 @@ function rejectRuntimeWorkspaceConfig(workspace, filePath, errors, location) {
|
|
|
3413
3574
|
severity: "error",
|
|
3414
3575
|
filePath,
|
|
3415
3576
|
location,
|
|
3416
|
-
message: `${location} has been removed from eval YAML. Put machine-local workspace_path in .agentv/config.local.yaml under execution, or pass --workspace-path. Keep portable
|
|
3577
|
+
message: `${location} has been removed from eval YAML. Put machine-local workspace_path in .agentv/config.local.yaml under execution, or pass --workspace-path. Keep portable coding-agent testbed setup in environment.`
|
|
3417
3578
|
});
|
|
3418
3579
|
}
|
|
3419
|
-
function importEntryPath(value) {
|
|
3420
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
3421
|
-
return value.trim();
|
|
3422
|
-
}
|
|
3423
|
-
if (!isObject(value)) {
|
|
3424
|
-
return void 0;
|
|
3425
|
-
}
|
|
3426
|
-
return typeof value.path === "string" && value.path.trim().length > 0 ? value.path.trim() : void 0;
|
|
3427
|
-
}
|
|
3428
|
-
async function validateImportsField(imports, filePath, errors) {
|
|
3429
|
-
if (imports === void 0) {
|
|
3430
|
-
return;
|
|
3431
|
-
}
|
|
3432
|
-
if (!isObject(imports)) {
|
|
3433
|
-
errors.push({
|
|
3434
|
-
severity: "error",
|
|
3435
|
-
filePath,
|
|
3436
|
-
location: "imports",
|
|
3437
|
-
message: "Invalid 'imports' field. Use imports.suites and/or imports.tests."
|
|
3438
|
-
});
|
|
3439
|
-
return;
|
|
3440
|
-
}
|
|
3441
|
-
for (const key of Object.keys(imports)) {
|
|
3442
|
-
if (key !== "suites" && key !== "tests") {
|
|
3443
|
-
errors.push({
|
|
3444
|
-
severity: "warning",
|
|
3445
|
-
filePath,
|
|
3446
|
-
location: `imports.${key}`,
|
|
3447
|
-
message: `Unknown imports field '${key}'. Use imports.suites or imports.tests.`
|
|
3448
|
-
});
|
|
3449
|
-
}
|
|
3450
|
-
}
|
|
3451
|
-
await validateImportGroup(imports.suites, "suite", "imports.suites", filePath, errors);
|
|
3452
|
-
await validateImportGroup(imports.tests, "tests", "imports.tests", filePath, errors);
|
|
3453
|
-
}
|
|
3454
|
-
async function validateImportGroup(group, type, location, filePath, errors) {
|
|
3455
|
-
if (group === void 0) {
|
|
3456
|
-
return;
|
|
3457
|
-
}
|
|
3458
|
-
const entries = Array.isArray(group) ? group : [group];
|
|
3459
|
-
for (let i = 0; i < entries.length; i++) {
|
|
3460
|
-
const entry = entries[i];
|
|
3461
|
-
const entryLocation = `${location}[${i}]`;
|
|
3462
|
-
const entryPath = importEntryPath(entry);
|
|
3463
|
-
if (!entryPath) {
|
|
3464
|
-
errors.push({
|
|
3465
|
-
severity: "error",
|
|
3466
|
-
filePath,
|
|
3467
|
-
location: entryLocation,
|
|
3468
|
-
message: "Invalid import entry. Use a path string or an object with a non-empty 'path'."
|
|
3469
|
-
});
|
|
3470
|
-
continue;
|
|
3471
|
-
}
|
|
3472
|
-
if (type === "tests" && !/\.eval\.ya?ml$/i.test(entryPath)) {
|
|
3473
|
-
await validateRawCaseImportPath(entryPath, filePath, `${entryLocation}.path`, errors);
|
|
3474
|
-
}
|
|
3475
|
-
if (isObject(entry)) {
|
|
3476
|
-
for (const key of Object.keys(entry)) {
|
|
3477
|
-
if (!KNOWN_IMPORT_FIELDS.has(key)) {
|
|
3478
|
-
errors.push({
|
|
3479
|
-
severity: "warning",
|
|
3480
|
-
filePath,
|
|
3481
|
-
location: `${entryLocation}.${key}`,
|
|
3482
|
-
message: `Unknown field '${key}'. This field will be ignored.`
|
|
3483
|
-
});
|
|
3484
|
-
}
|
|
3485
|
-
}
|
|
3486
|
-
validateIncludeSelect(entry.select, `${entryLocation}.select`, filePath, errors);
|
|
3487
|
-
validateRunOverride(entry.run, `${entryLocation}.run`, filePath, errors);
|
|
3488
|
-
}
|
|
3489
|
-
}
|
|
3490
|
-
}
|
|
3491
3580
|
function collectImportEntries(parsed) {
|
|
3492
3581
|
const entries = [];
|
|
3493
|
-
if (isObject(parsed.imports)) {
|
|
3494
|
-
entries.push(...collectImportGroup(parsed.imports.suites, "suite", "imports.suites"));
|
|
3495
|
-
entries.push(...collectImportGroup(parsed.imports.tests, "tests", "imports.tests"));
|
|
3496
|
-
}
|
|
3497
3582
|
const tests = parsed.tests;
|
|
3498
3583
|
if (Array.isArray(tests)) {
|
|
3499
3584
|
for (let i = 0; i < tests.length; i++) {
|
|
@@ -3516,42 +3601,24 @@ function collectImportEntries(parsed) {
|
|
|
3516
3601
|
}
|
|
3517
3602
|
return entries;
|
|
3518
3603
|
}
|
|
3519
|
-
function collectImportGroup(group, type, location) {
|
|
3520
|
-
if (group === void 0) {
|
|
3521
|
-
return [];
|
|
3522
|
-
}
|
|
3523
|
-
const entries = Array.isArray(group) ? group : [group];
|
|
3524
|
-
return entries.flatMap((entry, index) => {
|
|
3525
|
-
const pathValue = importEntryPath(entry);
|
|
3526
|
-
return pathValue ? [
|
|
3527
|
-
{
|
|
3528
|
-
path: pathValue,
|
|
3529
|
-
type,
|
|
3530
|
-
location: `${location}[${index}].path`,
|
|
3531
|
-
...isObject(entry) && entry.select !== void 0 ? { select: entry.select } : {},
|
|
3532
|
-
...isObject(entry) && entry.run !== void 0 ? { run: entry.run } : {}
|
|
3533
|
-
}
|
|
3534
|
-
] : [];
|
|
3535
|
-
});
|
|
3536
|
-
}
|
|
3537
3604
|
async function validateCompositionDiagnostics(filePath, parsed, errors) {
|
|
3538
|
-
const
|
|
3539
|
-
if (
|
|
3605
|
+
const includeEntries = collectImportEntries(parsed);
|
|
3606
|
+
if (includeEntries.length === 0) {
|
|
3540
3607
|
return;
|
|
3541
3608
|
}
|
|
3542
3609
|
const parentHasRuntime = hasWrapperRuntimeControls(parsed);
|
|
3543
|
-
const hasSuiteImport =
|
|
3610
|
+
const hasSuiteImport = includeEntries.some((entry) => entry.type === "suite");
|
|
3544
3611
|
if (hasSuiteImport) {
|
|
3545
3612
|
for (const location of parentWorkspaceLocations(parsed)) {
|
|
3546
3613
|
errors.push({
|
|
3547
3614
|
severity: "error",
|
|
3548
3615
|
filePath,
|
|
3549
3616
|
location,
|
|
3550
|
-
message: "Parent
|
|
3617
|
+
message: location === "environment" ? "Parent environment is not allowed with legacy tests[].include suite entries. Run eval files directly, or use tests: file://... for raw cases that should use the parent environment." : "Parent workspace is not allowed with legacy tests[].include suite entries. Run eval files directly, or use tests: file://... for raw cases that should use the parent workspace."
|
|
3551
3618
|
});
|
|
3552
3619
|
}
|
|
3553
3620
|
}
|
|
3554
|
-
for (const entry of
|
|
3621
|
+
for (const entry of includeEntries) {
|
|
3555
3622
|
const resolvedSuites = await resolveSuiteIncludePaths(entry.path, path22.dirname(filePath));
|
|
3556
3623
|
if (entry.type === "suite") {
|
|
3557
3624
|
for (const resolvedSuite of resolvedSuites) {
|
|
@@ -3567,7 +3634,7 @@ async function validateCompositionDiagnostics(filePath, parsed, errors) {
|
|
|
3567
3634
|
severity: "warning",
|
|
3568
3635
|
filePath,
|
|
3569
3636
|
location: entry.location,
|
|
3570
|
-
message: parentHasRuntime ? `Imported suite '${resolvedSuite.displayPath}' defines ${runtimeFields.join(", ")}, but child target and run controls are ignored
|
|
3637
|
+
message: parentHasRuntime ? `Imported suite '${resolvedSuite.displayPath}' defines ${runtimeFields.join(", ")}, but child target 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 target and run controls are ignored by legacy tests[].include suite imports. Prefer running eval files directly with CLI multi-file selection and tags.`
|
|
3571
3638
|
});
|
|
3572
3639
|
}
|
|
3573
3640
|
continue;
|
|
@@ -3581,7 +3648,7 @@ async function validateCompositionDiagnostics(filePath, parsed, errors) {
|
|
|
3581
3648
|
severity: "warning",
|
|
3582
3649
|
filePath,
|
|
3583
3650
|
location: entry.location,
|
|
3584
|
-
message: `
|
|
3651
|
+
message: `Legacy tests[].include with type: tests imports raw cases from eval suite '${resolvedSuite.displayPath}' and drops suite context, including child environment, workspace, input, assertions, metadata, target, and run controls. Prefer tests: file://... for raw case files.`
|
|
3585
3652
|
});
|
|
3586
3653
|
}
|
|
3587
3654
|
}
|
|
@@ -3620,6 +3687,9 @@ function parentWorkspaceLocations(parsed) {
|
|
|
3620
3687
|
if (parsed.workspace !== void 0) {
|
|
3621
3688
|
locations.push("workspace");
|
|
3622
3689
|
}
|
|
3690
|
+
if (parsed.environment !== void 0) {
|
|
3691
|
+
locations.push("environment");
|
|
3692
|
+
}
|
|
3623
3693
|
if (isObject(parsed.execution) && parsed.execution.workspace !== void 0) {
|
|
3624
3694
|
locations.push("execution.workspace");
|
|
3625
3695
|
}
|
|
@@ -3634,12 +3704,11 @@ async function readImportedSuite(filePath) {
|
|
|
3634
3704
|
}
|
|
3635
3705
|
}
|
|
3636
3706
|
function validateIncludeEntry(entry, location, filePath, errors) {
|
|
3637
|
-
const mode = entry.type === "suite" ? "suites" : entry.type === "tests" ? "tests" : void 0;
|
|
3638
3707
|
errors.push({
|
|
3639
3708
|
severity: "warning",
|
|
3640
3709
|
filePath,
|
|
3641
3710
|
location,
|
|
3642
|
-
message:
|
|
3711
|
+
message: entry.type === "suite" ? "tests[].include with type: suite is deprecated. Run eval files directly with CLI multi-file selection and tags instead." : "tests[].include is deprecated. Use tests: file://... or string entries inside tests: for raw case files."
|
|
3643
3712
|
});
|
|
3644
3713
|
for (const key of Object.keys(entry)) {
|
|
3645
3714
|
if (!KNOWN_INCLUDE_FIELDS.has(key)) {
|
|
@@ -4041,35 +4110,18 @@ async function validateWorkspaceConfig(workspace, evalFilePath, errors, location
|
|
|
4041
4110
|
if (workspace === void 0) {
|
|
4042
4111
|
return;
|
|
4043
4112
|
}
|
|
4044
|
-
if (
|
|
4045
|
-
validateWorkspaceRepoConfig(workspace, evalFilePath, errors, location);
|
|
4046
|
-
return;
|
|
4047
|
-
}
|
|
4048
|
-
if (typeof workspace !== "string") {
|
|
4049
|
-
return;
|
|
4050
|
-
}
|
|
4051
|
-
const workspacePath = path22.resolve(path22.dirname(evalFilePath), workspace);
|
|
4052
|
-
try {
|
|
4053
|
-
const workspaceContent = await readFile22(workspacePath, "utf8");
|
|
4054
|
-
const parsedWorkspace = interpolateEnv(parseYamlValue(workspaceContent), process.env);
|
|
4055
|
-
if (!isObject(parsedWorkspace)) {
|
|
4056
|
-
errors.push({
|
|
4057
|
-
severity: "error",
|
|
4058
|
-
filePath: evalFilePath,
|
|
4059
|
-
location,
|
|
4060
|
-
message: `External workspace file must contain a YAML object: ${workspace}`
|
|
4061
|
-
});
|
|
4062
|
-
return;
|
|
4063
|
-
}
|
|
4064
|
-
validateWorkspaceRepoConfig(parsedWorkspace, workspacePath, errors, location);
|
|
4065
|
-
} catch (error) {
|
|
4066
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
4113
|
+
if (typeof workspace === "string") {
|
|
4067
4114
|
errors.push({
|
|
4068
4115
|
severity: "error",
|
|
4069
4116
|
filePath: evalFilePath,
|
|
4070
4117
|
location,
|
|
4071
|
-
message:
|
|
4118
|
+
message: `${location} has been removed from public eval YAML. Use environment: file://... for reusable coding-agent testbed recipes.`
|
|
4072
4119
|
});
|
|
4120
|
+
return;
|
|
4121
|
+
}
|
|
4122
|
+
if (isObject(workspace)) {
|
|
4123
|
+
validateWorkspaceRepoConfig(workspace, evalFilePath, errors, location);
|
|
4124
|
+
return;
|
|
4073
4125
|
}
|
|
4074
4126
|
}
|
|
4075
4127
|
function validateWorkspaceRepoConfig(workspace, filePath, errors, location) {
|
|
@@ -4078,12 +4130,79 @@ function validateWorkspaceRepoConfig(workspace, filePath, errors, location) {
|
|
|
4078
4130
|
const afterEachHook = isObject(hooks) ? hooks.after_each : void 0;
|
|
4079
4131
|
const scope = workspace.scope;
|
|
4080
4132
|
const docker = workspace.docker;
|
|
4133
|
+
let hasRemovedTestbedField = false;
|
|
4134
|
+
if (Object.keys(workspace).length === 0) {
|
|
4135
|
+
errors.push({
|
|
4136
|
+
severity: "error",
|
|
4137
|
+
filePath,
|
|
4138
|
+
location,
|
|
4139
|
+
message: "workspace has been removed from public eval YAML. Use environment for coding-agent testbed setup."
|
|
4140
|
+
});
|
|
4141
|
+
return;
|
|
4142
|
+
}
|
|
4143
|
+
if ("template" in workspace) {
|
|
4144
|
+
hasRemovedTestbedField = true;
|
|
4145
|
+
errors.push({
|
|
4146
|
+
severity: "error",
|
|
4147
|
+
filePath,
|
|
4148
|
+
location: `${location}.template`,
|
|
4149
|
+
message: "workspace.template has been removed from public eval YAML. Use environment.workdir and environment.setup for authored testbed setup."
|
|
4150
|
+
});
|
|
4151
|
+
}
|
|
4152
|
+
if ("repos" in workspace) {
|
|
4153
|
+
hasRemovedTestbedField = true;
|
|
4154
|
+
errors.push({
|
|
4155
|
+
severity: "error",
|
|
4156
|
+
filePath,
|
|
4157
|
+
location: `${location}.repos`,
|
|
4158
|
+
message: "workspace.repos has been removed from public eval YAML. Use environment.setup.command argv to materialize repositories."
|
|
4159
|
+
});
|
|
4160
|
+
}
|
|
4161
|
+
if ("scope" in workspace) {
|
|
4162
|
+
hasRemovedTestbedField = true;
|
|
4163
|
+
errors.push({
|
|
4164
|
+
severity: "error",
|
|
4165
|
+
filePath,
|
|
4166
|
+
location: `${location}.scope`,
|
|
4167
|
+
message: "workspace.scope has been removed from public eval YAML. Use environment at suite/test scope and let runtime manage workspace lifetime."
|
|
4168
|
+
});
|
|
4169
|
+
}
|
|
4170
|
+
if ("docker" in workspace) {
|
|
4171
|
+
hasRemovedTestbedField = true;
|
|
4172
|
+
errors.push({
|
|
4173
|
+
severity: "error",
|
|
4174
|
+
filePath,
|
|
4175
|
+
location: `${location}.docker`,
|
|
4176
|
+
message: "workspace.docker has been removed from public eval YAML. Use environment.type: docker with image or context."
|
|
4177
|
+
});
|
|
4178
|
+
}
|
|
4179
|
+
if ("hooks" in workspace) {
|
|
4180
|
+
hasRemovedTestbedField = true;
|
|
4181
|
+
errors.push({
|
|
4182
|
+
severity: "error",
|
|
4183
|
+
filePath,
|
|
4184
|
+
location: `${location}.hooks`,
|
|
4185
|
+
message: "workspace.hooks has been removed from public eval YAML. Use environment.setup for testbed setup and extensions for lifecycle instrumentation."
|
|
4186
|
+
});
|
|
4187
|
+
}
|
|
4188
|
+
if ("env" in workspace) {
|
|
4189
|
+
hasRemovedTestbedField = true;
|
|
4190
|
+
errors.push({
|
|
4191
|
+
severity: "error",
|
|
4192
|
+
filePath,
|
|
4193
|
+
location: `${location}.env`,
|
|
4194
|
+
message: "workspace.env has been removed from public eval YAML. Use top-level env for provider/eval variables or environment.env for environment-scoped variables."
|
|
4195
|
+
});
|
|
4196
|
+
}
|
|
4197
|
+
if (hasRemovedTestbedField) {
|
|
4198
|
+
return;
|
|
4199
|
+
}
|
|
4081
4200
|
if ("mode" in workspace) {
|
|
4082
4201
|
errors.push({
|
|
4083
4202
|
severity: "error",
|
|
4084
4203
|
filePath,
|
|
4085
4204
|
location: `${location}.mode`,
|
|
4086
|
-
message: "workspace.mode has been removed from eval YAML. Use workspace.
|
|
4205
|
+
message: "workspace.mode has been removed from eval YAML. Use --workspace-path or execution.workspace_path for machine-local existing directories, and environment for portable testbed setup."
|
|
4087
4206
|
});
|
|
4088
4207
|
}
|
|
4089
4208
|
if ("isolation" in workspace) {
|
|
@@ -4091,7 +4210,7 @@ function validateWorkspaceRepoConfig(workspace, filePath, errors, location) {
|
|
|
4091
4210
|
severity: "error",
|
|
4092
4211
|
filePath,
|
|
4093
4212
|
location: `${location}.isolation`,
|
|
4094
|
-
message: "workspace.isolation has been removed. Use
|
|
4213
|
+
message: "workspace.isolation has been removed from eval YAML. Use environment at suite/test scope and let AgentV manage runtime isolation."
|
|
4095
4214
|
});
|
|
4096
4215
|
}
|
|
4097
4216
|
if ("path" in workspace) {
|
|
@@ -4099,7 +4218,18 @@ function validateWorkspaceRepoConfig(workspace, filePath, errors, location) {
|
|
|
4099
4218
|
severity: "error",
|
|
4100
4219
|
filePath,
|
|
4101
4220
|
location: `${location}.path`,
|
|
4102
|
-
message: "workspace.path has been removed from eval YAML.
|
|
4221
|
+
message: "workspace.path has been removed from eval YAML. Use environment.workdir for portable testbed cwd; put existing machine-local workspace paths in .agentv/config.local.yaml execution.workspace_path or pass --workspace-path."
|
|
4222
|
+
});
|
|
4223
|
+
}
|
|
4224
|
+
for (const key of Object.keys(workspace)) {
|
|
4225
|
+
if (KNOWN_REMOVED_WORKSPACE_FIELDS.has(key)) {
|
|
4226
|
+
continue;
|
|
4227
|
+
}
|
|
4228
|
+
errors.push({
|
|
4229
|
+
severity: "error",
|
|
4230
|
+
filePath,
|
|
4231
|
+
location: `${location}.${key}`,
|
|
4232
|
+
message: `${location}.${key} has been removed from public eval YAML. Use environment for portable coding-agent testbed setup.`
|
|
4103
4233
|
});
|
|
4104
4234
|
}
|
|
4105
4235
|
if (scope !== void 0 && scope !== "suite" && scope !== "attempt") {
|
|
@@ -4412,11 +4542,11 @@ async function validateSuiteImportCycles(filePath, parsed, errors) {
|
|
|
4412
4542
|
await validateSuiteImportCyclesFromParsed(filePath, parsed, [root], errors);
|
|
4413
4543
|
}
|
|
4414
4544
|
async function validateSuiteImportCyclesFromParsed(currentFilePath, parsed, stack, errors) {
|
|
4415
|
-
const
|
|
4416
|
-
if (
|
|
4545
|
+
const includeEntries = collectImportEntries(parsed);
|
|
4546
|
+
if (includeEntries.length === 0) {
|
|
4417
4547
|
return;
|
|
4418
4548
|
}
|
|
4419
|
-
for (const entry of
|
|
4549
|
+
for (const entry of includeEntries) {
|
|
4420
4550
|
if (entry.type !== "suite") {
|
|
4421
4551
|
continue;
|
|
4422
4552
|
}
|
|
@@ -4529,6 +4659,16 @@ function validateAssertArray(assertField, location, filePath, errors, customAsse
|
|
|
4529
4659
|
continue;
|
|
4530
4660
|
}
|
|
4531
4661
|
const typeValue = rawTypeValue.replace(/_/g, "-");
|
|
4662
|
+
const staleMessage = staleAuthoredAssertionMessage(item);
|
|
4663
|
+
if (staleMessage) {
|
|
4664
|
+
errors.push({
|
|
4665
|
+
severity: "error",
|
|
4666
|
+
filePath,
|
|
4667
|
+
location: `${itemLocation}.type`,
|
|
4668
|
+
message: staleMessage
|
|
4669
|
+
});
|
|
4670
|
+
continue;
|
|
4671
|
+
}
|
|
4532
4672
|
const replacement = REMOVED_ASSERTION_TYPE_REPLACEMENTS.get(typeValue);
|
|
4533
4673
|
if (replacement) {
|
|
4534
4674
|
errors.push({
|
|
@@ -4549,7 +4689,7 @@ function validateAssertArray(assertField, location, filePath, errors, customAsse
|
|
|
4549
4689
|
});
|
|
4550
4690
|
continue;
|
|
4551
4691
|
}
|
|
4552
|
-
if (!isGraderKind(typeValue) && !PROMPTFOO_ASSERTION_TYPES.has(typeValue) && !customAssertionTypes.has(typeValue)) {
|
|
4692
|
+
if (!isGraderKind(typeValue) && !isGraderKind(baseTypeValue) && !PROMPTFOO_ASSERTION_TYPES.has(typeValue) && !customAssertionTypes.has(typeValue)) {
|
|
4553
4693
|
errors.push({
|
|
4554
4694
|
severity: "warning",
|
|
4555
4695
|
filePath,
|
|
@@ -5092,7 +5232,7 @@ function validateUnknownSettings(target, provider, absolutePath, location, error
|
|
|
5092
5232
|
severity: "warning",
|
|
5093
5233
|
filePath: absolutePath,
|
|
5094
5234
|
location: `${location}.${key}`,
|
|
5095
|
-
message: "workspace_template has been removed from targets. Use eval-level
|
|
5235
|
+
message: "workspace_template has been removed from targets. Use eval-level environment.workdir and environment.setup instead."
|
|
5096
5236
|
});
|
|
5097
5237
|
continue;
|
|
5098
5238
|
}
|
|
@@ -7445,7 +7585,7 @@ async function runEvalCommand(input) {
|
|
|
7445
7585
|
const resolvedExperiment = resolveExperimentForRun(options.experiment);
|
|
7446
7586
|
const evalPathInputs = input.testFiles.length > 0 ? [...input.testFiles] : [];
|
|
7447
7587
|
if (evalPathInputs.length === 0 && process.stdin.isTTY) {
|
|
7448
|
-
const { launchInteractiveWizard } = await import("./interactive-
|
|
7588
|
+
const { launchInteractiveWizard } = await import("./interactive-RUY3OCBI.js");
|
|
7449
7589
|
await launchInteractiveWizard();
|
|
7450
7590
|
return void 0;
|
|
7451
7591
|
}
|
|
@@ -7785,7 +7925,7 @@ async function runEvalCommand(input) {
|
|
|
7785
7925
|
});
|
|
7786
7926
|
let transcriptProviderFactory;
|
|
7787
7927
|
if (options.transcript) {
|
|
7788
|
-
const { TranscriptProvider } = await import("./dist-
|
|
7928
|
+
const { TranscriptProvider } = await import("./dist-6Z7U473R.js");
|
|
7789
7929
|
const transcriptProvider = await TranscriptProvider.fromFile(options.transcript);
|
|
7790
7930
|
const totalTests = [...fileMetadata.values()].reduce(
|
|
7791
7931
|
(sum, meta) => sum + meta.testCases.length,
|
|
@@ -8051,7 +8191,7 @@ ${formatRequiredVersionFailureNote(requiredVersionCheck)}`);
|
|
|
8051
8191
|
const sourceTests = activeSourceTests;
|
|
8052
8192
|
const taskBundleTargets = buildTaskBundleTargetSelections(activeTestFiles, fileMetadata);
|
|
8053
8193
|
if (isResumeAppend) {
|
|
8054
|
-
const { writePerTestArtifacts } = await import("./artifact-writer-
|
|
8194
|
+
const { writePerTestArtifacts } = await import("./artifact-writer-JFNIPMKW.js");
|
|
8055
8195
|
await writePerTestArtifacts(allResults, runDir, {
|
|
8056
8196
|
experiment: normalizeExperimentName(options.experiment),
|
|
8057
8197
|
runId: path12.basename(runDir),
|
|
@@ -8269,4 +8409,4 @@ export {
|
|
|
8269
8409
|
filterByCategory,
|
|
8270
8410
|
runEvalCommand
|
|
8271
8411
|
};
|
|
8272
|
-
//# sourceMappingURL=chunk-
|
|
8412
|
+
//# sourceMappingURL=chunk-FVR4RQFK.js.map
|