agentv 4.8.0 → 4.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.
@@ -6941,7 +6941,7 @@ function createOpenRouter(options = {}) {
6941
6941
  );
6942
6942
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
6943
6943
  provider: "openrouter.chat",
6944
- url: ({ path: path50 }) => `${baseURL}${path50}`,
6944
+ url: ({ path: path51 }) => `${baseURL}${path51}`,
6945
6945
  headers: getHeaders,
6946
6946
  compatibility,
6947
6947
  fetch: options.fetch,
@@ -6949,7 +6949,7 @@ function createOpenRouter(options = {}) {
6949
6949
  });
6950
6950
  const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
6951
6951
  provider: "openrouter.completion",
6952
- url: ({ path: path50 }) => `${baseURL}${path50}`,
6952
+ url: ({ path: path51 }) => `${baseURL}${path51}`,
6953
6953
  headers: getHeaders,
6954
6954
  compatibility,
6955
6955
  fetch: options.fetch,
@@ -6957,14 +6957,14 @@ function createOpenRouter(options = {}) {
6957
6957
  });
6958
6958
  const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
6959
6959
  provider: "openrouter.embedding",
6960
- url: ({ path: path50 }) => `${baseURL}${path50}`,
6960
+ url: ({ path: path51 }) => `${baseURL}${path51}`,
6961
6961
  headers: getHeaders,
6962
6962
  fetch: options.fetch,
6963
6963
  extraBody: options.extraBody
6964
6964
  });
6965
6965
  const createImageModel = (modelId, settings = {}) => new OpenRouterImageModel(modelId, settings, {
6966
6966
  provider: "openrouter.image",
6967
- url: ({ path: path50 }) => `${baseURL}${path50}`,
6967
+ url: ({ path: path51 }) => `${baseURL}${path51}`,
6968
6968
  headers: getHeaders,
6969
6969
  fetch: options.fetch,
6970
6970
  extraBody: options.extraBody
@@ -14556,18 +14556,21 @@ import { readdir as readdir6, stat as stat7 } from "node:fs/promises";
14556
14556
  import path43 from "node:path";
14557
14557
  import { existsSync as existsSync5 } from "node:fs";
14558
14558
  import path45 from "node:path";
14559
- import { mkdir as mkdir15, readFile as readFile13, writeFile as writeFile8 } from "node:fs/promises";
14559
+ import { readFile as readFile13 } from "node:fs/promises";
14560
14560
  import path46 from "node:path";
14561
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync as readdirSync3, statSync as statSync2, writeFileSync } from "node:fs";
14561
+ import { parse as parse5 } from "yaml";
14562
+ import { mkdir as mkdir15, readFile as readFile14, writeFile as writeFile8 } from "node:fs/promises";
14562
14563
  import path47 from "node:path";
14564
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync as readdirSync3, statSync as statSync2, writeFileSync } from "node:fs";
14565
+ import path48 from "node:path";
14563
14566
  import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
14564
14567
  import { readdir as readdir8, stat as stat9 } from "node:fs/promises";
14565
14568
  import { homedir as homedir3 } from "node:os";
14566
- import path48 from "node:path";
14569
+ import path49 from "node:path";
14567
14570
  import { readdir as readdir9, stat as stat10 } from "node:fs/promises";
14568
14571
  import { homedir as homedir4 } from "node:os";
14569
- import path49 from "node:path";
14570
- import { readFile as readFile14 } from "node:fs/promises";
14572
+ import path50 from "node:path";
14573
+ import { readFile as readFile15 } from "node:fs/promises";
14571
14574
  function computeTraceSummary(messages) {
14572
14575
  const toolCallCounts = {};
14573
14576
  const toolDurations = {};
@@ -17389,6 +17392,58 @@ function parseMetadata(suite) {
17389
17392
  requires: suite.requires
17390
17393
  });
17391
17394
  }
17395
+ function parseRepoSource(raw) {
17396
+ if (!isJsonObject(raw)) return void 0;
17397
+ const obj = raw;
17398
+ if (obj.type === "git" && typeof obj.url === "string") {
17399
+ return { type: "git", url: obj.url };
17400
+ }
17401
+ if (obj.type === "local" && typeof obj.path === "string") {
17402
+ return { type: "local", path: obj.path };
17403
+ }
17404
+ return void 0;
17405
+ }
17406
+ function parseRepoCheckout(raw) {
17407
+ if (!isJsonObject(raw)) return void 0;
17408
+ const obj = raw;
17409
+ const ref = typeof obj.ref === "string" ? obj.ref : void 0;
17410
+ const resolve2 = obj.resolve === "remote" || obj.resolve === "local" ? obj.resolve : void 0;
17411
+ const ancestor = typeof obj.ancestor === "number" ? obj.ancestor : void 0;
17412
+ if (!ref && !resolve2 && ancestor === void 0) return void 0;
17413
+ return {
17414
+ ...ref !== void 0 && { ref },
17415
+ ...resolve2 !== void 0 && { resolve: resolve2 },
17416
+ ...ancestor !== void 0 && { ancestor }
17417
+ };
17418
+ }
17419
+ function parseRepoClone(raw) {
17420
+ if (!isJsonObject(raw)) return void 0;
17421
+ const obj = raw;
17422
+ const depth = typeof obj.depth === "number" ? obj.depth : void 0;
17423
+ const filter2 = typeof obj.filter === "string" ? obj.filter : void 0;
17424
+ const sparse = Array.isArray(obj.sparse) ? obj.sparse.filter((s) => typeof s === "string") : void 0;
17425
+ if (depth === void 0 && !filter2 && !sparse) return void 0;
17426
+ return {
17427
+ ...depth !== void 0 && { depth },
17428
+ ...filter2 !== void 0 && { filter: filter2 },
17429
+ ...sparse !== void 0 && { sparse }
17430
+ };
17431
+ }
17432
+ function parseRepoConfig(raw) {
17433
+ if (!isJsonObject(raw)) return void 0;
17434
+ const obj = raw;
17435
+ const repoPath = typeof obj.path === "string" ? obj.path : void 0;
17436
+ const source = parseRepoSource(obj.source);
17437
+ if (!repoPath || !source) return void 0;
17438
+ const checkout = parseRepoCheckout(obj.checkout);
17439
+ const clone = parseRepoClone(obj.clone);
17440
+ return {
17441
+ path: repoPath,
17442
+ source,
17443
+ ...checkout !== void 0 && { checkout },
17444
+ ...clone !== void 0 && { clone }
17445
+ };
17446
+ }
17392
17447
  async function buildPromptInputs(testCase, mode = "lm") {
17393
17448
  const segmentsByMessage = testCase.input.map(
17394
17449
  (message) => extractContentSegments(message.content)
@@ -17780,58 +17835,6 @@ function parseWorkspaceScriptConfig(raw, evalFileDir) {
17780
17835
  }
17781
17836
  return cwd ? { ...config, cwd } : config;
17782
17837
  }
17783
- function parseRepoSource(raw) {
17784
- if (!isJsonObject(raw)) return void 0;
17785
- const obj = raw;
17786
- if (obj.type === "git" && typeof obj.url === "string") {
17787
- return { type: "git", url: obj.url };
17788
- }
17789
- if (obj.type === "local" && typeof obj.path === "string") {
17790
- return { type: "local", path: obj.path };
17791
- }
17792
- return void 0;
17793
- }
17794
- function parseRepoCheckout(raw) {
17795
- if (!isJsonObject(raw)) return void 0;
17796
- const obj = raw;
17797
- const ref = typeof obj.ref === "string" ? obj.ref : void 0;
17798
- const resolve2 = obj.resolve === "remote" || obj.resolve === "local" ? obj.resolve : void 0;
17799
- const ancestor = typeof obj.ancestor === "number" ? obj.ancestor : void 0;
17800
- if (!ref && !resolve2 && ancestor === void 0) return void 0;
17801
- return {
17802
- ...ref !== void 0 && { ref },
17803
- ...resolve2 !== void 0 && { resolve: resolve2 },
17804
- ...ancestor !== void 0 && { ancestor }
17805
- };
17806
- }
17807
- function parseRepoClone(raw) {
17808
- if (!isJsonObject(raw)) return void 0;
17809
- const obj = raw;
17810
- const depth = typeof obj.depth === "number" ? obj.depth : void 0;
17811
- const filter2 = typeof obj.filter === "string" ? obj.filter : void 0;
17812
- const sparse = Array.isArray(obj.sparse) ? obj.sparse.filter((s) => typeof s === "string") : void 0;
17813
- if (depth === void 0 && !filter2 && !sparse) return void 0;
17814
- return {
17815
- ...depth !== void 0 && { depth },
17816
- ...filter2 !== void 0 && { filter: filter2 },
17817
- ...sparse !== void 0 && { sparse }
17818
- };
17819
- }
17820
- function parseRepoConfig(raw) {
17821
- if (!isJsonObject(raw)) return void 0;
17822
- const obj = raw;
17823
- const repoPath = typeof obj.path === "string" ? obj.path : void 0;
17824
- const source = parseRepoSource(obj.source);
17825
- if (!repoPath || !source) return void 0;
17826
- const checkout = parseRepoCheckout(obj.checkout);
17827
- const clone = parseRepoClone(obj.clone);
17828
- return {
17829
- path: repoPath,
17830
- source,
17831
- ...checkout !== void 0 && { checkout },
17832
- ...clone !== void 0 && { clone }
17833
- };
17834
- }
17835
17838
  function parseWorkspaceHookConfig(raw, evalFileDir) {
17836
17839
  if (!isJsonObject(raw)) return void 0;
17837
17840
  const script = parseWorkspaceScriptConfig(raw, evalFileDir);
@@ -25076,15 +25079,15 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
25076
25079
  });
25077
25080
  }
25078
25081
  async function execShellWithStdin(command, stdinPayload, options = {}) {
25079
- const { mkdir: mkdir16, readFile: readFile15, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
25082
+ const { mkdir: mkdir16, readFile: readFile16, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
25080
25083
  const { tmpdir: tmpdir3 } = await import("node:os");
25081
- const path50 = await import("node:path");
25084
+ const path51 = await import("node:path");
25082
25085
  const { randomUUID: randomUUID10 } = await import("node:crypto");
25083
- const dir = path50.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
25086
+ const dir = path51.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
25084
25087
  await mkdir16(dir, { recursive: true });
25085
- const stdinPath = path50.join(dir, "stdin.txt");
25086
- const stdoutPath = path50.join(dir, "stdout.txt");
25087
- const stderrPath = path50.join(dir, "stderr.txt");
25088
+ const stdinPath = path51.join(dir, "stdin.txt");
25089
+ const stdoutPath = path51.join(dir, "stdout.txt");
25090
+ const stderrPath = path51.join(dir, "stderr.txt");
25088
25091
  await writeFile9(stdinPath, stdinPayload, "utf8");
25089
25092
  const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
25090
25093
  const { spawn: spawn5 } = await import("node:child_process");
@@ -25114,8 +25117,8 @@ async function execShellWithStdin(command, stdinPayload, options = {}) {
25114
25117
  resolve2(code ?? 0);
25115
25118
  });
25116
25119
  });
25117
- const stdout = (await readFile15(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
25118
- const stderr = (await readFile15(stderrPath, "utf8")).replace(/\r\n/g, "\n");
25120
+ const stdout = (await readFile16(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
25121
+ const stderr = (await readFile16(stderrPath, "utf8")).replace(/\r\n/g, "\n");
25119
25122
  return { stdout, stderr, exitCode };
25120
25123
  } finally {
25121
25124
  await rm6(dir, { recursive: true, force: true });
@@ -27349,115 +27352,115 @@ var FieldAccuracyEvaluator = class {
27349
27352
  * Evaluate a single field against the expected value.
27350
27353
  */
27351
27354
  evaluateField(fieldConfig, candidateData, expectedData) {
27352
- const { path: path50, match, required = true, weight = 1 } = fieldConfig;
27353
- const candidateValue = resolvePath(candidateData, path50);
27354
- const expectedValue = resolvePath(expectedData, path50);
27355
+ const { path: path51, match, required = true, weight = 1 } = fieldConfig;
27356
+ const candidateValue = resolvePath(candidateData, path51);
27357
+ const expectedValue = resolvePath(expectedData, path51);
27355
27358
  if (expectedValue === void 0) {
27356
27359
  return {
27357
- path: path50,
27360
+ path: path51,
27358
27361
  score: 1,
27359
27362
  // No expected value means no comparison needed
27360
27363
  weight,
27361
27364
  hit: true,
27362
- message: `${path50}: no expected value`
27365
+ message: `${path51}: no expected value`
27363
27366
  };
27364
27367
  }
27365
27368
  if (candidateValue === void 0) {
27366
27369
  if (required) {
27367
27370
  return {
27368
- path: path50,
27371
+ path: path51,
27369
27372
  score: 0,
27370
27373
  weight,
27371
27374
  hit: false,
27372
- message: `${path50} (required, missing)`
27375
+ message: `${path51} (required, missing)`
27373
27376
  };
27374
27377
  }
27375
27378
  return {
27376
- path: path50,
27379
+ path: path51,
27377
27380
  score: 1,
27378
27381
  // Don't penalize missing optional fields
27379
27382
  weight: 0,
27380
27383
  // Zero weight means it won't affect the score
27381
27384
  hit: true,
27382
- message: `${path50}: optional field missing`
27385
+ message: `${path51}: optional field missing`
27383
27386
  };
27384
27387
  }
27385
27388
  switch (match) {
27386
27389
  case "exact":
27387
- return this.compareExact(path50, candidateValue, expectedValue, weight);
27390
+ return this.compareExact(path51, candidateValue, expectedValue, weight);
27388
27391
  case "numeric_tolerance":
27389
27392
  return this.compareNumericTolerance(
27390
- path50,
27393
+ path51,
27391
27394
  candidateValue,
27392
27395
  expectedValue,
27393
27396
  fieldConfig,
27394
27397
  weight
27395
27398
  );
27396
27399
  case "date":
27397
- return this.compareDate(path50, candidateValue, expectedValue, fieldConfig, weight);
27400
+ return this.compareDate(path51, candidateValue, expectedValue, fieldConfig, weight);
27398
27401
  default:
27399
27402
  return {
27400
- path: path50,
27403
+ path: path51,
27401
27404
  score: 0,
27402
27405
  weight,
27403
27406
  hit: false,
27404
- message: `${path50}: unknown match type "${match}"`
27407
+ message: `${path51}: unknown match type "${match}"`
27405
27408
  };
27406
27409
  }
27407
27410
  }
27408
27411
  /**
27409
27412
  * Exact equality comparison.
27410
27413
  */
27411
- compareExact(path50, candidateValue, expectedValue, weight) {
27414
+ compareExact(path51, candidateValue, expectedValue, weight) {
27412
27415
  if (deepEqual(candidateValue, expectedValue)) {
27413
27416
  return {
27414
- path: path50,
27417
+ path: path51,
27415
27418
  score: 1,
27416
27419
  weight,
27417
27420
  hit: true,
27418
- message: path50
27421
+ message: path51
27419
27422
  };
27420
27423
  }
27421
27424
  if (typeof candidateValue !== typeof expectedValue) {
27422
27425
  return {
27423
- path: path50,
27426
+ path: path51,
27424
27427
  score: 0,
27425
27428
  weight,
27426
27429
  hit: false,
27427
- message: `${path50} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
27430
+ message: `${path51} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
27428
27431
  };
27429
27432
  }
27430
27433
  return {
27431
- path: path50,
27434
+ path: path51,
27432
27435
  score: 0,
27433
27436
  weight,
27434
27437
  hit: false,
27435
- message: `${path50} (value mismatch)`
27438
+ message: `${path51} (value mismatch)`
27436
27439
  };
27437
27440
  }
27438
27441
  /**
27439
27442
  * Numeric comparison with absolute or relative tolerance.
27440
27443
  */
27441
- compareNumericTolerance(path50, candidateValue, expectedValue, fieldConfig, weight) {
27444
+ compareNumericTolerance(path51, candidateValue, expectedValue, fieldConfig, weight) {
27442
27445
  const { tolerance = 0, relative = false } = fieldConfig;
27443
27446
  const candidateNum = toNumber(candidateValue);
27444
27447
  const expectedNum = toNumber(expectedValue);
27445
27448
  if (candidateNum === null || expectedNum === null) {
27446
27449
  return {
27447
- path: path50,
27450
+ path: path51,
27448
27451
  score: 0,
27449
27452
  weight,
27450
27453
  hit: false,
27451
- message: `${path50} (non-numeric value)`
27454
+ message: `${path51} (non-numeric value)`
27452
27455
  };
27453
27456
  }
27454
27457
  if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
27455
27458
  return {
27456
- path: path50,
27459
+ path: path51,
27457
27460
  score: 0,
27458
27461
  weight,
27459
27462
  hit: false,
27460
- message: `${path50} (invalid numeric value)`
27463
+ message: `${path51} (invalid numeric value)`
27461
27464
  };
27462
27465
  }
27463
27466
  const diff = Math.abs(candidateNum - expectedNum);
@@ -27470,61 +27473,61 @@ var FieldAccuracyEvaluator = class {
27470
27473
  }
27471
27474
  if (withinTolerance) {
27472
27475
  return {
27473
- path: path50,
27476
+ path: path51,
27474
27477
  score: 1,
27475
27478
  weight,
27476
27479
  hit: true,
27477
- message: `${path50} (within tolerance: diff=${diff.toFixed(2)})`
27480
+ message: `${path51} (within tolerance: diff=${diff.toFixed(2)})`
27478
27481
  };
27479
27482
  }
27480
27483
  return {
27481
- path: path50,
27484
+ path: path51,
27482
27485
  score: 0,
27483
27486
  weight,
27484
27487
  hit: false,
27485
- message: `${path50} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
27488
+ message: `${path51} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
27486
27489
  };
27487
27490
  }
27488
27491
  /**
27489
27492
  * Date comparison with format normalization.
27490
27493
  */
27491
- compareDate(path50, candidateValue, expectedValue, fieldConfig, weight) {
27494
+ compareDate(path51, candidateValue, expectedValue, fieldConfig, weight) {
27492
27495
  const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
27493
27496
  const candidateDate = parseDate(String(candidateValue), formats);
27494
27497
  const expectedDate = parseDate(String(expectedValue), formats);
27495
27498
  if (candidateDate === null) {
27496
27499
  return {
27497
- path: path50,
27500
+ path: path51,
27498
27501
  score: 0,
27499
27502
  weight,
27500
27503
  hit: false,
27501
- message: `${path50} (unparseable candidate date)`
27504
+ message: `${path51} (unparseable candidate date)`
27502
27505
  };
27503
27506
  }
27504
27507
  if (expectedDate === null) {
27505
27508
  return {
27506
- path: path50,
27509
+ path: path51,
27507
27510
  score: 0,
27508
27511
  weight,
27509
27512
  hit: false,
27510
- message: `${path50} (unparseable expected date)`
27513
+ message: `${path51} (unparseable expected date)`
27511
27514
  };
27512
27515
  }
27513
27516
  if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
27514
27517
  return {
27515
- path: path50,
27518
+ path: path51,
27516
27519
  score: 1,
27517
27520
  weight,
27518
27521
  hit: true,
27519
- message: path50
27522
+ message: path51
27520
27523
  };
27521
27524
  }
27522
27525
  return {
27523
- path: path50,
27526
+ path: path51,
27524
27527
  score: 0,
27525
27528
  weight,
27526
27529
  hit: false,
27527
- message: `${path50} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
27530
+ message: `${path51} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
27528
27531
  };
27529
27532
  }
27530
27533
  /**
@@ -27557,11 +27560,11 @@ var FieldAccuracyEvaluator = class {
27557
27560
  };
27558
27561
  }
27559
27562
  };
27560
- function resolvePath(obj, path50) {
27561
- if (!path50 || !obj) {
27563
+ function resolvePath(obj, path51) {
27564
+ if (!path51 || !obj) {
27562
27565
  return void 0;
27563
27566
  }
27564
- const parts = path50.split(/\.|\[|\]/).filter((p) => p.length > 0);
27567
+ const parts = path51.split(/\.|\[|\]/).filter((p) => p.length > 0);
27565
27568
  let current = obj;
27566
27569
  for (const part of parts) {
27567
27570
  if (current === null || current === void 0) {
@@ -28043,8 +28046,8 @@ var TokenUsageEvaluator = class {
28043
28046
  };
28044
28047
  }
28045
28048
  };
28046
- function getNestedValue(obj, path50) {
28047
- const parts = path50.split(".");
28049
+ function getNestedValue(obj, path51) {
28050
+ const parts = path51.split(".");
28048
28051
  let current = obj;
28049
28052
  for (const part of parts) {
28050
28053
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -32463,6 +32466,98 @@ function buildPrompt(criteria, question, referenceAnswer) {
32463
32466
  }
32464
32467
  return parts.join("\n");
32465
32468
  }
32469
+ function normalizeGitUrl(url) {
32470
+ let normalized = url.replace(/\.git$/, "");
32471
+ try {
32472
+ const parsed = new URL(normalized);
32473
+ parsed.hostname = parsed.hostname.toLowerCase();
32474
+ normalized = parsed.toString().replace(/\/$/, "");
32475
+ } catch {
32476
+ }
32477
+ return normalized;
32478
+ }
32479
+ async function scanRepoDeps(evalFilePaths) {
32480
+ const seen = /* @__PURE__ */ new Map();
32481
+ const errors = [];
32482
+ for (const filePath of evalFilePaths) {
32483
+ try {
32484
+ const repos = await extractReposFromEvalFile(filePath);
32485
+ for (const repo of repos) {
32486
+ if (repo.source.type !== "git") continue;
32487
+ const ref = repo.checkout?.ref;
32488
+ const key = `${normalizeGitUrl(repo.source.url)}\0${ref ?? ""}`;
32489
+ const existing = seen.get(key);
32490
+ if (existing) {
32491
+ existing.usedBy.push(filePath);
32492
+ } else {
32493
+ const { ref: _ref, ...checkoutRest } = repo.checkout ?? {};
32494
+ const hasCheckout = Object.keys(checkoutRest).length > 0;
32495
+ seen.set(key, {
32496
+ url: repo.source.url,
32497
+ ref,
32498
+ clone: repo.clone,
32499
+ checkout: hasCheckout ? checkoutRest : void 0,
32500
+ usedBy: [filePath]
32501
+ });
32502
+ }
32503
+ }
32504
+ } catch (err) {
32505
+ errors.push({
32506
+ file: filePath,
32507
+ message: err instanceof Error ? err.message : String(err)
32508
+ });
32509
+ }
32510
+ }
32511
+ return { repos: [...seen.values()], errors };
32512
+ }
32513
+ async function extractReposFromEvalFile(filePath) {
32514
+ const content = await readFile13(filePath, "utf8");
32515
+ const parsed = interpolateEnv(parse5(content), process.env);
32516
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return [];
32517
+ const obj = parsed;
32518
+ const evalFileDir = path46.dirname(path46.resolve(filePath));
32519
+ const repos = [];
32520
+ const suiteRepos = await extractReposFromWorkspaceRaw(obj.workspace, evalFileDir);
32521
+ repos.push(...suiteRepos);
32522
+ const tests = Array.isArray(obj.tests) ? obj.tests : [];
32523
+ for (const test of tests) {
32524
+ if (test && typeof test === "object" && !Array.isArray(test)) {
32525
+ const testObj = test;
32526
+ const testRepos = await extractReposFromWorkspaceRaw(testObj.workspace, evalFileDir);
32527
+ repos.push(...testRepos);
32528
+ }
32529
+ }
32530
+ return repos;
32531
+ }
32532
+ async function extractReposFromWorkspaceRaw(raw, evalFileDir) {
32533
+ if (typeof raw === "string") {
32534
+ const workspaceFilePath = path46.resolve(evalFileDir, raw);
32535
+ const content = await readFile13(workspaceFilePath, "utf8");
32536
+ const parsed = interpolateEnv(parse5(content), process.env);
32537
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return [];
32538
+ return extractReposFromObject(parsed);
32539
+ }
32540
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
32541
+ return extractReposFromObject(raw);
32542
+ }
32543
+ return [];
32544
+ }
32545
+ function extractReposFromObject(obj) {
32546
+ const rawRepos = Array.isArray(obj.repos) ? obj.repos : [];
32547
+ const result = [];
32548
+ for (const r of rawRepos) {
32549
+ if (!r || typeof r !== "object" || Array.isArray(r)) continue;
32550
+ const repo = r;
32551
+ const source = parseRepoSource(repo.source);
32552
+ if (!source) continue;
32553
+ result.push({
32554
+ source,
32555
+ checkout: parseRepoCheckout(repo.checkout),
32556
+ clone: parseRepoClone(repo.clone)
32557
+ });
32558
+ }
32559
+ return result;
32560
+ }
32466
32561
  var DEFAULT_CACHE_PATH = ".agentv/cache";
32467
32562
  var ResponseCache = class {
32468
32563
  cachePath;
@@ -32472,7 +32567,7 @@ var ResponseCache = class {
32472
32567
  async get(key) {
32473
32568
  const filePath = this.keyToPath(key);
32474
32569
  try {
32475
- const data = await readFile13(filePath, "utf8");
32570
+ const data = await readFile14(filePath, "utf8");
32476
32571
  return JSON.parse(data);
32477
32572
  } catch {
32478
32573
  return void 0;
@@ -32480,13 +32575,13 @@ var ResponseCache = class {
32480
32575
  }
32481
32576
  async set(key, value) {
32482
32577
  const filePath = this.keyToPath(key);
32483
- const dir = path46.dirname(filePath);
32578
+ const dir = path47.dirname(filePath);
32484
32579
  await mkdir15(dir, { recursive: true });
32485
32580
  await writeFile8(filePath, JSON.stringify(value, null, 2), "utf8");
32486
32581
  }
32487
32582
  keyToPath(key) {
32488
32583
  const prefix = key.slice(0, 2);
32489
- return path46.join(this.cachePath, prefix, `${key}.json`);
32584
+ return path47.join(this.cachePath, prefix, `${key}.json`);
32490
32585
  }
32491
32586
  };
32492
32587
  function shouldEnableCache(params) {
@@ -32501,7 +32596,7 @@ function shouldSkipCacheForTemperature(targetConfig) {
32501
32596
  return false;
32502
32597
  }
32503
32598
  function getProjectsRegistryPath() {
32504
- return path47.join(getAgentvHome(), "projects.yaml");
32599
+ return path48.join(getAgentvHome(), "projects.yaml");
32505
32600
  }
32506
32601
  function loadProjectRegistry() {
32507
32602
  const registryPath = getProjectsRegistryPath();
@@ -32521,14 +32616,14 @@ function loadProjectRegistry() {
32521
32616
  }
32522
32617
  function saveProjectRegistry(registry) {
32523
32618
  const registryPath = getProjectsRegistryPath();
32524
- const dir = path47.dirname(registryPath);
32619
+ const dir = path48.dirname(registryPath);
32525
32620
  if (!existsSync6(dir)) {
32526
32621
  mkdirSync2(dir, { recursive: true });
32527
32622
  }
32528
32623
  writeFileSync(registryPath, stringifyYaml(registry), "utf-8");
32529
32624
  }
32530
32625
  function deriveProjectId(dirPath, existingIds) {
32531
- const base = path47.basename(dirPath).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
32626
+ const base = path48.basename(dirPath).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
32532
32627
  let candidate = base || "project";
32533
32628
  let suffix = 2;
32534
32629
  while (existingIds.includes(candidate)) {
@@ -32538,11 +32633,11 @@ function deriveProjectId(dirPath, existingIds) {
32538
32633
  return candidate;
32539
32634
  }
32540
32635
  function addProject(projectPath) {
32541
- const absPath = path47.resolve(projectPath);
32636
+ const absPath = path48.resolve(projectPath);
32542
32637
  if (!existsSync6(absPath)) {
32543
32638
  throw new Error(`Directory not found: ${absPath}`);
32544
32639
  }
32545
- if (!existsSync6(path47.join(absPath, ".agentv"))) {
32640
+ if (!existsSync6(path48.join(absPath, ".agentv"))) {
32546
32641
  throw new Error(`No .agentv/ directory found in ${absPath}. Run an evaluation first.`);
32547
32642
  }
32548
32643
  const registry = loadProjectRegistry();
@@ -32556,7 +32651,7 @@ function addProject(projectPath) {
32556
32651
  absPath,
32557
32652
  registry.projects.map((p) => p.id)
32558
32653
  ),
32559
- name: path47.basename(absPath),
32654
+ name: path48.basename(absPath),
32560
32655
  path: absPath,
32561
32656
  addedAt: now2,
32562
32657
  lastOpenedAt: now2
@@ -32585,14 +32680,14 @@ function touchProject(projectId) {
32585
32680
  }
32586
32681
  }
32587
32682
  function discoverProjects(rootDir, maxDepth = 2) {
32588
- const absRoot = path47.resolve(rootDir);
32683
+ const absRoot = path48.resolve(rootDir);
32589
32684
  if (!existsSync6(absRoot) || !statSync2(absRoot).isDirectory()) {
32590
32685
  return [];
32591
32686
  }
32592
32687
  const results = [];
32593
32688
  function scan(dir, depth) {
32594
32689
  if (depth > maxDepth) return;
32595
- if (existsSync6(path47.join(dir, ".agentv"))) {
32690
+ if (existsSync6(path48.join(dir, ".agentv"))) {
32596
32691
  results.push(dir);
32597
32692
  return;
32598
32693
  }
@@ -32602,7 +32697,7 @@ function discoverProjects(rootDir, maxDepth = 2) {
32602
32697
  for (const entry of entries) {
32603
32698
  if (!entry.isDirectory()) continue;
32604
32699
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
32605
- scan(path47.join(dir, entry.name), depth + 1);
32700
+ scan(path48.join(dir, entry.name), depth + 1);
32606
32701
  }
32607
32702
  } catch {
32608
32703
  }
@@ -33501,7 +33596,7 @@ function extractResponseItemContent(content) {
33501
33596
  }
33502
33597
  return parts.length > 0 ? parts.join("") : void 0;
33503
33598
  }
33504
- var DEFAULT_SESSIONS_DIR = () => path48.join(homedir3(), ".codex", "sessions");
33599
+ var DEFAULT_SESSIONS_DIR = () => path49.join(homedir3(), ".codex", "sessions");
33505
33600
  async function discoverCodexSessions(opts) {
33506
33601
  const sessionsDir = opts?.sessionsDir ?? DEFAULT_SESSIONS_DIR();
33507
33602
  const limit = opts?.latest ? 1 : opts?.limit ?? 10;
@@ -33513,7 +33608,7 @@ async function discoverCodexSessions(opts) {
33513
33608
  return [];
33514
33609
  }
33515
33610
  for (const year of yearDirs) {
33516
- const yearPath = path48.join(sessionsDir, year);
33611
+ const yearPath = path49.join(sessionsDir, year);
33517
33612
  let monthDirs;
33518
33613
  try {
33519
33614
  monthDirs = await readdir8(yearPath);
@@ -33521,7 +33616,7 @@ async function discoverCodexSessions(opts) {
33521
33616
  continue;
33522
33617
  }
33523
33618
  for (const month of monthDirs) {
33524
- const monthPath = path48.join(yearPath, month);
33619
+ const monthPath = path49.join(yearPath, month);
33525
33620
  let dayDirs;
33526
33621
  try {
33527
33622
  dayDirs = await readdir8(monthPath);
@@ -33533,7 +33628,7 @@ async function discoverCodexSessions(opts) {
33533
33628
  const dirDate = `${year}-${month}-${day}`;
33534
33629
  if (dirDate !== opts.date) continue;
33535
33630
  }
33536
- const dayPath = path48.join(monthPath, day);
33631
+ const dayPath = path49.join(monthPath, day);
33537
33632
  let files;
33538
33633
  try {
33539
33634
  files = await readdir8(dayPath);
@@ -33542,7 +33637,7 @@ async function discoverCodexSessions(opts) {
33542
33637
  }
33543
33638
  for (const file of files) {
33544
33639
  if (!file.startsWith("rollout-") || !file.endsWith(".jsonl")) continue;
33545
- const filePath = path48.join(dayPath, file);
33640
+ const filePath = path49.join(dayPath, file);
33546
33641
  const nameWithoutExt = file.replace(/\.jsonl$/, "");
33547
33642
  const parts = nameWithoutExt.split("-");
33548
33643
  const sessionId = parts.length >= 6 ? parts.slice(-5).join("-") : nameWithoutExt;
@@ -33561,7 +33656,7 @@ async function discoverCodexSessions(opts) {
33561
33656
  sessions.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());
33562
33657
  return sessions.slice(0, limit);
33563
33658
  }
33564
- var DEFAULT_PROJECTS_DIR = () => path49.join(homedir4(), ".claude", "projects");
33659
+ var DEFAULT_PROJECTS_DIR = () => path50.join(homedir4(), ".claude", "projects");
33565
33660
  function encodeProjectPath(projectPath) {
33566
33661
  return projectPath.replace(/\//g, "-");
33567
33662
  }
@@ -33580,7 +33675,7 @@ async function discoverClaudeSessions(opts) {
33580
33675
  }
33581
33676
  const sessions = [];
33582
33677
  for (const projectDir of projectDirs) {
33583
- const dirPath = path49.join(projectsDir, projectDir);
33678
+ const dirPath = path50.join(projectsDir, projectDir);
33584
33679
  let entries;
33585
33680
  try {
33586
33681
  entries = await readdir9(dirPath);
@@ -33591,7 +33686,7 @@ async function discoverClaudeSessions(opts) {
33591
33686
  if (!entry.endsWith(".jsonl")) continue;
33592
33687
  const sessionId = entry.replace(/\.jsonl$/, "");
33593
33688
  if (opts?.sessionId && sessionId !== opts.sessionId) continue;
33594
- const filePath = path49.join(dirPath, entry);
33689
+ const filePath = path50.join(dirPath, entry);
33595
33690
  let updatedAt;
33596
33691
  try {
33597
33692
  const fileStat = await stat10(filePath);
@@ -33635,11 +33730,11 @@ function toTranscriptJsonLine(entry) {
33635
33730
  };
33636
33731
  }
33637
33732
  async function readTranscriptJsonl(filePath) {
33638
- const text2 = await readFile14(filePath, "utf8");
33733
+ const text2 = await readFile15(filePath, "utf8");
33639
33734
  return text2.split("\n").filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
33640
33735
  }
33641
33736
  async function readTranscriptFile(filePath) {
33642
- return readFile14(filePath, "utf8");
33737
+ return readFile15(filePath, "utf8");
33643
33738
  }
33644
33739
  var TranscriptProvider = class _TranscriptProvider {
33645
33740
  id;
@@ -33842,6 +33937,7 @@ export {
33842
33937
  defineConfig,
33843
33938
  loadTsConfig,
33844
33939
  generateRubrics,
33940
+ scanRepoDeps,
33845
33941
  ResponseCache,
33846
33942
  shouldEnableCache,
33847
33943
  shouldSkipCacheForTemperature,
@@ -33870,4 +33966,4 @@ export {
33870
33966
  TranscriptProvider,
33871
33967
  createAgentKernel
33872
33968
  };
33873
- //# sourceMappingURL=chunk-H4GQXK5M.js.map
33969
+ //# sourceMappingURL=chunk-7K5LYK5B.js.map