@agentv/core 3.7.0 → 3.9.0
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/dist/{chunk-2IZOTQ25.js → chunk-PC5TLJF6.js} +143 -4
- package/dist/chunk-PC5TLJF6.js.map +1 -0
- package/dist/evaluation/validation/index.cjs +228 -72
- package/dist/evaluation/validation/index.cjs.map +1 -1
- package/dist/evaluation/validation/index.js +85 -37
- package/dist/evaluation/validation/index.js.map +1 -1
- package/dist/index.cjs +519 -778
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -23
- package/dist/index.d.ts +11 -23
- package/dist/index.js +450 -841
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-2IZOTQ25.js.map +0 -1
|
@@ -103,13 +103,56 @@ function getExpectedSchema(fileType) {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
// src/evaluation/validation/eval-validator.ts
|
|
106
|
+
var import_promises3 = require("fs/promises");
|
|
107
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
108
|
+
var import_yaml3 = require("yaml");
|
|
109
|
+
|
|
110
|
+
// src/evaluation/interpolation.ts
|
|
111
|
+
var ENV_VAR_PATTERN = /\$\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
|
|
112
|
+
function interpolateEnv(value, env) {
|
|
113
|
+
if (typeof value === "string") {
|
|
114
|
+
return value.replace(ENV_VAR_PATTERN, (_, varName) => env[varName] ?? "");
|
|
115
|
+
}
|
|
116
|
+
if (Array.isArray(value)) {
|
|
117
|
+
return value.map((item) => interpolateEnv(item, env));
|
|
118
|
+
}
|
|
119
|
+
if (value !== null && typeof value === "object") {
|
|
120
|
+
const result = {};
|
|
121
|
+
for (const [key, val] of Object.entries(value)) {
|
|
122
|
+
result[key] = interpolateEnv(val, env);
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/evaluation/loaders/case-file-loader.ts
|
|
106
130
|
var import_promises2 = require("fs/promises");
|
|
107
131
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
132
|
+
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
108
133
|
var import_yaml2 = require("yaml");
|
|
109
134
|
|
|
110
135
|
// src/evaluation/types.ts
|
|
111
136
|
var TEST_MESSAGE_ROLE_VALUES = ["system", "user", "assistant", "tool"];
|
|
112
137
|
var TEST_MESSAGE_ROLE_SET = new Set(TEST_MESSAGE_ROLE_VALUES);
|
|
138
|
+
function isJsonObject(value) {
|
|
139
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
return Object.values(value).every(isJsonValue);
|
|
143
|
+
}
|
|
144
|
+
function isJsonValue(value) {
|
|
145
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
if (Array.isArray(value)) {
|
|
149
|
+
return value.every(isJsonValue);
|
|
150
|
+
}
|
|
151
|
+
if (typeof value === "object") {
|
|
152
|
+
return isJsonObject(value);
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
113
156
|
var EVALUATOR_KIND_VALUES = [
|
|
114
157
|
"code-grader",
|
|
115
158
|
"llm-grader",
|
|
@@ -143,6 +186,74 @@ function isEvaluatorKind(value) {
|
|
|
143
186
|
return typeof value === "string" && EVALUATOR_KIND_SET.has(value);
|
|
144
187
|
}
|
|
145
188
|
|
|
189
|
+
// src/evaluation/loaders/case-file-loader.ts
|
|
190
|
+
var ANSI_YELLOW = "\x1B[33m";
|
|
191
|
+
var ANSI_RESET = "\x1B[0m";
|
|
192
|
+
function parseYamlCases(content, filePath) {
|
|
193
|
+
const raw = (0, import_yaml2.parse)(content);
|
|
194
|
+
const parsed = interpolateEnv(raw, process.env);
|
|
195
|
+
if (!Array.isArray(parsed)) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`External test file must contain a YAML array, got ${typeof parsed}: ${filePath}`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
const results = [];
|
|
201
|
+
for (const item of parsed) {
|
|
202
|
+
if (!isJsonObject(item)) {
|
|
203
|
+
throw new Error(`External test file contains non-object entry: ${filePath}`);
|
|
204
|
+
}
|
|
205
|
+
results.push(item);
|
|
206
|
+
}
|
|
207
|
+
return results;
|
|
208
|
+
}
|
|
209
|
+
function parseJsonlCases(content, filePath) {
|
|
210
|
+
const lines = content.split("\n");
|
|
211
|
+
const results = [];
|
|
212
|
+
for (let i = 0; i < lines.length; i++) {
|
|
213
|
+
const line = lines[i].trim();
|
|
214
|
+
if (line === "") continue;
|
|
215
|
+
try {
|
|
216
|
+
const raw = JSON.parse(line);
|
|
217
|
+
const parsed = interpolateEnv(raw, process.env);
|
|
218
|
+
if (!isJsonObject(parsed)) {
|
|
219
|
+
throw new Error("Expected JSON object");
|
|
220
|
+
}
|
|
221
|
+
results.push(parsed);
|
|
222
|
+
} catch (error) {
|
|
223
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
224
|
+
throw new Error(`Malformed JSONL at line ${i + 1}: ${message}
|
|
225
|
+
File: ${filePath}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return results;
|
|
229
|
+
}
|
|
230
|
+
async function loadCasesFromFile(filePath) {
|
|
231
|
+
const ext = import_node_path2.default.extname(filePath).toLowerCase();
|
|
232
|
+
let content;
|
|
233
|
+
try {
|
|
234
|
+
content = await (0, import_promises2.readFile)(filePath, "utf8");
|
|
235
|
+
} catch (error) {
|
|
236
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
237
|
+
throw new Error(`Cannot read external test file: ${filePath}
|
|
238
|
+
${message}`);
|
|
239
|
+
}
|
|
240
|
+
if (content.trim() === "") {
|
|
241
|
+
console.warn(
|
|
242
|
+
`${ANSI_YELLOW}Warning: External test file is empty, skipping: ${filePath}${ANSI_RESET}`
|
|
243
|
+
);
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
if (ext === ".yaml" || ext === ".yml") {
|
|
247
|
+
return parseYamlCases(content, filePath);
|
|
248
|
+
}
|
|
249
|
+
if (ext === ".jsonl") {
|
|
250
|
+
return parseJsonlCases(content, filePath);
|
|
251
|
+
}
|
|
252
|
+
throw new Error(
|
|
253
|
+
`Unsupported external test file format '${ext}': ${filePath}. Supported: .yaml, .yml, .jsonl`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
146
257
|
// src/evaluation/validation/eval-validator.ts
|
|
147
258
|
var ASSERTION_TYPES_WITH_STRING_VALUE = /* @__PURE__ */ new Set([
|
|
148
259
|
"contains",
|
|
@@ -165,11 +276,11 @@ function isObject(value) {
|
|
|
165
276
|
}
|
|
166
277
|
async function validateEvalFile(filePath) {
|
|
167
278
|
const errors = [];
|
|
168
|
-
const absolutePath =
|
|
279
|
+
const absolutePath = import_node_path3.default.resolve(filePath);
|
|
169
280
|
let parsed;
|
|
170
281
|
try {
|
|
171
|
-
const content = await (0,
|
|
172
|
-
parsed = (0,
|
|
282
|
+
const content = await (0, import_promises3.readFile)(absolutePath, "utf8");
|
|
283
|
+
parsed = interpolateEnv((0, import_yaml3.parse)(content), process.env);
|
|
173
284
|
} catch (error) {
|
|
174
285
|
errors.push({
|
|
175
286
|
severity: "error",
|
|
@@ -232,6 +343,31 @@ async function validateEvalFile(filePath) {
|
|
|
232
343
|
}
|
|
233
344
|
if (typeof cases === "string") {
|
|
234
345
|
validateTestsStringPath(cases, absolutePath, errors);
|
|
346
|
+
await validateWorkspaceConfig(parsed.workspace, absolutePath, errors, "workspace");
|
|
347
|
+
const ext = import_node_path3.default.extname(cases).toLowerCase();
|
|
348
|
+
if (VALID_TEST_FILE_EXTENSIONS.has(ext)) {
|
|
349
|
+
const externalCasesPath = import_node_path3.default.resolve(import_node_path3.default.dirname(absolutePath), cases);
|
|
350
|
+
try {
|
|
351
|
+
const externalCases = await loadCasesFromFile(externalCasesPath);
|
|
352
|
+
for (let i = 0; i < externalCases.length; i++) {
|
|
353
|
+
const externalCase = externalCases[i];
|
|
354
|
+
await validateWorkspaceConfig(
|
|
355
|
+
externalCase.workspace,
|
|
356
|
+
absolutePath,
|
|
357
|
+
errors,
|
|
358
|
+
`tests[${i}].workspace`
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
} catch (error) {
|
|
362
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
363
|
+
errors.push({
|
|
364
|
+
severity: "error",
|
|
365
|
+
filePath: absolutePath,
|
|
366
|
+
location: "tests",
|
|
367
|
+
message
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
235
371
|
return {
|
|
236
372
|
valid: errors.filter((e) => e.severity === "error").length === 0,
|
|
237
373
|
filePath: absolutePath,
|
|
@@ -339,10 +475,14 @@ async function validateEvalFile(filePath) {
|
|
|
339
475
|
if (assertField !== void 0) {
|
|
340
476
|
validateAssertArray(assertField, location, absolutePath, errors);
|
|
341
477
|
}
|
|
478
|
+
await validateWorkspaceConfig(
|
|
479
|
+
evalCase.workspace,
|
|
480
|
+
absolutePath,
|
|
481
|
+
errors,
|
|
482
|
+
`${location}.workspace`
|
|
483
|
+
);
|
|
342
484
|
}
|
|
343
|
-
|
|
344
|
-
validateWorkspaceRepoConfig(parsed.workspace, absolutePath, errors);
|
|
345
|
-
}
|
|
485
|
+
await validateWorkspaceConfig(parsed.workspace, absolutePath, errors, "workspace");
|
|
346
486
|
return {
|
|
347
487
|
valid: errors.filter((e) => e.severity === "error").length === 0,
|
|
348
488
|
filePath: absolutePath,
|
|
@@ -350,6 +490,41 @@ async function validateEvalFile(filePath) {
|
|
|
350
490
|
errors
|
|
351
491
|
};
|
|
352
492
|
}
|
|
493
|
+
async function validateWorkspaceConfig(workspace, evalFilePath, errors, location) {
|
|
494
|
+
if (workspace === void 0) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
if (isObject(workspace)) {
|
|
498
|
+
validateWorkspaceRepoConfig(workspace, evalFilePath, errors);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
if (typeof workspace !== "string") {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const workspacePath = import_node_path3.default.resolve(import_node_path3.default.dirname(evalFilePath), workspace);
|
|
505
|
+
try {
|
|
506
|
+
const workspaceContent = await (0, import_promises3.readFile)(workspacePath, "utf8");
|
|
507
|
+
const parsedWorkspace = interpolateEnv((0, import_yaml3.parse)(workspaceContent), process.env);
|
|
508
|
+
if (!isObject(parsedWorkspace)) {
|
|
509
|
+
errors.push({
|
|
510
|
+
severity: "error",
|
|
511
|
+
filePath: evalFilePath,
|
|
512
|
+
location,
|
|
513
|
+
message: `External workspace file must contain a YAML object: ${workspace}`
|
|
514
|
+
});
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
validateWorkspaceRepoConfig(parsedWorkspace, workspacePath, errors);
|
|
518
|
+
} catch (error) {
|
|
519
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
520
|
+
errors.push({
|
|
521
|
+
severity: "error",
|
|
522
|
+
filePath: evalFilePath,
|
|
523
|
+
location,
|
|
524
|
+
message: `Failed to load external workspace file '${workspace}': ${message}`
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
353
528
|
function validateWorkspaceRepoConfig(workspace, filePath, errors) {
|
|
354
529
|
const repos = workspace.repos;
|
|
355
530
|
const hooks = workspace.hooks;
|
|
@@ -358,8 +533,21 @@ function validateWorkspaceRepoConfig(workspace, filePath, errors) {
|
|
|
358
533
|
if (Array.isArray(repos)) {
|
|
359
534
|
for (const repo of repos) {
|
|
360
535
|
if (!isObject(repo)) continue;
|
|
536
|
+
const source = repo.source;
|
|
361
537
|
const checkout = repo.checkout;
|
|
362
538
|
const clone = repo.clone;
|
|
539
|
+
if (isObject(source) && isObject(checkout)) {
|
|
540
|
+
const sourceType = source.type;
|
|
541
|
+
const resolve = checkout.resolve;
|
|
542
|
+
if (sourceType === "local" && typeof resolve === "string") {
|
|
543
|
+
errors.push({
|
|
544
|
+
severity: "warning",
|
|
545
|
+
filePath,
|
|
546
|
+
location: `workspace.repos[path=${repo.path}]`,
|
|
547
|
+
message: "checkout.resolve has no effect for a local source. Use source.type to choose where the repo comes from; keep checkout.ref or checkout.ancestor only when pinning a local source."
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
363
551
|
if (isObject(checkout) && isObject(clone)) {
|
|
364
552
|
const ancestor = checkout.ancestor;
|
|
365
553
|
const depth = clone.depth;
|
|
@@ -491,7 +679,7 @@ function validateMetadata(parsed, filePath, errors) {
|
|
|
491
679
|
}
|
|
492
680
|
}
|
|
493
681
|
function validateTestsStringPath(testsPath, filePath, errors) {
|
|
494
|
-
const ext =
|
|
682
|
+
const ext = import_node_path3.default.extname(testsPath);
|
|
495
683
|
if (!VALID_TEST_FILE_EXTENSIONS.has(ext)) {
|
|
496
684
|
errors.push({
|
|
497
685
|
severity: "warning",
|
|
@@ -637,12 +825,12 @@ function validateContentForRoleMarkers(content, location, filePath, errors) {
|
|
|
637
825
|
}
|
|
638
826
|
|
|
639
827
|
// src/evaluation/validation/targets-validator.ts
|
|
640
|
-
var
|
|
641
|
-
var
|
|
642
|
-
var
|
|
828
|
+
var import_promises4 = require("fs/promises");
|
|
829
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
830
|
+
var import_yaml4 = require("yaml");
|
|
643
831
|
|
|
644
832
|
// src/evaluation/providers/targets.ts
|
|
645
|
-
var
|
|
833
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
646
834
|
var import_zod = require("zod");
|
|
647
835
|
var CliHealthcheckHttpInputSchema = import_zod.z.object({
|
|
648
836
|
url: import_zod.z.string().min(1, "healthcheck URL is required"),
|
|
@@ -722,7 +910,6 @@ var CliTargetConfigSchema = import_zod.z.object({
|
|
|
722
910
|
var CLI_PLACEHOLDERS = /* @__PURE__ */ new Set([
|
|
723
911
|
"PROMPT",
|
|
724
912
|
"PROMPT_FILE",
|
|
725
|
-
"GUIDELINES",
|
|
726
913
|
"EVAL_ID",
|
|
727
914
|
"ATTEMPT",
|
|
728
915
|
"FILES",
|
|
@@ -1058,11 +1245,11 @@ function validateUnknownSettings(target, provider, absolutePath, location, error
|
|
|
1058
1245
|
}
|
|
1059
1246
|
async function validateTargetsFile(filePath) {
|
|
1060
1247
|
const errors = [];
|
|
1061
|
-
const absolutePath =
|
|
1248
|
+
const absolutePath = import_node_path5.default.resolve(filePath);
|
|
1062
1249
|
let parsed;
|
|
1063
1250
|
try {
|
|
1064
|
-
const content = await (0,
|
|
1065
|
-
parsed = (0,
|
|
1251
|
+
const content = await (0, import_promises4.readFile)(absolutePath, "utf8");
|
|
1252
|
+
parsed = (0, import_yaml4.parse)(content);
|
|
1066
1253
|
} catch (error) {
|
|
1067
1254
|
errors.push({
|
|
1068
1255
|
severity: "error",
|
|
@@ -1261,13 +1448,13 @@ async function validateTargetsFile(filePath) {
|
|
|
1261
1448
|
}
|
|
1262
1449
|
|
|
1263
1450
|
// src/evaluation/validation/config-validator.ts
|
|
1264
|
-
var
|
|
1265
|
-
var
|
|
1451
|
+
var import_promises5 = require("fs/promises");
|
|
1452
|
+
var import_yaml5 = require("yaml");
|
|
1266
1453
|
async function validateConfigFile(filePath) {
|
|
1267
1454
|
const errors = [];
|
|
1268
1455
|
try {
|
|
1269
|
-
const content = await (0,
|
|
1270
|
-
const parsed = (0,
|
|
1456
|
+
const content = await (0, import_promises5.readFile)(filePath, "utf8");
|
|
1457
|
+
const parsed = (0, import_yaml5.parse)(content);
|
|
1271
1458
|
if (typeof parsed !== "object" || parsed === null) {
|
|
1272
1459
|
errors.push({
|
|
1273
1460
|
severity: "error",
|
|
@@ -1277,31 +1464,6 @@ async function validateConfigFile(filePath) {
|
|
|
1277
1464
|
return { valid: false, filePath, fileType: "config", errors };
|
|
1278
1465
|
}
|
|
1279
1466
|
const config = parsed;
|
|
1280
|
-
const guidelinePatterns = config.guideline_patterns;
|
|
1281
|
-
if (guidelinePatterns !== void 0) {
|
|
1282
|
-
if (!Array.isArray(guidelinePatterns)) {
|
|
1283
|
-
errors.push({
|
|
1284
|
-
severity: "error",
|
|
1285
|
-
filePath,
|
|
1286
|
-
location: "guideline_patterns",
|
|
1287
|
-
message: "Field 'guideline_patterns' must be an array"
|
|
1288
|
-
});
|
|
1289
|
-
} else if (!guidelinePatterns.every((p) => typeof p === "string")) {
|
|
1290
|
-
errors.push({
|
|
1291
|
-
severity: "error",
|
|
1292
|
-
filePath,
|
|
1293
|
-
location: "guideline_patterns",
|
|
1294
|
-
message: "All entries in 'guideline_patterns' must be strings"
|
|
1295
|
-
});
|
|
1296
|
-
} else if (guidelinePatterns.length === 0) {
|
|
1297
|
-
errors.push({
|
|
1298
|
-
severity: "warning",
|
|
1299
|
-
filePath,
|
|
1300
|
-
location: "guideline_patterns",
|
|
1301
|
-
message: "Field 'guideline_patterns' is empty. Consider removing it or adding patterns."
|
|
1302
|
-
});
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
1467
|
const evalPatterns = config.eval_patterns;
|
|
1306
1468
|
if (evalPatterns !== void 0) {
|
|
1307
1469
|
if (!Array.isArray(evalPatterns)) {
|
|
@@ -1338,13 +1500,7 @@ async function validateConfigFile(filePath) {
|
|
|
1338
1500
|
});
|
|
1339
1501
|
}
|
|
1340
1502
|
}
|
|
1341
|
-
const allowedFields = /* @__PURE__ */ new Set([
|
|
1342
|
-
"$schema",
|
|
1343
|
-
"guideline_patterns",
|
|
1344
|
-
"eval_patterns",
|
|
1345
|
-
"required_version",
|
|
1346
|
-
"execution"
|
|
1347
|
-
]);
|
|
1503
|
+
const allowedFields = /* @__PURE__ */ new Set(["$schema", "eval_patterns", "required_version", "execution"]);
|
|
1348
1504
|
const unexpectedFields = Object.keys(config).filter((key) => !allowedFields.has(key));
|
|
1349
1505
|
if (unexpectedFields.length > 0) {
|
|
1350
1506
|
errors.push({
|
|
@@ -1370,31 +1526,31 @@ async function validateConfigFile(filePath) {
|
|
|
1370
1526
|
}
|
|
1371
1527
|
|
|
1372
1528
|
// src/evaluation/validation/file-reference-validator.ts
|
|
1373
|
-
var
|
|
1374
|
-
var
|
|
1375
|
-
var
|
|
1529
|
+
var import_promises7 = require("fs/promises");
|
|
1530
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
1531
|
+
var import_yaml6 = require("yaml");
|
|
1376
1532
|
|
|
1377
1533
|
// src/evaluation/file-utils.ts
|
|
1378
1534
|
var import_node_fs = require("fs");
|
|
1379
|
-
var
|
|
1380
|
-
var
|
|
1535
|
+
var import_promises6 = require("fs/promises");
|
|
1536
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
1381
1537
|
async function fileExists(filePath) {
|
|
1382
1538
|
try {
|
|
1383
|
-
await (0,
|
|
1539
|
+
await (0, import_promises6.access)(filePath, import_node_fs.constants.F_OK);
|
|
1384
1540
|
return true;
|
|
1385
1541
|
} catch {
|
|
1386
1542
|
return false;
|
|
1387
1543
|
}
|
|
1388
1544
|
}
|
|
1389
1545
|
async function findGitRoot(startPath) {
|
|
1390
|
-
let currentDir =
|
|
1391
|
-
const root =
|
|
1546
|
+
let currentDir = import_node_path6.default.dirname(import_node_path6.default.resolve(startPath));
|
|
1547
|
+
const root = import_node_path6.default.parse(currentDir).root;
|
|
1392
1548
|
while (currentDir !== root) {
|
|
1393
|
-
const gitPath =
|
|
1549
|
+
const gitPath = import_node_path6.default.join(currentDir, ".git");
|
|
1394
1550
|
if (await fileExists(gitPath)) {
|
|
1395
1551
|
return currentDir;
|
|
1396
1552
|
}
|
|
1397
|
-
const parentDir =
|
|
1553
|
+
const parentDir = import_node_path6.default.dirname(currentDir);
|
|
1398
1554
|
if (parentDir === currentDir) {
|
|
1399
1555
|
break;
|
|
1400
1556
|
}
|
|
@@ -1405,16 +1561,16 @@ async function findGitRoot(startPath) {
|
|
|
1405
1561
|
function buildSearchRoots(evalPath, repoRoot) {
|
|
1406
1562
|
const uniqueRoots = [];
|
|
1407
1563
|
const addRoot = (root) => {
|
|
1408
|
-
const normalized =
|
|
1564
|
+
const normalized = import_node_path6.default.resolve(root);
|
|
1409
1565
|
if (!uniqueRoots.includes(normalized)) {
|
|
1410
1566
|
uniqueRoots.push(normalized);
|
|
1411
1567
|
}
|
|
1412
1568
|
};
|
|
1413
|
-
let currentDir =
|
|
1569
|
+
let currentDir = import_node_path6.default.dirname(evalPath);
|
|
1414
1570
|
let reachedBoundary = false;
|
|
1415
1571
|
while (!reachedBoundary) {
|
|
1416
1572
|
addRoot(currentDir);
|
|
1417
|
-
const parentDir =
|
|
1573
|
+
const parentDir = import_node_path6.default.dirname(currentDir);
|
|
1418
1574
|
if (currentDir === repoRoot || parentDir === currentDir) {
|
|
1419
1575
|
reachedBoundary = true;
|
|
1420
1576
|
} else {
|
|
@@ -1432,16 +1588,16 @@ function trimLeadingSeparators(value) {
|
|
|
1432
1588
|
async function resolveFileReference(rawValue, searchRoots) {
|
|
1433
1589
|
const displayPath = trimLeadingSeparators(rawValue);
|
|
1434
1590
|
const potentialPaths = [];
|
|
1435
|
-
if (
|
|
1436
|
-
potentialPaths.push(
|
|
1591
|
+
if (import_node_path6.default.isAbsolute(rawValue)) {
|
|
1592
|
+
potentialPaths.push(import_node_path6.default.normalize(rawValue));
|
|
1437
1593
|
}
|
|
1438
1594
|
for (const base of searchRoots) {
|
|
1439
|
-
potentialPaths.push(
|
|
1595
|
+
potentialPaths.push(import_node_path6.default.resolve(base, displayPath));
|
|
1440
1596
|
}
|
|
1441
1597
|
const attempted = [];
|
|
1442
1598
|
const seen = /* @__PURE__ */ new Set();
|
|
1443
1599
|
for (const candidate of potentialPaths) {
|
|
1444
|
-
const absoluteCandidate =
|
|
1600
|
+
const absoluteCandidate = import_node_path6.default.resolve(candidate);
|
|
1445
1601
|
if (seen.has(absoluteCandidate)) {
|
|
1446
1602
|
continue;
|
|
1447
1603
|
}
|
|
@@ -1460,7 +1616,7 @@ function isObject3(value) {
|
|
|
1460
1616
|
}
|
|
1461
1617
|
async function validateFileReferences(evalFilePath) {
|
|
1462
1618
|
const errors = [];
|
|
1463
|
-
const absolutePath =
|
|
1619
|
+
const absolutePath = import_node_path7.default.resolve(evalFilePath);
|
|
1464
1620
|
const gitRoot = await findGitRoot(absolutePath);
|
|
1465
1621
|
if (!gitRoot) {
|
|
1466
1622
|
errors.push({
|
|
@@ -1473,8 +1629,8 @@ async function validateFileReferences(evalFilePath) {
|
|
|
1473
1629
|
const searchRoots = buildSearchRoots(absolutePath, gitRoot);
|
|
1474
1630
|
let parsed;
|
|
1475
1631
|
try {
|
|
1476
|
-
const content = await (0,
|
|
1477
|
-
parsed = (0,
|
|
1632
|
+
const content = await (0, import_promises7.readFile)(absolutePath, "utf8");
|
|
1633
|
+
parsed = (0, import_yaml6.parse)(content);
|
|
1478
1634
|
} catch {
|
|
1479
1635
|
return errors;
|
|
1480
1636
|
}
|
|
@@ -1561,7 +1717,7 @@ async function validateMessagesFileRefs(messages, location, searchRoots, filePat
|
|
|
1561
1717
|
});
|
|
1562
1718
|
} else {
|
|
1563
1719
|
try {
|
|
1564
|
-
const fileContent = await (0,
|
|
1720
|
+
const fileContent = await (0, import_promises7.readFile)(resolvedPath, "utf8");
|
|
1565
1721
|
if (fileContent.trim().length === 0) {
|
|
1566
1722
|
errors.push({
|
|
1567
1723
|
severity: "warning",
|