agentv 4.44.0-next.1 → 5.0.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.
Files changed (52) hide show
  1. package/README.md +2 -2
  2. package/dist/{artifact-writer-72MQQELS.js → artifact-writer-QD52FC56.js} +12 -10
  3. package/dist/{chunk-KAGZRUO6.js → chunk-6JVM4GJI.js} +3 -2
  4. package/dist/chunk-6JVM4GJI.js.map +1 -0
  5. package/dist/{chunk-2N3YSEMI.js → chunk-6Q56CEXV.js} +333 -99
  6. package/dist/chunk-6Q56CEXV.js.map +1 -0
  7. package/dist/{chunk-5DYGN547.js → chunk-GZJMODLW.js} +1008 -663
  8. package/dist/chunk-GZJMODLW.js.map +1 -0
  9. package/dist/{chunk-CXHYTYHU.js → chunk-IBI7A5RP.js} +621 -191
  10. package/dist/chunk-IBI7A5RP.js.map +1 -0
  11. package/dist/{chunk-NPVGBFF6.js → chunk-IJEZFZJR.js} +2 -43
  12. package/dist/chunk-IJEZFZJR.js.map +1 -0
  13. package/dist/{chunk-BPGJ4HBU.js → chunk-RCIEHFQ2.js} +3 -3
  14. package/dist/{chunk-NCNDA3F6.js → chunk-UG4JHZYM.js} +1176 -224
  15. package/dist/chunk-UG4JHZYM.js.map +1 -0
  16. package/dist/cli.js +7 -7
  17. package/dist/dashboard/assets/index-BVMrdN8a.js +119 -0
  18. package/dist/dashboard/assets/{index-DitffAxS.js → index-D5_8DE_B.js} +1 -1
  19. package/dist/dashboard/assets/index-DZWXfWsv.css +1 -0
  20. package/dist/dashboard/index.html +2 -2
  21. package/dist/{dist-L4YCQOQ6.js → dist-KJ6PELQY.js} +45 -11
  22. package/dist/{docker-workspace-RPPXBT27-B4AQHVWA.js → docker-workspace-ZJ2ESVBI-6UDETQII.js} +2 -2
  23. package/dist/{exec-AR6JUUN5-6MBPURPR.js → exec-MYPAJJP7-C5HD5WG5.js} +2 -2
  24. package/dist/index.js +7 -7
  25. package/dist/{interactive-DRNRKLEQ.js → interactive-2WMVAASS.js} +7 -7
  26. package/dist/skills/agentv-bench/SKILL.md +3 -3
  27. package/dist/skills/agentv-bench/agents/analyzer.md +1 -1
  28. package/dist/skills/agentv-bench/references/autoresearch.md +1 -1
  29. package/dist/skills/agentv-bench/references/eval-yaml-spec.md +13 -3
  30. package/dist/skills/agentv-bench/references/migrating-from-skill-creator.md +2 -2
  31. package/dist/skills/agentv-bench/references/schemas.md +6 -6
  32. package/dist/skills/agentv-bench/references/subagent-pipeline.md +1 -1
  33. package/dist/skills/agentv-eval-writer/SKILL.md +10 -0
  34. package/dist/skills/agentv-eval-writer/references/eval-schema.json +3 -63
  35. package/dist/skills/agentv-eval-writer/references/experiment-schema.json +278 -0
  36. package/dist/{ts-eval-loader-S7ESROX2-6CB3HB6H.js → ts-eval-loader-RE43OAGX-AMRCUKBZ.js} +3 -3
  37. package/package.json +1 -1
  38. package/dist/chunk-2N3YSEMI.js.map +0 -1
  39. package/dist/chunk-5DYGN547.js.map +0 -1
  40. package/dist/chunk-CXHYTYHU.js.map +0 -1
  41. package/dist/chunk-KAGZRUO6.js.map +0 -1
  42. package/dist/chunk-NCNDA3F6.js.map +0 -1
  43. package/dist/chunk-NPVGBFF6.js.map +0 -1
  44. package/dist/dashboard/assets/index-1Hvy8sBy.js +0 -119
  45. package/dist/dashboard/assets/index-J5sPcQO3.css +0 -1
  46. /package/dist/{artifact-writer-72MQQELS.js.map → artifact-writer-QD52FC56.js.map} +0 -0
  47. /package/dist/{chunk-BPGJ4HBU.js.map → chunk-RCIEHFQ2.js.map} +0 -0
  48. /package/dist/{dist-L4YCQOQ6.js.map → dist-KJ6PELQY.js.map} +0 -0
  49. /package/dist/{docker-workspace-RPPXBT27-B4AQHVWA.js.map → docker-workspace-ZJ2ESVBI-6UDETQII.js.map} +0 -0
  50. /package/dist/{exec-AR6JUUN5-6MBPURPR.js.map → exec-MYPAJJP7-C5HD5WG5.js.map} +0 -0
  51. /package/dist/{interactive-DRNRKLEQ.js.map → interactive-2WMVAASS.js.map} +0 -0
  52. /package/dist/{ts-eval-loader-S7ESROX2-6CB3HB6H.js.map → ts-eval-loader-RE43OAGX-AMRCUKBZ.js.map} +0 -0
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; const require = createRequire(impor
2
2
  import {
3
3
  execFileWithStdin,
4
4
  execShellWithStdin
5
- } from "./chunk-NPVGBFF6.js";
5
+ } from "./chunk-IJEZFZJR.js";
6
6
  import {
7
7
  AgentvProvider,
8
8
  AnthropicProvider,
@@ -493,8 +493,8 @@ function getErrorMap() {
493
493
 
494
494
  // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
495
495
  var makeIssue = (params) => {
496
- const { data, path: path53, errorMaps, issueData } = params;
497
- const fullPath = [...path53, ...issueData.path || []];
496
+ const { data, path: path51, errorMaps, issueData } = params;
497
+ const fullPath = [...path51, ...issueData.path || []];
498
498
  const fullIssue = {
499
499
  ...issueData,
500
500
  path: fullPath
@@ -610,11 +610,11 @@ var errorUtil;
610
610
 
611
611
  // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
612
612
  var ParseInputLazyPath = class {
613
- constructor(parent, value, path53, key) {
613
+ constructor(parent, value, path51, key) {
614
614
  this._cachedPath = [];
615
615
  this.parent = parent;
616
616
  this.data = value;
617
- this._path = path53;
617
+ this._path = path51;
618
618
  this._key = key;
619
619
  }
620
620
  get path() {
@@ -4056,19 +4056,26 @@ var coerce = {
4056
4056
  };
4057
4057
  var NEVER = INVALID;
4058
4058
 
4059
- // ../../packages/core/dist/chunk-FMQSS3SC.js
4059
+ // ../../packages/core/dist/chunk-LP6SQKR3.js
4060
4060
  import { parse } from "yaml";
4061
- import os from "node:os";
4062
4061
  import path from "node:path";
4062
+ import os from "node:os";
4063
+ import path2 from "node:path";
4063
4064
  import { constants } from "node:fs";
4064
4065
  import { access, readFile } from "node:fs/promises";
4065
- import path2 from "node:path";
4066
+ import path3 from "node:path";
4066
4067
  import { existsSync, readFileSync } from "node:fs";
4067
4068
  import { homedir } from "node:os";
4068
- import path3 from "node:path";
4069
- import { readFile as readFile2, readdir, stat } from "node:fs/promises";
4070
4069
  import path4 from "node:path";
4070
+ import { readFile as readFile2, readdir, stat } from "node:fs/promises";
4071
+ import path5 from "node:path";
4071
4072
  import fg from "fast-glob";
4073
+ import { constants as constants2 } from "node:fs";
4074
+ import { access as access2 } from "node:fs/promises";
4075
+ import path6 from "node:path";
4076
+ import { fileURLToPath } from "node:url";
4077
+ import { readFile as readFile3 } from "node:fs/promises";
4078
+ import path7 from "node:path";
4072
4079
  var CONTENT_TYPES = /* @__PURE__ */ new Set(["text", "image", "file"]);
4073
4080
  function isContent(value) {
4074
4081
  if (!value || typeof value !== "object") return false;
@@ -4171,13 +4178,40 @@ var PARSE_OPTIONS = { merge: true };
4171
4178
  function parseYamlValue(content) {
4172
4179
  return parse(content, PARSE_OPTIONS);
4173
4180
  }
4181
+ var AGENTV_CONFIG_FILE_NAME = "config.yaml";
4182
+ var AGENTV_CONFIG_YML_FILE_NAME = "config.yml";
4183
+ var AGENTV_LOCAL_CONFIG_FILE_NAME = "config.local.yaml";
4184
+ var AGENTV_LOCAL_CONFIG_YML_FILE_NAME = "config.local.yml";
4185
+ function getLocalConfigPath(configPath2) {
4186
+ const basename = path.basename(configPath2);
4187
+ const localName = basename === AGENTV_CONFIG_YML_FILE_NAME ? AGENTV_LOCAL_CONFIG_YML_FILE_NAME : AGENTV_LOCAL_CONFIG_FILE_NAME;
4188
+ return path.join(path.dirname(configPath2), localName);
4189
+ }
4190
+ function isAgentVConfigFileName(basename) {
4191
+ return basename === AGENTV_CONFIG_FILE_NAME || basename === AGENTV_CONFIG_YML_FILE_NAME || basename === AGENTV_LOCAL_CONFIG_FILE_NAME || basename === AGENTV_LOCAL_CONFIG_YML_FILE_NAME;
4192
+ }
4193
+ function isPlainConfigObject(value) {
4194
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
4195
+ return false;
4196
+ }
4197
+ const prototype = Object.getPrototypeOf(value);
4198
+ return prototype === Object.prototype || prototype === null;
4199
+ }
4200
+ function mergeConfigObjects(base, overlay) {
4201
+ const merged = { ...base };
4202
+ for (const [key, overlayValue] of Object.entries(overlay)) {
4203
+ const baseValue = merged[key];
4204
+ merged[key] = isPlainConfigObject(baseValue) && isPlainConfigObject(overlayValue) ? mergeConfigObjects(baseValue, overlayValue) : overlayValue;
4205
+ }
4206
+ return merged;
4207
+ }
4174
4208
  function readEnvPath(name) {
4175
4209
  const value = process.env[name];
4176
4210
  if (!value || value === "undefined") return void 0;
4177
4211
  return value;
4178
4212
  }
4179
4213
  function getAgentvConfigDir() {
4180
- return readEnvPath("AGENTV_HOME") ?? path.join(os.homedir(), ".agentv");
4214
+ return readEnvPath("AGENTV_HOME") ?? path2.join(os.homedir(), ".agentv");
4181
4215
  }
4182
4216
  function getAgentvHome() {
4183
4217
  return getAgentvConfigDir();
@@ -4186,16 +4220,16 @@ function getAgentvDataDir() {
4186
4220
  return readEnvPath("AGENTV_DATA_DIR") ?? getAgentvConfigDir();
4187
4221
  }
4188
4222
  function getWorkspacesRoot() {
4189
- return path.join(getAgentvDataDir(), "workspaces");
4223
+ return path2.join(getAgentvDataDir(), "workspaces");
4190
4224
  }
4191
4225
  function getSubagentsRoot() {
4192
- return path.join(getAgentvDataDir(), "subagents");
4226
+ return path2.join(getAgentvDataDir(), "subagents");
4193
4227
  }
4194
4228
  function getTraceStateRoot() {
4195
- return path.join(getAgentvDataDir(), "trace-state");
4229
+ return path2.join(getAgentvDataDir(), "trace-state");
4196
4230
  }
4197
4231
  function getWorkspacePoolRoot() {
4198
- return path.join(getAgentvDataDir(), "workspace-pool");
4232
+ return path2.join(getAgentvDataDir(), "workspace-pool");
4199
4233
  }
4200
4234
  async function fileExists(filePath) {
4201
4235
  try {
@@ -4217,14 +4251,14 @@ async function readJsonFile(filePath) {
4217
4251
  return JSON.parse(content);
4218
4252
  }
4219
4253
  async function findGitRoot(startPath) {
4220
- let currentDir = path2.dirname(path2.resolve(startPath));
4221
- const root = path2.parse(currentDir).root;
4254
+ let currentDir = path3.dirname(path3.resolve(startPath));
4255
+ const root = path3.parse(currentDir).root;
4222
4256
  while (currentDir !== root) {
4223
- const gitPath = path2.join(currentDir, ".git");
4257
+ const gitPath = path3.join(currentDir, ".git");
4224
4258
  if (await fileExists(gitPath)) {
4225
4259
  return currentDir;
4226
4260
  }
4227
- const parentDir = path2.dirname(currentDir);
4261
+ const parentDir = path3.dirname(currentDir);
4228
4262
  if (parentDir === currentDir) {
4229
4263
  break;
4230
4264
  }
@@ -4235,8 +4269,8 @@ async function findGitRoot(startPath) {
4235
4269
  function buildDirectoryChain(filePath, repoRoot) {
4236
4270
  const directories = [];
4237
4271
  const seen = /* @__PURE__ */ new Set();
4238
- const boundary = path2.resolve(repoRoot);
4239
- let current = path2.resolve(path2.dirname(filePath));
4272
+ const boundary = path3.resolve(repoRoot);
4273
+ let current = path3.resolve(path3.dirname(filePath));
4240
4274
  while (current !== void 0) {
4241
4275
  if (!seen.has(current)) {
4242
4276
  directories.push(current);
@@ -4245,7 +4279,7 @@ function buildDirectoryChain(filePath, repoRoot) {
4245
4279
  if (current === boundary) {
4246
4280
  break;
4247
4281
  }
4248
- const parent = path2.dirname(current);
4282
+ const parent = path3.dirname(current);
4249
4283
  if (parent === current) {
4250
4284
  break;
4251
4285
  }
@@ -4259,16 +4293,16 @@ function buildDirectoryChain(filePath, repoRoot) {
4259
4293
  function buildSearchRoots(evalPath, repoRoot) {
4260
4294
  const uniqueRoots = [];
4261
4295
  const addRoot = (root) => {
4262
- const normalized = path2.resolve(root);
4296
+ const normalized = path3.resolve(root);
4263
4297
  if (!uniqueRoots.includes(normalized)) {
4264
4298
  uniqueRoots.push(normalized);
4265
4299
  }
4266
4300
  };
4267
- let currentDir = path2.dirname(evalPath);
4301
+ let currentDir = path3.dirname(evalPath);
4268
4302
  let reachedBoundary = false;
4269
4303
  while (!reachedBoundary) {
4270
4304
  addRoot(currentDir);
4271
- const parentDir = path2.dirname(currentDir);
4305
+ const parentDir = path3.dirname(currentDir);
4272
4306
  if (currentDir === repoRoot || parentDir === currentDir) {
4273
4307
  reachedBoundary = true;
4274
4308
  } else {
@@ -4286,16 +4320,16 @@ function trimLeadingSeparators(value) {
4286
4320
  async function resolveFileReference(rawValue, searchRoots) {
4287
4321
  const displayPath = trimLeadingSeparators(rawValue);
4288
4322
  const potentialPaths = [];
4289
- if (path2.isAbsolute(rawValue)) {
4290
- potentialPaths.push(path2.normalize(rawValue));
4323
+ if (path3.isAbsolute(rawValue)) {
4324
+ potentialPaths.push(path3.normalize(rawValue));
4291
4325
  }
4292
4326
  for (const base of searchRoots) {
4293
- potentialPaths.push(path2.resolve(base, displayPath));
4327
+ potentialPaths.push(path3.resolve(base, displayPath));
4294
4328
  }
4295
4329
  const attempted = [];
4296
4330
  const seen = /* @__PURE__ */ new Set();
4297
4331
  for (const candidate of potentialPaths) {
4298
- const absoluteCandidate = path2.resolve(candidate);
4332
+ const absoluteCandidate = path3.resolve(candidate);
4299
4333
  if (seen.has(absoluteCandidate)) {
4300
4334
  continue;
4301
4335
  }
@@ -4478,11 +4512,11 @@ function normalizeCliHealthcheck(input, env, targetName, evalFilePath) {
4478
4512
  allowLiteral: true,
4479
4513
  optionalEnv: true
4480
4514
  });
4481
- if (cwd && evalFilePath && !path3.isAbsolute(cwd)) {
4482
- cwd = path3.resolve(path3.dirname(path3.resolve(evalFilePath)), cwd);
4515
+ if (cwd && evalFilePath && !path4.isAbsolute(cwd)) {
4516
+ cwd = path4.resolve(path4.dirname(path4.resolve(evalFilePath)), cwd);
4483
4517
  }
4484
4518
  if (!cwd && evalFilePath) {
4485
- cwd = path3.dirname(path3.resolve(evalFilePath));
4519
+ cwd = path4.dirname(path4.resolve(evalFilePath));
4486
4520
  }
4487
4521
  return {
4488
4522
  command,
@@ -4499,11 +4533,11 @@ function normalizeCliTargetInput(input, env, evalFilePath) {
4499
4533
  allowLiteral: true,
4500
4534
  optionalEnv: true
4501
4535
  });
4502
- if (cwd && evalFilePath && !path3.isAbsolute(cwd)) {
4503
- cwd = path3.resolve(path3.dirname(path3.resolve(evalFilePath)), cwd);
4536
+ if (cwd && evalFilePath && !path4.isAbsolute(cwd)) {
4537
+ cwd = path4.resolve(path4.dirname(path4.resolve(evalFilePath)), cwd);
4504
4538
  }
4505
4539
  if (!cwd && evalFilePath) {
4506
- cwd = path3.dirname(path3.resolve(evalFilePath));
4540
+ cwd = path4.dirname(path4.resolve(evalFilePath));
4507
4541
  }
4508
4542
  const timeoutSeconds = input.timeout_seconds;
4509
4543
  const timeoutMs = timeoutSeconds !== void 0 ? Math.floor(timeoutSeconds * 1e3) : void 0;
@@ -5643,7 +5677,7 @@ function resolveClaudeConfig(target, env, _evalFilePath) {
5643
5677
  };
5644
5678
  }
5645
5679
  function resolveCcMirrorBinaryPath(variant) {
5646
- const variantJsonPath = path3.join(homedir(), ".cc-mirror", variant, "variant.json");
5680
+ const variantJsonPath = path4.join(homedir(), ".cc-mirror", variant, "variant.json");
5647
5681
  if (!existsSync(variantJsonPath)) {
5648
5682
  throw new Error(
5649
5683
  `cc-mirror variant "${variant}": ${variantJsonPath} not found. Install the variant or set "executable" explicitly.`
@@ -5729,7 +5763,7 @@ function resolveReplayConfig(target, env, evalFilePath) {
5729
5763
  };
5730
5764
  }
5731
5765
  function resolveReplaySourcePath(sourcePath, evalFilePath) {
5732
- return evalFilePath && !path3.isAbsolute(sourcePath) ? path3.resolve(path3.dirname(path3.resolve(evalFilePath)), sourcePath) : path3.resolve(sourcePath);
5766
+ return evalFilePath && !path4.isAbsolute(sourcePath) ? path4.resolve(path4.dirname(path4.resolve(evalFilePath)), sourcePath) : path4.resolve(sourcePath);
5733
5767
  }
5734
5768
  function resolveVSCodeConfig(target, env, insiders, _evalFilePath) {
5735
5769
  const executableSource = target.executable;
@@ -5770,8 +5804,8 @@ function resolveCliConfig(target, env, evalFilePath) {
5770
5804
  const parseResult = CliTargetInputSchema.safeParse(target, { errorMap: cliErrorMap });
5771
5805
  if (!parseResult.success) {
5772
5806
  const firstError = parseResult.error.errors[0];
5773
- const path53 = firstError?.path.join(".") || "";
5774
- const prefix = path53 ? `${target.name} ${path53}: ` : `${target.name}: `;
5807
+ const path83 = firstError?.path.join(".") || "";
5808
+ const prefix = path83 ? `${target.name} ${path83}: ` : `${target.name}: `;
5775
5809
  throw new Error(`${prefix}${firstError?.message}`);
5776
5810
  }
5777
5811
  const normalized = normalizeCliTargetInput(parseResult.data, env, evalFilePath);
@@ -5792,11 +5826,11 @@ function resolveDiscoveredProviderConfig(target, providerKind, env, evalFilePath
5792
5826
  allowLiteral: true,
5793
5827
  optionalEnv: true
5794
5828
  });
5795
- if (cwd && evalFilePath && !path3.isAbsolute(cwd)) {
5796
- cwd = path3.resolve(path3.dirname(path3.resolve(evalFilePath)), cwd);
5829
+ if (cwd && evalFilePath && !path4.isAbsolute(cwd)) {
5830
+ cwd = path4.resolve(path4.dirname(path4.resolve(evalFilePath)), cwd);
5797
5831
  }
5798
5832
  if (!cwd && evalFilePath) {
5799
- cwd = path3.dirname(path3.resolve(evalFilePath));
5833
+ cwd = path4.dirname(path4.resolve(evalFilePath));
5800
5834
  }
5801
5835
  return {
5802
5836
  command,
@@ -6150,7 +6184,7 @@ function parseJsonlCases(content, filePath) {
6150
6184
  return results;
6151
6185
  }
6152
6186
  async function loadCasesFromFile(filePath) {
6153
- const ext = path4.extname(filePath).toLowerCase();
6187
+ const ext = path5.extname(filePath).toLowerCase();
6154
6188
  let content;
6155
6189
  try {
6156
6190
  content = await readFile2(filePath, "utf8");
@@ -6177,7 +6211,7 @@ async function loadCasesFromFile(filePath) {
6177
6211
  }
6178
6212
  async function resolveFileReference2(ref, evalFileDir) {
6179
6213
  const rawPath = extractFilePath(ref);
6180
- const absolutePattern = path4.resolve(evalFileDir, rawPath);
6214
+ const absolutePattern = path5.resolve(evalFileDir, rawPath);
6181
6215
  if (isGlobPattern(rawPath)) {
6182
6216
  const matches = await fg(absolutePattern.replaceAll("\\", "/"), {
6183
6217
  onlyFiles: true,
@@ -6204,10 +6238,10 @@ async function loadCasesFromDirectory(dirPath) {
6204
6238
  const subdirs = entries.filter((e) => e.isDirectory()).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
6205
6239
  const results = [];
6206
6240
  for (const subdir of subdirs) {
6207
- const subdirPath = path4.join(dirPath, subdir.name);
6241
+ const subdirPath = path5.join(dirPath, subdir.name);
6208
6242
  let caseFilePath;
6209
6243
  for (const filename of ["case.yaml", "case.yml"]) {
6210
- const candidate = path4.join(subdirPath, filename);
6244
+ const candidate = path5.join(subdirPath, filename);
6211
6245
  try {
6212
6246
  const s = await stat(candidate);
6213
6247
  if (s.isFile()) {
@@ -6243,7 +6277,7 @@ async function loadCasesFromDirectory(dirPath) {
6243
6277
  caseObj.id = subdir.name;
6244
6278
  }
6245
6279
  if (!caseObj.workspace) {
6246
- const workspaceDirPath = path4.join(subdirPath, "workspace");
6280
+ const workspaceDirPath = path5.join(subdirPath, "workspace");
6247
6281
  try {
6248
6282
  const s = await stat(workspaceDirPath);
6249
6283
  if (s.isDirectory()) {
@@ -6268,18 +6302,172 @@ async function expandFileReferences(tests, evalFileDir) {
6268
6302
  }
6269
6303
  return expanded;
6270
6304
  }
6305
+ async function fileExists2(absolutePath) {
6306
+ try {
6307
+ await access2(absolutePath, constants2.F_OK);
6308
+ return true;
6309
+ } catch {
6310
+ return false;
6311
+ }
6312
+ }
6313
+ function resolveToAbsolutePath(candidate) {
6314
+ if (candidate instanceof URL) {
6315
+ return candidate.protocol === "file:" ? fileURLToPath(candidate) : candidate.pathname;
6316
+ }
6317
+ if (typeof candidate === "string") {
6318
+ if (candidate.startsWith("file:")) {
6319
+ return fileURLToPath(candidate);
6320
+ }
6321
+ return path6.resolve(candidate);
6322
+ }
6323
+ throw new TypeError("Unsupported repoRoot value. Expected string or URL.");
6324
+ }
6325
+ function buildDirectoryChain2(filePath, repoRoot) {
6326
+ const directories = [];
6327
+ const seen = /* @__PURE__ */ new Set();
6328
+ const boundary = path6.resolve(repoRoot);
6329
+ let current = path6.resolve(path6.dirname(filePath));
6330
+ while (current !== void 0) {
6331
+ if (!seen.has(current)) {
6332
+ directories.push(current);
6333
+ seen.add(current);
6334
+ }
6335
+ if (current === boundary) {
6336
+ break;
6337
+ }
6338
+ const parent = path6.dirname(current);
6339
+ if (parent === current) {
6340
+ break;
6341
+ }
6342
+ current = parent;
6343
+ }
6344
+ if (!seen.has(boundary)) {
6345
+ directories.push(boundary);
6346
+ }
6347
+ return directories;
6348
+ }
6349
+ function buildSearchRoots2(evalPath, repoRoot) {
6350
+ const uniqueRoots = [];
6351
+ const addRoot = (root) => {
6352
+ const normalized = path6.resolve(root);
6353
+ if (!uniqueRoots.includes(normalized)) {
6354
+ uniqueRoots.push(normalized);
6355
+ }
6356
+ };
6357
+ let currentDir = path6.dirname(evalPath);
6358
+ let reachedBoundary = false;
6359
+ while (!reachedBoundary) {
6360
+ addRoot(currentDir);
6361
+ const parentDir = path6.dirname(currentDir);
6362
+ if (currentDir === repoRoot || parentDir === currentDir) {
6363
+ reachedBoundary = true;
6364
+ } else {
6365
+ currentDir = parentDir;
6366
+ }
6367
+ }
6368
+ addRoot(repoRoot);
6369
+ addRoot(process.cwd());
6370
+ return uniqueRoots;
6371
+ }
6372
+ function trimLeadingSeparators2(value) {
6373
+ const trimmed = value.replace(/^[/\\]+/, "");
6374
+ return trimmed.length > 0 ? trimmed : value;
6375
+ }
6376
+ async function resolveFileReference3(rawValue, searchRoots) {
6377
+ const displayPath = trimLeadingSeparators2(rawValue);
6378
+ const potentialPaths = [];
6379
+ if (path6.isAbsolute(rawValue)) {
6380
+ potentialPaths.push(path6.normalize(rawValue));
6381
+ }
6382
+ for (const base of searchRoots) {
6383
+ potentialPaths.push(path6.resolve(base, displayPath));
6384
+ }
6385
+ const attempted = [];
6386
+ const seen = /* @__PURE__ */ new Set();
6387
+ for (const candidate of potentialPaths) {
6388
+ const absoluteCandidate = path6.resolve(candidate);
6389
+ if (seen.has(absoluteCandidate)) {
6390
+ continue;
6391
+ }
6392
+ seen.add(absoluteCandidate);
6393
+ attempted.push(absoluteCandidate);
6394
+ if (await fileExists2(absoluteCandidate)) {
6395
+ return { displayPath, resolvedPath: absoluteCandidate, attempted };
6396
+ }
6397
+ }
6398
+ return { displayPath, attempted };
6399
+ }
6400
+ var PROMPT_MD_FILENAME = "PROMPT.md";
6401
+ function asStringArray(value) {
6402
+ if (!Array.isArray(value)) {
6403
+ return void 0;
6404
+ }
6405
+ return value.filter((entry) => typeof entry === "string");
6406
+ }
6407
+ function basenameForPortablePath(value) {
6408
+ return value.split(/[\\/]/).at(-1) ?? value;
6409
+ }
6410
+ function isPromptMdPath(value) {
6411
+ return basenameForPortablePath(value) === PROMPT_MD_FILENAME;
6412
+ }
6413
+ function splitInputFiles(value) {
6414
+ const files = asStringArray(value);
6415
+ if (!files) {
6416
+ return {};
6417
+ }
6418
+ const promptFile = files.find(isPromptMdPath);
6419
+ const remaining = promptFile ? files.filter((file2) => !isPromptMdPath(file2)) : files;
6420
+ return {
6421
+ files,
6422
+ ...promptFile ? { promptFile } : {},
6423
+ ...remaining.length > 0 ? { remainingInputFiles: remaining } : {}
6424
+ };
6425
+ }
6426
+ async function readPromptFile(promptPath) {
6427
+ return (await readFile3(promptPath, "utf8")).replace(/\r\n/g, "\n");
6428
+ }
6429
+ async function loadPromptMdFallback(options) {
6430
+ const testSplit = splitInputFiles(options.testInputFiles);
6431
+ const suiteSplit = splitInputFiles(options.suiteInputFiles);
6432
+ const inputFilesSource = testSplit.files ? "test" : suiteSplit.files ? "suite" : void 0;
6433
+ const activeSplit = inputFilesSource === "test" ? testSplit : suiteSplit;
6434
+ if (activeSplit.promptFile) {
6435
+ const resolved = await resolveFileReference3(activeSplit.promptFile, options.searchRoots);
6436
+ if (resolved.resolvedPath) {
6437
+ return {
6438
+ promptText: await readPromptFile(resolved.resolvedPath),
6439
+ promptPath: path7.resolve(resolved.resolvedPath),
6440
+ source: "input_files",
6441
+ ...inputFilesSource ? { inputFilesSource } : {},
6442
+ ...activeSplit.remainingInputFiles ? { remainingInputFiles: activeSplit.remainingInputFiles } : {}
6443
+ };
6444
+ }
6445
+ }
6446
+ const siblingPromptPath = path7.join(
6447
+ path7.dirname(path7.resolve(options.evalFilePath)),
6448
+ PROMPT_MD_FILENAME
6449
+ );
6450
+ if (await fileExists2(siblingPromptPath)) {
6451
+ return {
6452
+ promptText: await readPromptFile(siblingPromptPath),
6453
+ promptPath: siblingPromptPath,
6454
+ source: "sibling"
6455
+ };
6456
+ }
6457
+ return void 0;
6458
+ }
6271
6459
 
6272
- // ../../packages/core/dist/chunk-BPMHQXAX.js
6273
- import path51 from "node:path";
6460
+ // ../../packages/core/dist/chunk-ZAXCSMNE.js
6461
+ import path50 from "node:path";
6274
6462
  import { pathToFileURL as pathToFileURL2 } from "node:url";
6275
6463
  import { existsSync as existsSync7 } from "node:fs";
6276
- import path50 from "node:path";
6464
+ import path49 from "node:path";
6277
6465
  import micromatch4 from "micromatch";
6278
- import { mkdir, readFile as readFile3, writeFile } from "node:fs/promises";
6279
- import path5 from "node:path";
6466
+ import { mkdir, readFile as readFile4, writeFile } from "node:fs/promises";
6467
+ import path8 from "node:path";
6280
6468
  import { createHash as createHash6, randomUUID as randomUUID10 } from "node:crypto";
6281
- import path48 from "node:path";
6282
- import { fileURLToPath as fileURLToPath5 } from "node:url";
6469
+ import path47 from "node:path";
6470
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
6283
6471
  import micromatch3 from "micromatch";
6284
6472
  import { mkdtemp, rm, writeFile as writeFile2 } from "node:fs/promises";
6285
6473
  import { tmpdir } from "node:os";
@@ -6290,22 +6478,22 @@ import fs from "node:fs/promises";
6290
6478
  import path32 from "node:path";
6291
6479
  import { readFile as readFile22 } from "node:fs/promises";
6292
6480
  import path22 from "node:path";
6293
- import { fileURLToPath } from "node:url";
6481
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
6294
6482
  import { spawn } from "node:child_process";
6295
6483
  import { randomUUID } from "node:crypto";
6296
6484
  import { createWriteStream } from "node:fs";
6297
6485
  import { mkdir as mkdir2 } from "node:fs/promises";
6298
- import path6 from "node:path";
6486
+ import path62 from "node:path";
6299
6487
  import path42 from "node:path";
6300
6488
  import path52 from "node:path";
6301
6489
  import { randomUUID as randomUUID2 } from "node:crypto";
6302
6490
  import { createWriteStream as createWriteStream2 } from "node:fs";
6303
6491
  import { mkdir as mkdir3 } from "node:fs/promises";
6304
- import path7 from "node:path";
6492
+ import path72 from "node:path";
6305
6493
  import { exec as execWithCallback } from "node:child_process";
6306
6494
  import fs2 from "node:fs/promises";
6307
6495
  import os2 from "node:os";
6308
- import path8 from "node:path";
6496
+ import path82 from "node:path";
6309
6497
  import { promisify } from "node:util";
6310
6498
  import { randomUUID as randomUUID3 } from "node:crypto";
6311
6499
  import { createWriteStream as createWriteStream3 } from "node:fs";
@@ -6998,10 +7186,10 @@ function assignProp(target, prop, value) {
6998
7186
  configurable: true
6999
7187
  });
7000
7188
  }
7001
- function getElementAtPath(obj, path53) {
7002
- if (!path53)
7189
+ function getElementAtPath(obj, path51) {
7190
+ if (!path51)
7003
7191
  return obj;
7004
- return path53.reduce((acc, key) => acc?.[key], obj);
7192
+ return path51.reduce((acc, key) => acc?.[key], obj);
7005
7193
  }
7006
7194
  function promiseAllObject(promisesObj) {
7007
7195
  const keys = Object.keys(promisesObj);
@@ -7321,11 +7509,11 @@ function aborted(x, startIndex = 0) {
7321
7509
  }
7322
7510
  return false;
7323
7511
  }
7324
- function prefixIssues(path53, issues) {
7512
+ function prefixIssues(path51, issues) {
7325
7513
  return issues.map((iss) => {
7326
7514
  var _a;
7327
7515
  (_a = iss).path ?? (_a.path = []);
7328
- iss.path.unshift(path53);
7516
+ iss.path.unshift(path51);
7329
7517
  return iss;
7330
7518
  });
7331
7519
  }
@@ -7462,7 +7650,7 @@ function treeifyError(error40, _mapper) {
7462
7650
  return issue2.message;
7463
7651
  };
7464
7652
  const result = { errors: [] };
7465
- const processError = (error41, path53 = []) => {
7653
+ const processError = (error41, path51 = []) => {
7466
7654
  var _a, _b;
7467
7655
  for (const issue2 of error41.issues) {
7468
7656
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -7472,7 +7660,7 @@ function treeifyError(error40, _mapper) {
7472
7660
  } else if (issue2.code === "invalid_element") {
7473
7661
  processError({ issues: issue2.issues }, issue2.path);
7474
7662
  } else {
7475
- const fullpath = [...path53, ...issue2.path];
7663
+ const fullpath = [...path51, ...issue2.path];
7476
7664
  if (fullpath.length === 0) {
7477
7665
  result.errors.push(mapper(issue2));
7478
7666
  continue;
@@ -7502,9 +7690,9 @@ function treeifyError(error40, _mapper) {
7502
7690
  processError(error40);
7503
7691
  return result;
7504
7692
  }
7505
- function toDotPath(path53) {
7693
+ function toDotPath(path51) {
7506
7694
  const segs = [];
7507
- for (const seg of path53) {
7695
+ for (const seg of path51) {
7508
7696
  if (typeof seg === "number")
7509
7697
  segs.push(`[${seg}]`);
7510
7698
  else if (typeof seg === "symbol")
@@ -18934,7 +19122,7 @@ var RequestError = class _RequestError extends Error {
18934
19122
  }
18935
19123
  };
18936
19124
 
18937
- // ../../packages/core/dist/chunk-BPMHQXAX.js
19125
+ // ../../packages/core/dist/chunk-ZAXCSMNE.js
18938
19126
  import { exec as execCallback } from "node:child_process";
18939
19127
  import { readdirSync, statSync } from "node:fs";
18940
19128
  import { readFile as readFile32, readdir as readdir2, stat as stat2 } from "node:fs/promises";
@@ -18944,11 +19132,11 @@ import { randomUUID as randomUUID4 } from "node:crypto";
18944
19132
  import { createWriteStream as createWriteStream4, existsSync as existsSync2, readdirSync as readdirSync2 } from "node:fs";
18945
19133
  import { arch, homedir as homedir3, platform } from "node:os";
18946
19134
  import path11 from "node:path";
18947
- import { fileURLToPath as fileURLToPath2 } from "node:url";
19135
+ import { fileURLToPath as fileURLToPath22 } from "node:url";
18948
19136
  import { readFile as readFile5 } from "node:fs/promises";
18949
19137
  import { homedir as homedir4 } from "node:os";
18950
19138
  import path14 from "node:path";
18951
- import { readFile as readFile4, readdir as readdir22, stat as stat22 } from "node:fs/promises";
19139
+ import { readFile as readFile42, readdir as readdir22, stat as stat22 } from "node:fs/promises";
18952
19140
  import { homedir as homedir32 } from "node:os";
18953
19141
  import path13 from "node:path";
18954
19142
  import { randomUUID as randomUUID6 } from "node:crypto";
@@ -18975,7 +19163,7 @@ import { readFile as readFile7 } from "node:fs/promises";
18975
19163
  import { createHash as createHash3 } from "node:crypto";
18976
19164
  import { createHash as createHash2 } from "node:crypto";
18977
19165
  import { exec as exec2 } from "node:child_process";
18978
- import { constants as constants2, access as access2 } from "node:fs/promises";
19166
+ import { constants as constants22, access as access22 } from "node:fs/promises";
18979
19167
  import path29 from "node:path";
18980
19168
  import { promisify as promisify4 } from "node:util";
18981
19169
  import { stat as stat5, writeFile as writeFile7 } from "node:fs/promises";
@@ -19031,28 +19219,24 @@ import { stringify as stringifyYaml } from "yaml";
19031
19219
  import { readdir as readdir7, stat as stat7 } from "node:fs/promises";
19032
19220
  import path39 from "node:path";
19033
19221
  import { readFile as readFile18, stat as stat9 } from "node:fs/promises";
19034
- import path47 from "node:path";
19222
+ import path46 from "node:path";
19035
19223
  import micromatch2 from "micromatch";
19036
19224
  import { stringify as stringifyYaml2 } from "yaml";
19037
19225
  import { readFile as readFile12 } from "node:fs/promises";
19038
19226
  import path41 from "node:path";
19039
19227
  import { readFile as readFile13 } from "node:fs/promises";
19040
- import path43 from "node:path";
19041
- import { constants as constants4 } from "node:fs";
19042
- import { access as access4 } from "node:fs/promises";
19043
19228
  import path422 from "node:path";
19044
- import { fileURLToPath as fileURLToPath4 } from "node:url";
19045
19229
  import { readFile as readFile15 } from "node:fs/promises";
19046
- import path44 from "node:path";
19230
+ import path43 from "node:path";
19047
19231
  import { readFile as readFile14 } from "node:fs/promises";
19048
19232
  import { readFile as readFile17 } from "node:fs/promises";
19049
- import path46 from "node:path";
19233
+ import path45 from "node:path";
19050
19234
  import micromatch from "micromatch";
19051
19235
  import { readFile as readFile16 } from "node:fs/promises";
19052
- import path45 from "node:path";
19236
+ import path44 from "node:path";
19053
19237
  import { createHash as createHash7 } from "node:crypto";
19054
19238
  import { copyFile as copyFile3, mkdir as mkdir18, readFile as readFile20, writeFile as writeFile10 } from "node:fs/promises";
19055
- import path49 from "node:path";
19239
+ import path48 from "node:path";
19056
19240
  import { readFile as readFile19 } from "node:fs/promises";
19057
19241
  var DEFAULT_CACHE_PATH = ".agentv/cache";
19058
19242
  var ResponseCache = class {
@@ -19063,7 +19247,7 @@ var ResponseCache = class {
19063
19247
  async get(key) {
19064
19248
  const filePath = this.keyToPath(key);
19065
19249
  try {
19066
- const data = await readFile3(filePath, "utf8");
19250
+ const data = await readFile4(filePath, "utf8");
19067
19251
  return JSON.parse(data);
19068
19252
  } catch {
19069
19253
  return void 0;
@@ -19071,13 +19255,13 @@ var ResponseCache = class {
19071
19255
  }
19072
19256
  async set(key, value) {
19073
19257
  const filePath = this.keyToPath(key);
19074
- const dir = path5.dirname(filePath);
19258
+ const dir = path8.dirname(filePath);
19075
19259
  await mkdir(dir, { recursive: true });
19076
19260
  await writeFile(filePath, JSON.stringify(value, null, 2), "utf8");
19077
19261
  }
19078
19262
  keyToPath(key) {
19079
19263
  const prefix = key.slice(0, 2);
19080
- return path5.join(this.cachePath, prefix, `${key}.json`);
19264
+ return path8.join(this.cachePath, prefix, `${key}.json`);
19081
19265
  }
19082
19266
  };
19083
19267
  function shouldEnableCache(params) {
@@ -19745,7 +19929,7 @@ var CodeGrader = class {
19745
19929
  let exitCode = 0;
19746
19930
  let execStderr = "";
19747
19931
  if (context.dockerConfig) {
19748
- const { DockerWorkspaceProvider } = await import("./docker-workspace-RPPXBT27-B4AQHVWA.js");
19932
+ const { DockerWorkspaceProvider } = await import("./docker-workspace-ZJ2ESVBI-6UDETQII.js");
19749
19933
  const dockerProvider = new DockerWorkspaceProvider(context.dockerConfig);
19750
19934
  const result = await dockerProvider.runGraderInContainer({
19751
19935
  command: [...this.command],
@@ -20020,7 +20204,7 @@ function normalizePreprocessorType(value) {
20020
20204
  }
20021
20205
  function resolveLocalFilePath(value, basePath) {
20022
20206
  if (value.startsWith("file://")) {
20023
- return fileURLToPath(value);
20207
+ return fileURLToPath2(value);
20024
20208
  }
20025
20209
  if (/^[a-z]+:\/\//i.test(value)) {
20026
20210
  return void 0;
@@ -22765,115 +22949,115 @@ var FieldAccuracyGrader = class {
22765
22949
  * Evaluate a single field against the expected value.
22766
22950
  */
22767
22951
  evaluateField(fieldConfig, candidateData, expectedData) {
22768
- const { path: path522, match, required: required2 = true, weight = 1 } = fieldConfig;
22769
- const candidateValue = resolvePath(candidateData, path522);
22770
- const expectedValue = resolvePath(expectedData, path522);
22952
+ const { path: path51, match, required: required2 = true, weight = 1 } = fieldConfig;
22953
+ const candidateValue = resolvePath(candidateData, path51);
22954
+ const expectedValue = resolvePath(expectedData, path51);
22771
22955
  if (expectedValue === void 0) {
22772
22956
  return {
22773
- path: path522,
22957
+ path: path51,
22774
22958
  score: 1,
22775
22959
  // No expected value means no comparison needed
22776
22960
  weight,
22777
22961
  hit: true,
22778
- message: `${path522}: no expected value`
22962
+ message: `${path51}: no expected value`
22779
22963
  };
22780
22964
  }
22781
22965
  if (candidateValue === void 0) {
22782
22966
  if (required2) {
22783
22967
  return {
22784
- path: path522,
22968
+ path: path51,
22785
22969
  score: 0,
22786
22970
  weight,
22787
22971
  hit: false,
22788
- message: `${path522} (required, missing)`
22972
+ message: `${path51} (required, missing)`
22789
22973
  };
22790
22974
  }
22791
22975
  return {
22792
- path: path522,
22976
+ path: path51,
22793
22977
  score: 1,
22794
22978
  // Don't penalize missing optional fields
22795
22979
  weight: 0,
22796
22980
  // Zero weight means it won't affect the score
22797
22981
  hit: true,
22798
- message: `${path522}: optional field missing`
22982
+ message: `${path51}: optional field missing`
22799
22983
  };
22800
22984
  }
22801
22985
  switch (match) {
22802
22986
  case "exact":
22803
- return this.compareExact(path522, candidateValue, expectedValue, weight);
22987
+ return this.compareExact(path51, candidateValue, expectedValue, weight);
22804
22988
  case "numeric_tolerance":
22805
22989
  return this.compareNumericTolerance(
22806
- path522,
22990
+ path51,
22807
22991
  candidateValue,
22808
22992
  expectedValue,
22809
22993
  fieldConfig,
22810
22994
  weight
22811
22995
  );
22812
22996
  case "date":
22813
- return this.compareDate(path522, candidateValue, expectedValue, fieldConfig, weight);
22997
+ return this.compareDate(path51, candidateValue, expectedValue, fieldConfig, weight);
22814
22998
  default:
22815
22999
  return {
22816
- path: path522,
23000
+ path: path51,
22817
23001
  score: 0,
22818
23002
  weight,
22819
23003
  hit: false,
22820
- message: `${path522}: unknown match type "${match}"`
23004
+ message: `${path51}: unknown match type "${match}"`
22821
23005
  };
22822
23006
  }
22823
23007
  }
22824
23008
  /**
22825
23009
  * Exact equality comparison.
22826
23010
  */
22827
- compareExact(path522, candidateValue, expectedValue, weight) {
23011
+ compareExact(path51, candidateValue, expectedValue, weight) {
22828
23012
  if (deepEqual(candidateValue, expectedValue)) {
22829
23013
  return {
22830
- path: path522,
23014
+ path: path51,
22831
23015
  score: 1,
22832
23016
  weight,
22833
23017
  hit: true,
22834
- message: path522
23018
+ message: path51
22835
23019
  };
22836
23020
  }
22837
23021
  if (typeof candidateValue !== typeof expectedValue) {
22838
23022
  return {
22839
- path: path522,
23023
+ path: path51,
22840
23024
  score: 0,
22841
23025
  weight,
22842
23026
  hit: false,
22843
- message: `${path522} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
23027
+ message: `${path51} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
22844
23028
  };
22845
23029
  }
22846
23030
  return {
22847
- path: path522,
23031
+ path: path51,
22848
23032
  score: 0,
22849
23033
  weight,
22850
23034
  hit: false,
22851
- message: `${path522} (value mismatch)`
23035
+ message: `${path51} (value mismatch)`
22852
23036
  };
22853
23037
  }
22854
23038
  /**
22855
23039
  * Numeric comparison with absolute or relative tolerance.
22856
23040
  */
22857
- compareNumericTolerance(path522, candidateValue, expectedValue, fieldConfig, weight) {
23041
+ compareNumericTolerance(path51, candidateValue, expectedValue, fieldConfig, weight) {
22858
23042
  const { tolerance = 0, relative = false } = fieldConfig;
22859
23043
  const candidateNum = toNumber(candidateValue);
22860
23044
  const expectedNum = toNumber(expectedValue);
22861
23045
  if (candidateNum === null || expectedNum === null) {
22862
23046
  return {
22863
- path: path522,
23047
+ path: path51,
22864
23048
  score: 0,
22865
23049
  weight,
22866
23050
  hit: false,
22867
- message: `${path522} (non-numeric value)`
23051
+ message: `${path51} (non-numeric value)`
22868
23052
  };
22869
23053
  }
22870
23054
  if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
22871
23055
  return {
22872
- path: path522,
23056
+ path: path51,
22873
23057
  score: 0,
22874
23058
  weight,
22875
23059
  hit: false,
22876
- message: `${path522} (invalid numeric value)`
23060
+ message: `${path51} (invalid numeric value)`
22877
23061
  };
22878
23062
  }
22879
23063
  const diff = Math.abs(candidateNum - expectedNum);
@@ -22886,61 +23070,61 @@ var FieldAccuracyGrader = class {
22886
23070
  }
22887
23071
  if (withinTolerance) {
22888
23072
  return {
22889
- path: path522,
23073
+ path: path51,
22890
23074
  score: 1,
22891
23075
  weight,
22892
23076
  hit: true,
22893
- message: `${path522} (within tolerance: diff=${diff.toFixed(2)})`
23077
+ message: `${path51} (within tolerance: diff=${diff.toFixed(2)})`
22894
23078
  };
22895
23079
  }
22896
23080
  return {
22897
- path: path522,
23081
+ path: path51,
22898
23082
  score: 0,
22899
23083
  weight,
22900
23084
  hit: false,
22901
- message: `${path522} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
23085
+ message: `${path51} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
22902
23086
  };
22903
23087
  }
22904
23088
  /**
22905
23089
  * Date comparison with format normalization.
22906
23090
  */
22907
- compareDate(path522, candidateValue, expectedValue, fieldConfig, weight) {
23091
+ compareDate(path51, candidateValue, expectedValue, fieldConfig, weight) {
22908
23092
  const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
22909
23093
  const candidateDate = parseDate(String(candidateValue), formats);
22910
23094
  const expectedDate = parseDate(String(expectedValue), formats);
22911
23095
  if (candidateDate === null) {
22912
23096
  return {
22913
- path: path522,
23097
+ path: path51,
22914
23098
  score: 0,
22915
23099
  weight,
22916
23100
  hit: false,
22917
- message: `${path522} (unparseable candidate date)`
23101
+ message: `${path51} (unparseable candidate date)`
22918
23102
  };
22919
23103
  }
22920
23104
  if (expectedDate === null) {
22921
23105
  return {
22922
- path: path522,
23106
+ path: path51,
22923
23107
  score: 0,
22924
23108
  weight,
22925
23109
  hit: false,
22926
- message: `${path522} (unparseable expected date)`
23110
+ message: `${path51} (unparseable expected date)`
22927
23111
  };
22928
23112
  }
22929
23113
  if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
22930
23114
  return {
22931
- path: path522,
23115
+ path: path51,
22932
23116
  score: 1,
22933
23117
  weight,
22934
23118
  hit: true,
22935
- message: path522
23119
+ message: path51
22936
23120
  };
22937
23121
  }
22938
23122
  return {
22939
- path: path522,
23123
+ path: path51,
22940
23124
  score: 0,
22941
23125
  weight,
22942
23126
  hit: false,
22943
- message: `${path522} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
23127
+ message: `${path51} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
22944
23128
  };
22945
23129
  }
22946
23130
  /**
@@ -22973,11 +23157,11 @@ var FieldAccuracyGrader = class {
22973
23157
  };
22974
23158
  }
22975
23159
  };
22976
- function resolvePath(obj, path522) {
22977
- if (!path522 || !obj) {
23160
+ function resolvePath(obj, path51) {
23161
+ if (!path51 || !obj) {
22978
23162
  return void 0;
22979
23163
  }
22980
- const parts = path522.split(/\.|\[|\]/).filter((p) => p.length > 0);
23164
+ const parts = path51.split(/\.|\[|\]/).filter((p) => p.length > 0);
22981
23165
  let current = obj;
22982
23166
  for (const part of parts) {
22983
23167
  if (current === null || current === void 0) {
@@ -23508,8 +23692,8 @@ var TokenUsageGrader = class {
23508
23692
  };
23509
23693
  }
23510
23694
  };
23511
- function getNestedValue(obj, path522) {
23512
- const parts = path522.split(".");
23695
+ function getNestedValue(obj, path51) {
23696
+ const parts = path51.split(".");
23513
23697
  let current = obj;
23514
23698
  for (const part of parts) {
23515
23699
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -24610,10 +24794,10 @@ var ClaudeCliProvider = class {
24610
24794
  }
24611
24795
  resolveCwd(cwdOverride) {
24612
24796
  if (cwdOverride) {
24613
- return path6.resolve(cwdOverride);
24797
+ return path62.resolve(cwdOverride);
24614
24798
  }
24615
24799
  if (this.config.cwd) {
24616
- return path6.resolve(this.config.cwd);
24800
+ return path62.resolve(this.config.cwd);
24617
24801
  }
24618
24802
  return void 0;
24619
24803
  }
@@ -24623,7 +24807,7 @@ var ClaudeCliProvider = class {
24623
24807
  return void 0;
24624
24808
  }
24625
24809
  if (this.config.logDir) {
24626
- return path6.resolve(this.config.logDir);
24810
+ return path62.resolve(this.config.logDir);
24627
24811
  }
24628
24812
  return resolveDefaultProviderLogDir("claude-cli", request);
24629
24813
  }
@@ -24639,7 +24823,7 @@ var ClaudeCliProvider = class {
24639
24823
  console.warn(`Skipping Claude CLI stream logging (could not create ${logDir}): ${message}`);
24640
24824
  return void 0;
24641
24825
  }
24642
- const filePath = path6.join(logDir, buildLogFilename(request, this.targetName));
24826
+ const filePath = path62.join(logDir, buildLogFilename(request, this.targetName));
24643
24827
  try {
24644
24828
  const logger = await ClaudeCliStreamLogger.create({
24645
24829
  filePath,
@@ -25099,10 +25283,10 @@ var ClaudeSdkProvider = class {
25099
25283
  }
25100
25284
  resolveCwd(cwdOverride) {
25101
25285
  if (cwdOverride) {
25102
- return path7.resolve(cwdOverride);
25286
+ return path72.resolve(cwdOverride);
25103
25287
  }
25104
25288
  if (this.config.cwd) {
25105
- return path7.resolve(this.config.cwd);
25289
+ return path72.resolve(this.config.cwd);
25106
25290
  }
25107
25291
  return void 0;
25108
25292
  }
@@ -25112,7 +25296,7 @@ var ClaudeSdkProvider = class {
25112
25296
  return void 0;
25113
25297
  }
25114
25298
  if (this.config.logDir) {
25115
- return path7.resolve(this.config.logDir);
25299
+ return path72.resolve(this.config.logDir);
25116
25300
  }
25117
25301
  return resolveDefaultProviderLogDir("claude", request);
25118
25302
  }
@@ -25128,7 +25312,7 @@ var ClaudeSdkProvider = class {
25128
25312
  console.warn(`Skipping Claude stream logging (could not create ${logDir}): ${message}`);
25129
25313
  return void 0;
25130
25314
  }
25131
- const filePath = path7.join(logDir, buildLogFilename2(request, this.targetName));
25315
+ const filePath = path72.join(logDir, buildLogFilename2(request, this.targetName));
25132
25316
  try {
25133
25317
  const logger = await ClaudeStreamLogger.create({
25134
25318
  filePath,
@@ -25815,7 +25999,7 @@ function normalizeInputFiles2(inputFiles) {
25815
25999
  }
25816
26000
  const unique = /* @__PURE__ */ new Map();
25817
26001
  for (const inputFile of inputFiles) {
25818
- const absolutePath = path8.resolve(inputFile);
26002
+ const absolutePath = path82.resolve(inputFile);
25819
26003
  if (!unique.has(absolutePath)) {
25820
26004
  unique.set(absolutePath, absolutePath);
25821
26005
  }
@@ -25829,7 +26013,7 @@ function formatFileList(files, template) {
25829
26013
  const formatter = template ?? "{path}";
25830
26014
  return files.map((filePath) => {
25831
26015
  const escapedPath = shellEscape(filePath);
25832
- const escapedName = shellEscape(path8.basename(filePath));
26016
+ const escapedName = shellEscape(path82.basename(filePath));
25833
26017
  return formatter.replaceAll("{path}", escapedPath).replaceAll("{basename}", escapedName);
25834
26018
  }).join(" ");
25835
26019
  }
@@ -25853,7 +26037,7 @@ function generateOutputFilePath(evalCaseId, extension = ".json") {
25853
26037
  const safeEvalId = evalCaseId || "unknown";
25854
26038
  const timestamp = Date.now();
25855
26039
  const random = Math.random().toString(36).substring(2, 9);
25856
- return path8.join(os2.tmpdir(), `agentv-${safeEvalId}-${timestamp}-${random}${extension}`);
26040
+ return path82.join(os2.tmpdir(), `agentv-${safeEvalId}-${timestamp}-${random}${extension}`);
25857
26041
  }
25858
26042
  function formatTimeoutSuffix2(timeoutMs) {
25859
26043
  if (!timeoutMs || timeoutMs <= 0) {
@@ -26489,7 +26673,7 @@ function resolvePlatformCliPath() {
26489
26673
  const binaryName = os22 === "win32" ? "copilot.exe" : "copilot";
26490
26674
  try {
26491
26675
  const resolved = import.meta.resolve(`${packageName}/package.json`);
26492
- const packageJsonPath = resolved.startsWith("file:") ? fileURLToPath2(resolved) : resolved;
26676
+ const packageJsonPath = resolved.startsWith("file:") ? fileURLToPath22(resolved) : resolved;
26493
26677
  const binaryPath = path11.join(path11.dirname(packageJsonPath), binaryName);
26494
26678
  if (existsSync2(binaryPath)) {
26495
26679
  return binaryPath;
@@ -27471,7 +27655,7 @@ async function discoverCopilotSessions(opts) {
27471
27655
  const workspacePath = path13.join(sessionDir, "workspace.yaml");
27472
27656
  const eventsPath = path13.join(sessionDir, "events.jsonl");
27473
27657
  try {
27474
- const workspaceContent = await readFile4(workspacePath, "utf8");
27658
+ const workspaceContent = await readFile42(workspacePath, "utf8");
27475
27659
  const workspace = parseYamlValue(workspaceContent) ?? {};
27476
27660
  const cwd = String(workspace.cwd ?? "");
27477
27661
  let updatedAt;
@@ -33325,7 +33509,7 @@ async function locateVSCodeExecutable(candidate) {
33325
33509
  if (includesPathSeparator) {
33326
33510
  const resolved = path29.isAbsolute(candidate) ? candidate : path29.resolve(candidate);
33327
33511
  try {
33328
- await access2(resolved, constants2.F_OK);
33512
+ await access22(resolved, constants22.F_OK);
33329
33513
  return resolved;
33330
33514
  } catch {
33331
33515
  throw new Error(
@@ -33338,7 +33522,7 @@ async function locateVSCodeExecutable(candidate) {
33338
33522
  const { stdout } = await execAsync4(`${locator} ${candidate}`);
33339
33523
  const lines = stdout.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
33340
33524
  if (lines.length > 0 && lines[0]) {
33341
- await access2(lines[0], constants2.F_OK);
33525
+ await access22(lines[0], constants22.F_OK);
33342
33526
  return lines[0];
33343
33527
  }
33344
33528
  } catch {
@@ -33490,7 +33674,7 @@ function assertTargetDefinition(value, index, filePath) {
33490
33674
  }
33491
33675
  return value;
33492
33676
  }
33493
- async function fileExists2(filePath) {
33677
+ async function fileExists3(filePath) {
33494
33678
  try {
33495
33679
  await access32(filePath, constants32.F_OK);
33496
33680
  return true;
@@ -33500,7 +33684,7 @@ async function fileExists2(filePath) {
33500
33684
  }
33501
33685
  async function readTargetDefinitions(filePath) {
33502
33686
  const absolutePath = path30.resolve(filePath);
33503
- if (!await fileExists2(absolutePath)) {
33687
+ if (!await fileExists3(absolutePath)) {
33504
33688
  throw new Error(`targets.yaml not found at ${absolutePath}`);
33505
33689
  }
33506
33690
  const raw = await readFile10(absolutePath, "utf8");
@@ -34595,13 +34779,23 @@ var WorkspacePoolManager = class {
34595
34779
  }
34596
34780
  };
34597
34781
  function getProjectsRegistryPath() {
34598
- return path37.join(getAgentvConfigDir(), "config.yaml");
34782
+ return path37.join(getAgentvConfigDir(), AGENTV_CONFIG_FILE_NAME);
34599
34783
  }
34600
34784
  function readTrimmedString(value) {
34601
34785
  if (typeof value !== "string") return void 0;
34602
34786
  const trimmed = value.trim();
34603
34787
  return trimmed.length > 0 ? trimmed : void 0;
34604
34788
  }
34789
+ var warnedRemovedBackupAndForcePushPolicy = false;
34790
+ function warnRemovedBackupAndForcePushPolicy() {
34791
+ if (warnedRemovedBackupAndForcePushPolicy) {
34792
+ return;
34793
+ }
34794
+ warnedRemovedBackupAndForcePushPolicy = true;
34795
+ console.warn(
34796
+ "[agentv] projects[].results.sync.push_conflict_policy: 'backup_and_force_push' is no longer supported and was ignored while loading the project registry. Remove the field or set it to 'block'; AgentV never force-pushes result branches."
34797
+ );
34798
+ }
34605
34799
  function fromYaml(raw) {
34606
34800
  if (!raw || typeof raw !== "object") return null;
34607
34801
  const e = raw;
@@ -34645,11 +34839,14 @@ function fromYaml(raw) {
34645
34839
  sync: {
34646
34840
  ...typeof sync.auto_push === "boolean" ? { autoPush: sync.auto_push } : {},
34647
34841
  ...typeof sync.require_push === "boolean" ? { requirePush: sync.require_push } : {},
34648
- ...sync.push_conflict_policy === "block" || sync.push_conflict_policy === "backup_and_force_push" ? { pushConflictPolicy: sync.push_conflict_policy } : {}
34842
+ ...sync.push_conflict_policy === "block" ? { pushConflictPolicy: sync.push_conflict_policy } : {}
34649
34843
  }
34650
34844
  } : {},
34651
34845
  ...typeof r.branch_prefix === "string" && r.branch_prefix.trim().length > 0 ? { branchPrefix: r.branch_prefix.trim() } : {}
34652
34846
  };
34847
+ if (sync?.push_conflict_policy === "backup_and_force_push") {
34848
+ warnRemovedBackupAndForcePushPolicy();
34849
+ }
34653
34850
  }
34654
34851
  }
34655
34852
  return entry;
@@ -34711,12 +34908,12 @@ function toYaml(entry) {
34711
34908
  }
34712
34909
  function loadProjectRegistry() {
34713
34910
  const registryPath = getProjectsRegistryPath();
34714
- if (!existsSync4(registryPath)) {
34911
+ const localRegistryPath = getLocalConfigPath(registryPath);
34912
+ if (!existsSync4(registryPath) && !existsSync4(localRegistryPath)) {
34715
34913
  return { projects: [] };
34716
34914
  }
34717
34915
  try {
34718
- const raw = readFileSync22(registryPath, "utf-8");
34719
- const parsed = parseYamlValue(raw);
34916
+ const parsed = readMergedHomeConfig(registryPath);
34720
34917
  if (!parsed || typeof parsed !== "object") {
34721
34918
  return { projects: [] };
34722
34919
  }
@@ -34728,7 +34925,7 @@ function loadProjectRegistry() {
34728
34925
  }
34729
34926
  }
34730
34927
  function saveProjectRegistry(registry2) {
34731
- const registryPath = getProjectsRegistryPath();
34928
+ const registryPath = getProjectsRegistryWritePath();
34732
34929
  const dir = path37.dirname(registryPath);
34733
34930
  if (!existsSync4(dir)) {
34734
34931
  mkdirSync2(dir, { recursive: true });
@@ -34745,6 +34942,17 @@ function readHomeConfig(configPath2) {
34745
34942
  return {};
34746
34943
  }
34747
34944
  }
34945
+ function readMergedHomeConfig(configPath2) {
34946
+ const base = readHomeConfig(configPath2);
34947
+ const local = readHomeConfig(getLocalConfigPath(configPath2));
34948
+ return Object.keys(base).length > 0 && Object.keys(local).length > 0 ? mergeConfigObjects(base, local) : Object.keys(local).length > 0 ? local : base;
34949
+ }
34950
+ function getProjectsRegistryWritePath() {
34951
+ const registryPath = getProjectsRegistryPath();
34952
+ const localRegistryPath = getLocalConfigPath(registryPath);
34953
+ const localConfig = readHomeConfig(localRegistryPath);
34954
+ return Object.prototype.hasOwnProperty.call(localConfig, "projects") ? localRegistryPath : registryPath;
34955
+ }
34748
34956
  function deriveProjectId(dirPath, existingIds) {
34749
34957
  const base = path37.basename(dirPath).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
34750
34958
  let candidate = base || "project";
@@ -35688,7 +35896,7 @@ async function prepareSharedWorkspaceSetup(options) {
35688
35896
  const suiteDockerConfig = suiteWorkspace?.docker;
35689
35897
  if (suiteDockerConfig) {
35690
35898
  setupLog(`pulling Docker image: ${suiteDockerConfig.image}`);
35691
- const { DockerWorkspaceProvider } = await import("./docker-workspace-RPPXBT27-B4AQHVWA.js");
35899
+ const { DockerWorkspaceProvider } = await import("./docker-workspace-ZJ2ESVBI-6UDETQII.js");
35692
35900
  const dockerSetup = new DockerWorkspaceProvider(suiteDockerConfig);
35693
35901
  if (!await dockerSetup.isDockerAvailable()) {
35694
35902
  throw new Error(
@@ -36448,101 +36656,6 @@ function parseAgentSkillsEvals(parsed, source = "evals.json", baseDir) {
36448
36656
  }
36449
36657
  return tests;
36450
36658
  }
36451
- async function fileExists3(absolutePath) {
36452
- try {
36453
- await access4(absolutePath, constants4.F_OK);
36454
- return true;
36455
- } catch {
36456
- return false;
36457
- }
36458
- }
36459
- function resolveToAbsolutePath(candidate) {
36460
- if (candidate instanceof URL) {
36461
- return candidate.protocol === "file:" ? fileURLToPath4(candidate) : candidate.pathname;
36462
- }
36463
- if (typeof candidate === "string") {
36464
- if (candidate.startsWith("file:")) {
36465
- return fileURLToPath4(candidate);
36466
- }
36467
- return path422.resolve(candidate);
36468
- }
36469
- throw new TypeError("Unsupported repoRoot value. Expected string or URL.");
36470
- }
36471
- function buildDirectoryChain2(filePath, repoRoot) {
36472
- const directories = [];
36473
- const seen = /* @__PURE__ */ new Set();
36474
- const boundary = path422.resolve(repoRoot);
36475
- let current = path422.resolve(path422.dirname(filePath));
36476
- while (current !== void 0) {
36477
- if (!seen.has(current)) {
36478
- directories.push(current);
36479
- seen.add(current);
36480
- }
36481
- if (current === boundary) {
36482
- break;
36483
- }
36484
- const parent = path422.dirname(current);
36485
- if (parent === current) {
36486
- break;
36487
- }
36488
- current = parent;
36489
- }
36490
- if (!seen.has(boundary)) {
36491
- directories.push(boundary);
36492
- }
36493
- return directories;
36494
- }
36495
- function buildSearchRoots2(evalPath, repoRoot) {
36496
- const uniqueRoots = [];
36497
- const addRoot = (root) => {
36498
- const normalized = path422.resolve(root);
36499
- if (!uniqueRoots.includes(normalized)) {
36500
- uniqueRoots.push(normalized);
36501
- }
36502
- };
36503
- let currentDir = path422.dirname(evalPath);
36504
- let reachedBoundary = false;
36505
- while (!reachedBoundary) {
36506
- addRoot(currentDir);
36507
- const parentDir = path422.dirname(currentDir);
36508
- if (currentDir === repoRoot || parentDir === currentDir) {
36509
- reachedBoundary = true;
36510
- } else {
36511
- currentDir = parentDir;
36512
- }
36513
- }
36514
- addRoot(repoRoot);
36515
- addRoot(process.cwd());
36516
- return uniqueRoots;
36517
- }
36518
- function trimLeadingSeparators2(value) {
36519
- const trimmed = value.replace(/^[/\\]+/, "");
36520
- return trimmed.length > 0 ? trimmed : value;
36521
- }
36522
- async function resolveFileReference3(rawValue, searchRoots) {
36523
- const displayPath = trimLeadingSeparators2(rawValue);
36524
- const potentialPaths = [];
36525
- if (path422.isAbsolute(rawValue)) {
36526
- potentialPaths.push(path422.normalize(rawValue));
36527
- }
36528
- for (const base of searchRoots) {
36529
- potentialPaths.push(path422.resolve(base, displayPath));
36530
- }
36531
- const attempted = [];
36532
- const seen = /* @__PURE__ */ new Set();
36533
- for (const candidate of potentialPaths) {
36534
- const absoluteCandidate = path422.resolve(candidate);
36535
- if (seen.has(absoluteCandidate)) {
36536
- continue;
36537
- }
36538
- seen.add(absoluteCandidate);
36539
- attempted.push(absoluteCandidate);
36540
- if (await fileExists3(absoluteCandidate)) {
36541
- return { displayPath, resolvedPath: absoluteCandidate, attempted };
36542
- }
36543
- }
36544
- return { displayPath, attempted };
36545
- }
36546
36659
  var ANSI_YELLOW2 = "\x1B[33m";
36547
36660
  var ANSI_RESET22 = "\x1B[0m";
36548
36661
  var DEFAULT_EVAL_PATTERNS = [
@@ -36552,25 +36665,50 @@ var DEFAULT_EVAL_PATTERNS = [
36552
36665
  ];
36553
36666
  async function loadConfig(evalFilePath, repoRoot) {
36554
36667
  const directories = buildDirectoryChain2(evalFilePath, repoRoot);
36555
- const globalConfigPath = path43.join(getAgentvConfigDir(), "config.yaml");
36668
+ const globalConfigPath = path422.join(getAgentvConfigDir(), AGENTV_CONFIG_FILE_NAME);
36556
36669
  for (const directory of directories) {
36557
- const configPath2 = path43.join(directory, ".agentv", "config.yaml");
36558
- if (!await fileExists3(configPath2)) {
36670
+ const configPath2 = path422.join(directory, ".agentv", AGENTV_CONFIG_FILE_NAME);
36671
+ if (!await configPairExists(configPath2)) {
36559
36672
  continue;
36560
36673
  }
36561
- const config2 = await readConfigFile(configPath2);
36562
- if (config2) {
36563
- return config2;
36564
- }
36674
+ return readConfigFilePair(configPath2);
36565
36675
  }
36566
- return await fileExists3(globalConfigPath) ? readConfigFile(globalConfigPath) : null;
36676
+ return await configPairExists(globalConfigPath) ? readConfigFilePair(globalConfigPath) : null;
36567
36677
  }
36568
- async function readConfigFile(configPath2) {
36678
+ async function configPairExists(configPath2) {
36679
+ return await fileExists2(configPath2) || await fileExists2(getLocalConfigPath(configPath2));
36680
+ }
36681
+ async function readConfigObjectFile(configPath2) {
36682
+ if (!await fileExists2(configPath2)) {
36683
+ return void 0;
36684
+ }
36569
36685
  try {
36570
36686
  const rawConfig = await readFile13(configPath2, "utf8");
36571
- const parsed = interpolateEnv(parseYamlValue(rawConfig), process.env);
36687
+ const parsed = parseYamlValue(rawConfig);
36688
+ if (!isPlainConfigObject(parsed)) {
36689
+ logWarning(`Invalid AgentV config format at ${configPath2}`);
36690
+ return void 0;
36691
+ }
36692
+ return parsed;
36693
+ } catch (error40) {
36694
+ logWarning(`Could not read AgentV config at ${configPath2}: ${error40.message}`);
36695
+ return void 0;
36696
+ }
36697
+ }
36698
+ async function readConfigFilePair(configPath2) {
36699
+ const base = await readConfigObjectFile(configPath2);
36700
+ const local = await readConfigObjectFile(getLocalConfigPath(configPath2));
36701
+ const rawMerged = base && local ? mergeConfigObjects(base, local) : local ?? base;
36702
+ if (!rawMerged) {
36703
+ return null;
36704
+ }
36705
+ return parseConfigObject(rawMerged, local ? getLocalConfigPath(configPath2) : configPath2);
36706
+ }
36707
+ function parseConfigObject(rawConfig, configPath2) {
36708
+ try {
36709
+ const parsed = interpolateEnv(rawConfig, process.env);
36572
36710
  if (!isJsonObject(parsed)) {
36573
- logWarning(`Invalid config.yaml format at ${configPath2}`);
36711
+ logWarning(`Invalid AgentV config format at ${configPath2}`);
36574
36712
  return null;
36575
36713
  }
36576
36714
  const config2 = parsed;
@@ -36592,17 +36730,27 @@ async function readConfigFile(configPath2) {
36592
36730
  parsed.execution,
36593
36731
  configPath2
36594
36732
  );
36733
+ const defaultExperiment = parseDefaultExperiment(
36734
+ parsed.default_experiment,
36735
+ configPath2
36736
+ );
36737
+ const experiments = parseExperimentsConfig(
36738
+ parsed.experiments,
36739
+ configPath2
36740
+ );
36595
36741
  const results = parseResultsConfig(parsed.results, configPath2);
36596
36742
  const hooks = parseHooksConfig(parsed.hooks, configPath2);
36597
36743
  return {
36598
36744
  required_version: requiredVersion,
36599
36745
  eval_patterns: evalPatterns,
36746
+ ...defaultExperiment && { default_experiment: defaultExperiment },
36747
+ ...experiments && { experiments },
36600
36748
  execution: executionDefaults,
36601
36749
  results,
36602
36750
  ...hooks && { hooks }
36603
36751
  };
36604
36752
  } catch (error40) {
36605
- logWarning(`Could not read config.yaml at ${configPath2}: ${error40.message}`);
36753
+ logWarning(`Could not parse AgentV config at ${configPath2}: ${error40.message}`);
36606
36754
  return null;
36607
36755
  }
36608
36756
  }
@@ -36714,58 +36862,6 @@ function extractTargetsFromTestCase(testCase) {
36714
36862
  }
36715
36863
  return void 0;
36716
36864
  }
36717
- var VALID_TRIAL_STRATEGIES = /* @__PURE__ */ new Set([
36718
- "pass_at_k",
36719
- "mean",
36720
- "confidence_interval"
36721
- ]);
36722
- function extractTrialsConfig(suite) {
36723
- const execution = suite.execution;
36724
- if (!execution || typeof execution !== "object" || Array.isArray(execution)) {
36725
- return void 0;
36726
- }
36727
- const trials = execution.trials;
36728
- if (!trials || typeof trials !== "object" || Array.isArray(trials)) {
36729
- return void 0;
36730
- }
36731
- const trialsObj = trials;
36732
- const count = trialsObj.count;
36733
- if (count === void 0 || count === null) {
36734
- return void 0;
36735
- }
36736
- if (typeof count !== "number" || !Number.isInteger(count) || count < 1) {
36737
- logWarning(
36738
- `Invalid trials.count: ${count}, must be a positive integer. Ignoring trials config.`
36739
- );
36740
- return void 0;
36741
- }
36742
- if (count === 1) {
36743
- return void 0;
36744
- }
36745
- const rawStrategy = trialsObj.strategy;
36746
- let strategy = "pass_at_k";
36747
- if (rawStrategy !== void 0 && rawStrategy !== null) {
36748
- if (typeof rawStrategy !== "string" || !VALID_TRIAL_STRATEGIES.has(rawStrategy)) {
36749
- logWarning(
36750
- `Invalid trials.strategy: '${rawStrategy}'. Must be one of: pass_at_k, mean, confidence_interval. Defaulting to pass_at_k.`
36751
- );
36752
- } else {
36753
- strategy = rawStrategy;
36754
- }
36755
- }
36756
- const rawCostLimit = trialsObj.cost_limit_usd ?? trialsObj.costLimitUsd;
36757
- let costLimitUsd;
36758
- if (rawCostLimit !== void 0 && rawCostLimit !== null) {
36759
- if (typeof rawCostLimit === "number" && rawCostLimit > 0) {
36760
- costLimitUsd = rawCostLimit;
36761
- } else {
36762
- logWarning(
36763
- `Invalid trials.cost_limit_usd: ${rawCostLimit}. Must be a positive number. Ignoring.`
36764
- );
36765
- }
36766
- }
36767
- return { count, strategy, costLimitUsd };
36768
- }
36769
36865
  function extractCacheConfig(suite) {
36770
36866
  const execution = suite.execution;
36771
36867
  if (!execution || typeof execution !== "object" || Array.isArray(execution)) {
@@ -36896,6 +36992,36 @@ function parseExecutionDefaults(raw, configPath2) {
36896
36992
  }
36897
36993
  return Object.keys(result).length > 0 ? result : void 0;
36898
36994
  }
36995
+ function resolveDefaultExperimentReference(config2) {
36996
+ return config2?.experiments?.default ?? config2?.default_experiment;
36997
+ }
36998
+ function parseDefaultExperiment(raw, configPath2) {
36999
+ if (raw === void 0 || raw === null) {
37000
+ return void 0;
37001
+ }
37002
+ const value = readTrimmedString2(raw);
37003
+ if (!value) {
37004
+ logWarning(`Invalid default_experiment in ${configPath2}, expected non-empty string`);
37005
+ return void 0;
37006
+ }
37007
+ return value;
37008
+ }
37009
+ function parseExperimentsConfig(raw, configPath2) {
37010
+ if (raw === void 0 || raw === null) {
37011
+ return void 0;
37012
+ }
37013
+ if (typeof raw !== "object" || Array.isArray(raw)) {
37014
+ logWarning(`Invalid experiments in ${configPath2}, expected object`);
37015
+ return void 0;
37016
+ }
37017
+ const obj = raw;
37018
+ const defaultExperiment = readTrimmedString2(obj.default);
37019
+ if (obj.default !== void 0 && !defaultExperiment) {
37020
+ logWarning(`Invalid experiments.default in ${configPath2}, expected non-empty string`);
37021
+ return void 0;
37022
+ }
37023
+ return defaultExperiment ? { default: defaultExperiment } : void 0;
37024
+ }
36899
37025
  function isFilesystemPath(p) {
36900
37026
  return p.startsWith("/") || p.startsWith("~/") || p.startsWith("~\\") || p === "~" || /^[A-Za-z]:[/\\]/.test(p);
36901
37027
  }
@@ -37059,16 +37185,20 @@ function parseResultsConfig(raw, configPath2) {
37059
37185
  logWarning(`Invalid results.sync.require_push in ${configPath2}, expected boolean`);
37060
37186
  return void 0;
37061
37187
  }
37062
- if (syncObj.push_conflict_policy !== void 0 && syncObj.push_conflict_policy !== "block" && syncObj.push_conflict_policy !== "backup_and_force_push") {
37188
+ if (syncObj.push_conflict_policy === "backup_and_force_push") {
37063
37189
  logWarning(
37064
- `Invalid results.sync.push_conflict_policy in ${configPath2}, expected 'block' or 'backup_and_force_push'`
37190
+ `results.sync.push_conflict_policy: 'backup_and_force_push' in ${configPath2} is no longer supported. Remove the field or set it to 'block'; AgentV never force-pushes result branches.`
37065
37191
  );
37066
37192
  return void 0;
37067
37193
  }
37194
+ if (syncObj.push_conflict_policy !== void 0 && syncObj.push_conflict_policy !== "block") {
37195
+ logWarning(`Invalid results.sync.push_conflict_policy in ${configPath2}, expected 'block'`);
37196
+ return void 0;
37197
+ }
37068
37198
  sync = {
37069
37199
  ...typeof syncObj.auto_push === "boolean" && { auto_push: syncObj.auto_push },
37070
37200
  ...typeof syncObj.require_push === "boolean" && { require_push: syncObj.require_push },
37071
- ...(syncObj.push_conflict_policy === "block" || syncObj.push_conflict_policy === "backup_and_force_push") && {
37201
+ ...syncObj.push_conflict_policy === "block" && {
37072
37202
  push_conflict_policy: syncObj.push_conflict_policy
37073
37203
  }
37074
37204
  };
@@ -37199,8 +37329,8 @@ function isTemplateReference(value) {
37199
37329
  }
37200
37330
  async function resolveAssertionTemplateReference(include, searchRoots) {
37201
37331
  const templateCandidates = isTemplateReference(include) ? [
37202
- path44.join(".agentv", "templates", `${include}.yaml`),
37203
- path44.join(".agentv", "templates", `${include}.yml`)
37332
+ path43.join(".agentv", "templates", `${include}.yaml`),
37333
+ path43.join(".agentv", "templates", `${include}.yml`)
37204
37334
  ] : [include];
37205
37335
  const attempted = [];
37206
37336
  for (const candidate of templateCandidates) {
@@ -37253,10 +37383,10 @@ ${resolved.attempted.map((attempt) => ` Tried: ${attempt}`).join("\n")}` : "";
37253
37383
  `Invalid assertion template file in '${evalId}': ${resolved.resolvedPath} is missing a top-level assertions array`
37254
37384
  );
37255
37385
  }
37256
- const templateDir = path44.dirname(resolved.resolvedPath);
37386
+ const templateDir = path43.dirname(resolved.resolvedPath);
37257
37387
  const nestedSearchRoots = [
37258
37388
  templateDir,
37259
- ...searchRoots.filter((root) => path44.resolve(root) !== templateDir)
37389
+ ...searchRoots.filter((root) => path43.resolve(root) !== templateDir)
37260
37390
  ];
37261
37391
  return await expandGraderEntries(assertions, nestedSearchRoots, evalId, {
37262
37392
  depth: nextDepth,
@@ -37317,7 +37447,7 @@ async function collectAssertionTemplateReferencesFromValue(value, searchRoots, e
37317
37447
  references.push({
37318
37448
  kind: "assertion_template",
37319
37449
  displayPath: resolved.displayPath,
37320
- ...resolved.resolvedPath ? { resolvedPath: path44.resolve(resolved.resolvedPath) } : {}
37450
+ ...resolved.resolvedPath ? { resolvedPath: path43.resolve(resolved.resolvedPath) } : {}
37321
37451
  });
37322
37452
  if (resolved.resolvedPath) {
37323
37453
  if (includeContext.chain.includes(resolved.resolvedPath)) {
@@ -37327,10 +37457,10 @@ async function collectAssertionTemplateReferencesFromValue(value, searchRoots, e
37327
37457
  const content = await readFile15(resolved.resolvedPath, "utf8");
37328
37458
  const parsed = interpolateEnv(parseYamlValue(content), process.env);
37329
37459
  if (isJsonObject2(parsed) && Array.isArray(parsed.assertions)) {
37330
- const templateDir = path44.dirname(resolved.resolvedPath);
37460
+ const templateDir = path43.dirname(resolved.resolvedPath);
37331
37461
  const nestedSearchRoots = [
37332
37462
  templateDir,
37333
- ...searchRoots.filter((root) => path44.resolve(root) !== templateDir)
37463
+ ...searchRoots.filter((root) => path43.resolve(root) !== templateDir)
37334
37464
  ];
37335
37465
  references.push(
37336
37466
  ...await collectAssertionTemplateReferencesFromValue(
@@ -37500,7 +37630,7 @@ async function parseGraderList(candidateEvaluators, searchRoots, evalId, default
37500
37630
  }
37501
37631
  command = parseCommandToArgv(trimmed);
37502
37632
  } else {
37503
- command = asStringArray(
37633
+ command = asStringArray2(
37504
37634
  rawCommand,
37505
37635
  `code-grader command for evaluator '${name}' in '${evalId}'`
37506
37636
  );
@@ -37516,7 +37646,7 @@ async function parseGraderList(candidateEvaluators, searchRoots, evalId, default
37516
37646
  if (cwd) {
37517
37647
  const resolved = await resolveFileReference3(cwd, searchRoots);
37518
37648
  if (resolved.resolvedPath) {
37519
- resolvedCwd = path44.resolve(resolved.resolvedPath);
37649
+ resolvedCwd = path43.resolve(resolved.resolvedPath);
37520
37650
  } else {
37521
37651
  logWarning2(
37522
37652
  `Code-grader evaluator '${name}' in '${evalId}': cwd not found (${resolved.displayPath})`,
@@ -37706,7 +37836,7 @@ async function parseGraderList(candidateEvaluators, searchRoots, evalId, default
37706
37836
  aggregatorPrompt = fileRef;
37707
37837
  const resolved = await resolveFileReference3(fileRef, searchRoots);
37708
37838
  if (resolved.resolvedPath) {
37709
- promptPath2 = path44.resolve(resolved.resolvedPath);
37839
+ promptPath2 = path43.resolve(resolved.resolvedPath);
37710
37840
  } else {
37711
37841
  throw new Error(
37712
37842
  `Composite aggregator in '${evalId}': prompt file not found: ${resolved.displayPath}`
@@ -38376,7 +38506,7 @@ async function parseGraderList(candidateEvaluators, searchRoots, evalId, default
38376
38506
  `${ANSI_YELLOW22}Warning: 'prompt.script' is deprecated in evaluator '${name}' in '${evalId}'. Use 'prompt.command' instead.${ANSI_RESET3}`
38377
38507
  );
38378
38508
  }
38379
- const commandArray = asStringArray(
38509
+ const commandArray = asStringArray2(
38380
38510
  rawPrompt.command ?? rawPrompt.script,
38381
38511
  `prompt.command for evaluator '${name}' in '${evalId}'`
38382
38512
  );
@@ -38386,7 +38516,7 @@ async function parseGraderList(candidateEvaluators, searchRoots, evalId, default
38386
38516
  const commandPath = commandArray[commandArray.length - 1];
38387
38517
  const resolved = await resolveFileReference3(commandPath, searchRoots);
38388
38518
  if (resolved.resolvedPath) {
38389
- resolvedPromptScript = [...commandArray.slice(0, -1), path44.resolve(resolved.resolvedPath)];
38519
+ resolvedPromptScript = [...commandArray.slice(0, -1), path43.resolve(resolved.resolvedPath)];
38390
38520
  } else {
38391
38521
  throw new Error(
38392
38522
  `Grader '${name}' in '${evalId}': prompt command file not found: ${resolved.displayPath}`
@@ -38401,7 +38531,7 @@ async function parseGraderList(candidateEvaluators, searchRoots, evalId, default
38401
38531
  prompt = fileRef;
38402
38532
  const resolved = await resolveFileReference3(fileRef, searchRoots);
38403
38533
  if (resolved.resolvedPath) {
38404
- promptPath = path44.resolve(resolved.resolvedPath);
38534
+ promptPath = path43.resolve(resolved.resolvedPath);
38405
38535
  try {
38406
38536
  await validateCustomPromptContent(promptPath);
38407
38537
  } catch (error40) {
@@ -38540,7 +38670,7 @@ async function parsePreprocessors(rawValue, searchRoots, evaluatorName, evalId)
38540
38670
  if (!type) {
38541
38671
  throw new Error(`Grader '${evaluatorName}' in '${evalId}': preprocessor.type is required`);
38542
38672
  }
38543
- const command = asStringArray(
38673
+ const command = asStringArray2(
38544
38674
  rawEntry.command,
38545
38675
  `preprocessor command for evaluator '${evaluatorName}' in '${evalId}'`
38546
38676
  );
@@ -38559,7 +38689,7 @@ async function parsePreprocessors(rawValue, searchRoots, evaluatorName, evalId)
38559
38689
  preprocessors.push({
38560
38690
  type,
38561
38691
  command,
38562
- resolvedCommand: [...command.slice(0, -1), path44.resolve(resolved.resolvedPath)]
38692
+ resolvedCommand: [...command.slice(0, -1), path43.resolve(resolved.resolvedPath)]
38563
38693
  });
38564
38694
  }
38565
38695
  return preprocessors;
@@ -38626,7 +38756,7 @@ function asStringArrayStrict(value) {
38626
38756
  const result = value.filter((v) => typeof v === "string");
38627
38757
  return result.length > 0 ? result : void 0;
38628
38758
  }
38629
- function asStringArray(value, description) {
38759
+ function asStringArray2(value, description) {
38630
38760
  if (value === void 0) {
38631
38761
  return void 0;
38632
38762
  }
@@ -38654,10 +38784,10 @@ async function resolveOptionalCommandSource(command, searchRoots) {
38654
38784
  return void 0;
38655
38785
  }
38656
38786
  const resolved = await resolveFileReference3(candidate, searchRoots);
38657
- return resolved.resolvedPath ? path44.resolve(resolved.resolvedPath) : void 0;
38787
+ return resolved.resolvedPath ? path43.resolve(resolved.resolvedPath) : void 0;
38658
38788
  }
38659
38789
  function looksLikeFilePath(value) {
38660
- return path44.isAbsolute(value) || value.startsWith(".") || value.includes("/") || value.includes("\\") || /\.[cm]?[jt]sx?$|\.py$|\.sh$|\.bash$|\.rb$|\.go$|\.rs$/i.test(value);
38790
+ return path43.isAbsolute(value) || value.startsWith(".") || value.includes("/") || value.includes("\\") || /\.[cm]?[jt]sx?$|\.py$|\.sh$|\.bash$|\.rb$|\.go$|\.rs$/i.test(value);
38661
38791
  }
38662
38792
  function parseCommandToArgv(command) {
38663
38793
  if (process.platform === "win32") {
@@ -39045,7 +39175,7 @@ var IMAGE_MEDIA_TYPES = {
39045
39175
  ".bmp": "image/bmp"
39046
39176
  };
39047
39177
  function detectImageMediaType(filePath) {
39048
- const ext = path45.extname(filePath).toLowerCase();
39178
+ const ext = path44.extname(filePath).toLowerCase();
39049
39179
  return IMAGE_MEDIA_TYPES[ext];
39050
39180
  }
39051
39181
  var ANSI_YELLOW3 = "\x1B[33m";
@@ -39109,7 +39239,7 @@ async function processMessages(options) {
39109
39239
  ...cloneJsonObject(rawSegment),
39110
39240
  path: displayPath,
39111
39241
  text: fileContent,
39112
- resolvedPath: path45.resolve(resolvedPath)
39242
+ resolvedPath: path44.resolve(resolvedPath)
39113
39243
  });
39114
39244
  if (verbose) {
39115
39245
  const label = messageType === "input" ? "[File]" : "[Expected Output File]";
@@ -39233,7 +39363,7 @@ async function processExpectedMessages(options) {
39233
39363
  type: "file",
39234
39364
  path: displayPath,
39235
39365
  text: fileContent,
39236
- resolvedPath: path45.resolve(resolvedPath)
39366
+ resolvedPath: path44.resolve(resolvedPath)
39237
39367
  });
39238
39368
  if (verbose) {
39239
39369
  console.log(` [Expected Output File] Found: ${displayPath}`);
@@ -39379,7 +39509,7 @@ function matchesFilter(id, filter) {
39379
39509
  return typeof filter === "string" ? micromatch.isMatch(id, filter) : filter.some((pattern) => micromatch.isMatch(id, pattern));
39380
39510
  }
39381
39511
  function detectFormat(filePath) {
39382
- const ext = path46.extname(filePath).toLowerCase();
39512
+ const ext = path45.extname(filePath).toLowerCase();
39383
39513
  if (ext === ".jsonl") return "jsonl";
39384
39514
  if (ext === ".yaml" || ext === ".yml") return "yaml";
39385
39515
  if (ext === ".json") return "agent-skills-json";
@@ -39389,10 +39519,10 @@ function detectFormat(filePath) {
39389
39519
  );
39390
39520
  }
39391
39521
  async function loadSidecarMetadata(jsonlPath, verbose) {
39392
- const dir = path46.dirname(jsonlPath);
39393
- const base = path46.basename(jsonlPath, ".jsonl");
39394
- const sidecarPath = path46.join(dir, `${base}.yaml`);
39395
- if (!await fileExists3(sidecarPath)) {
39522
+ const dir = path45.dirname(jsonlPath);
39523
+ const base = path45.basename(jsonlPath, ".jsonl");
39524
+ const sidecarPath = path45.join(dir, `${base}.yaml`);
39525
+ if (!await fileExists2(sidecarPath)) {
39396
39526
  if (verbose) {
39397
39527
  logWarning4(`Sidecar metadata file not found: ${sidecarPath} (using defaults)`);
39398
39528
  }
@@ -39440,13 +39570,13 @@ function parseJsonlContent(content, filePath) {
39440
39570
  async function loadTestsFromJsonl(evalFilePath, repoRoot, options) {
39441
39571
  const verbose = options?.verbose ?? false;
39442
39572
  const filterPattern = options?.filter;
39443
- const absoluteTestPath = path46.resolve(evalFilePath);
39573
+ const absoluteTestPath = path45.resolve(evalFilePath);
39444
39574
  const repoRootPath = resolveToAbsolutePath(repoRoot);
39445
39575
  const searchRoots = buildSearchRoots2(absoluteTestPath, repoRootPath);
39446
39576
  const sidecar = await loadSidecarMetadata(absoluteTestPath, verbose);
39447
39577
  const rawFile = await readFile17(absoluteTestPath, "utf8");
39448
39578
  const rawCases = parseJsonlContent(rawFile, evalFilePath);
39449
- const fallbackSuiteName = path46.basename(absoluteTestPath, ".jsonl") || "eval";
39579
+ const fallbackSuiteName = path45.basename(absoluteTestPath, ".jsonl") || "eval";
39450
39580
  const suiteName = sidecar.name && sidecar.name.trim().length > 0 ? sidecar.name : fallbackSuiteName;
39451
39581
  const globalEvaluator = coerceEvaluator(sidecar.evaluator, "sidecar") ?? "llm-grader";
39452
39582
  const globalExecution = sidecar.execution;
@@ -39843,7 +39973,7 @@ function interpolateRawEvalCase(raw, vars) {
39843
39973
  }
39844
39974
  async function readTestSuiteMetadata(testFilePath) {
39845
39975
  try {
39846
- const absolutePath = path47.resolve(testFilePath);
39976
+ const absolutePath = path46.resolve(testFilePath);
39847
39977
  const content = await readFile18(absolutePath, "utf8");
39848
39978
  const parsed = interpolateEnv(parseYamlValue(content), process.env);
39849
39979
  if (!isJsonObject(parsed)) {
@@ -39852,8 +39982,7 @@ async function readTestSuiteMetadata(testFilePath) {
39852
39982
  return {
39853
39983
  target: extractTargetFromSuite(parsed),
39854
39984
  targets: extractTargetsFromSuite(parsed),
39855
- targetRefs: extractTargetRefsFromSuite(parsed),
39856
- trials: extractTrialsConfig(parsed)
39985
+ targetRefs: extractTargetRefsFromSuite(parsed)
39857
39986
  };
39858
39987
  } catch {
39859
39988
  return {};
@@ -39868,7 +39997,7 @@ async function loadTestSuite(evalFilePath, repoRoot, options) {
39868
39997
  return { tests: await loadTestsFromAgentSkills(evalFilePath) };
39869
39998
  }
39870
39999
  if (format === "typescript") {
39871
- const { loadTsEvalSuite: loadTsEvalSuite2 } = await import("./ts-eval-loader-S7ESROX2-6CB3HB6H.js");
40000
+ const { loadTsEvalSuite: loadTsEvalSuite2 } = await import("./ts-eval-loader-RE43OAGX-AMRCUKBZ.js");
39872
40001
  return loadTsEvalSuite2(evalFilePath, resolveToAbsolutePath(repoRoot), options);
39873
40002
  }
39874
40003
  const { tests, parsed, suiteWorkspacePath } = await loadTestsFromYaml(
@@ -39897,7 +40026,7 @@ async function loadTests(evalFilePath, repoRoot, options) {
39897
40026
  return loadTestsFromAgentSkills(evalFilePath);
39898
40027
  }
39899
40028
  if (format === "typescript") {
39900
- const { loadTsEvalSuite: loadTsEvalSuite2 } = await import("./ts-eval-loader-S7ESROX2-6CB3HB6H.js");
40029
+ const { loadTsEvalSuite: loadTsEvalSuite2 } = await import("./ts-eval-loader-RE43OAGX-AMRCUKBZ.js");
39901
40030
  const suite = await loadTsEvalSuite2(evalFilePath, resolveToAbsolutePath(repoRoot), options);
39902
40031
  return suite.tests;
39903
40032
  }
@@ -39906,14 +40035,14 @@ async function loadTests(evalFilePath, repoRoot, options) {
39906
40035
  }
39907
40036
  var loadEvalCases = loadTests;
39908
40037
  async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
39909
- const absoluteTestPath = path47.resolve(evalFilePath);
40038
+ const absoluteTestPath = path46.resolve(evalFilePath);
39910
40039
  const rawFile = await readFile18(absoluteTestPath, "utf8");
39911
40040
  return loadTestsFromParsedYamlValue(parseYamlValue(rawFile), evalFilePath, repoRoot, options);
39912
40041
  }
39913
40042
  async function loadTestsFromParsedYamlValue(rawParsed, evalFilePath, repoRoot, options) {
39914
40043
  const verbose = options?.verbose ?? false;
39915
40044
  const filterPattern = options?.filter;
39916
- const absoluteTestPath = path47.resolve(evalFilePath);
40045
+ const absoluteTestPath = path46.resolve(evalFilePath);
39917
40046
  const repoRootPath = resolveToAbsolutePath(repoRoot);
39918
40047
  const searchRoots = buildSearchRoots2(absoluteTestPath, repoRootPath);
39919
40048
  const config2 = await loadConfig(absoluteTestPath, repoRootPath);
@@ -39924,7 +40053,7 @@ async function loadTestsFromParsedYamlValue(rawParsed, evalFilePath, repoRoot, o
39924
40053
  }
39925
40054
  const suite = interpolated;
39926
40055
  const suiteNameFromFile = asString5(suite.name)?.trim();
39927
- const fallbackSuiteName = path47.basename(absoluteTestPath).replace(/\.eval\.ya?ml$/i, "").replace(/\.ya?ml$/i, "") || "eval";
40056
+ const fallbackSuiteName = path46.basename(absoluteTestPath).replace(/\.eval\.ya?ml$/i, "").replace(/\.ya?ml$/i, "") || "eval";
39928
40057
  const suiteName = suiteNameFromFile && suiteNameFromFile.length > 0 ? suiteNameFromFile : fallbackSuiteName;
39929
40058
  const rawTestCases = resolveTests(suite);
39930
40059
  const globalEvaluator = coerceEvaluator(suite.evaluator, "global") ?? "llm-grader";
@@ -39934,10 +40063,10 @@ async function loadTestsFromParsedYamlValue(rawParsed, evalFilePath, repoRoot, o
39934
40063
  "<suite>",
39935
40064
  absoluteTestPath
39936
40065
  );
39937
- const evalFileDir = path47.dirname(absoluteTestPath);
40066
+ const evalFileDir = path46.dirname(absoluteTestPath);
39938
40067
  let expandedTestCases;
39939
40068
  if (typeof rawTestCases === "string") {
39940
- const externalPath = path47.resolve(evalFileDir, rawTestCases);
40069
+ const externalPath = path46.resolve(evalFileDir, rawTestCases);
39941
40070
  let isDir = false;
39942
40071
  try {
39943
40072
  const pathStat = await stat9(externalPath);
@@ -39992,12 +40121,41 @@ async function loadTestsFromParsedYamlValue(rawParsed, evalFilePath, repoRoot, o
39992
40121
  const skipDefaults = caseExecution?.skip_defaults === true;
39993
40122
  const caseThreshold = typeof caseExecution?.threshold === "number" && caseExecution.threshold >= 0 && caseExecution.threshold <= 1 ? caseExecution.threshold : void 0;
39994
40123
  const effectiveSuiteInputFiles = rawSuiteInputFiles && !skipDefaults ? interpolateCaseField(rawSuiteInputFiles, caseVars) : void 0;
39995
- const testInputMessages = resolveInputMessages(renderedCase, effectiveSuiteInputFiles);
40124
+ let inputCase = renderedCase;
40125
+ let inputSuiteFiles = effectiveSuiteInputFiles;
40126
+ if (renderedCase.input === void 0) {
40127
+ const promptFallback = await loadPromptMdFallback({
40128
+ evalFilePath: absoluteTestPath,
40129
+ searchRoots,
40130
+ testInputFiles: renderedCase.input_files,
40131
+ suiteInputFiles: effectiveSuiteInputFiles
40132
+ });
40133
+ if (promptFallback) {
40134
+ if (promptFallback.inputFilesSource === "test") {
40135
+ const { input_files: _inputFiles, ...caseWithoutInputFiles } = renderedCase;
40136
+ inputCase = {
40137
+ ...caseWithoutInputFiles,
40138
+ input: promptFallback.promptText,
40139
+ ...promptFallback.remainingInputFiles ? { input_files: [...promptFallback.remainingInputFiles] } : {}
40140
+ };
40141
+ inputSuiteFiles = void 0;
40142
+ } else {
40143
+ inputCase = {
40144
+ ...renderedCase,
40145
+ input: promptFallback.promptText
40146
+ };
40147
+ if (promptFallback.inputFilesSource === "suite") {
40148
+ inputSuiteFiles = promptFallback.remainingInputFiles ? [...promptFallback.remainingInputFiles] : void 0;
40149
+ }
40150
+ }
40151
+ }
40152
+ }
40153
+ const testInputMessages = resolveInputMessages(inputCase, inputSuiteFiles);
39996
40154
  const expectedMessages = resolveExpectedMessages(renderedCase) ?? [];
39997
40155
  const hasEvaluationSpec = !!outcome || expectedMessages.length > 0 || renderedCase.assertions !== void 0 || renderedCase.assert !== void 0 || Array.isArray(renderedCase.turns) && renderedCase.turns.length > 0;
39998
40156
  if (!id || !hasEvaluationSpec || !testInputMessages || testInputMessages.length === 0) {
39999
40157
  logError3(
40000
- `Skipping incomplete test: ${id ?? "unknown"}. Missing required fields: id, input, and at least one of criteria/expected_output/assertions/turns`
40158
+ `Skipping incomplete test: ${id ?? "unknown"}. Missing required fields: id, input or PROMPT.md, and at least one of criteria/expected_output/assertions/turns`
40001
40159
  );
40002
40160
  continue;
40003
40161
  }
@@ -40137,7 +40295,6 @@ function buildEvalSuiteResult(parsed, tests, suiteWorkspacePath) {
40137
40295
  const threshold = extractThreshold(parsed);
40138
40296
  return {
40139
40297
  tests,
40140
- trials: extractTrialsConfig(parsed),
40141
40298
  targets: extractTargetsFromSuite(parsed),
40142
40299
  targetRefs: extractTargetRefsFromSuite(parsed),
40143
40300
  workers: extractWorkersFromSuite(parsed),
@@ -40259,7 +40416,7 @@ function collectInputSourceReferences(inputMessages) {
40259
40416
  references.push({
40260
40417
  kind: "input_file",
40261
40418
  displayPath,
40262
- ...typeof segment.resolvedPath === "string" ? { resolvedPath: path47.resolve(segment.resolvedPath) } : {}
40419
+ ...typeof segment.resolvedPath === "string" ? { resolvedPath: path46.resolve(segment.resolvedPath) } : {}
40263
40420
  });
40264
40421
  }
40265
40422
  }
@@ -40332,7 +40489,7 @@ function collectSingleGraderSourceReferences(evaluator) {
40332
40489
  references.push({
40333
40490
  kind: "code_grader_command",
40334
40491
  displayPath: evaluator.aggregator.path,
40335
- resolvedPath: path47.resolve(evaluator.aggregator.cwd ?? "", evaluator.aggregator.path),
40492
+ resolvedPath: path46.resolve(evaluator.aggregator.cwd ?? "", evaluator.aggregator.path),
40336
40493
  graderName: evaluator.name
40337
40494
  });
40338
40495
  } else if (evaluator.aggregator.type === "llm-grader" && evaluator.aggregator.promptPath) {
@@ -40365,9 +40522,9 @@ function dedupeSourceReferences(references) {
40365
40522
  return deduped;
40366
40523
  }
40367
40524
  function toPortableRelativePath(root, candidate) {
40368
- const relative = path47.relative(root, candidate);
40369
- if (relative && !relative.startsWith("..") && !path47.isAbsolute(relative)) {
40370
- return relative.split(path47.sep).join("/");
40525
+ const relative = path46.relative(root, candidate);
40526
+ if (relative && !relative.startsWith("..") && !path46.isAbsolute(relative)) {
40527
+ return relative.split(path46.sep).join("/");
40371
40528
  }
40372
40529
  return void 0;
40373
40530
  }
@@ -40421,8 +40578,8 @@ function parseWorkspaceScriptConfig(raw, evalFileDir) {
40421
40578
  if (!command) return void 0;
40422
40579
  const timeoutMs = typeof obj.timeout_ms === "number" ? obj.timeout_ms : void 0;
40423
40580
  let cwd = typeof obj.cwd === "string" ? obj.cwd : void 0;
40424
- if (cwd && !path47.isAbsolute(cwd)) {
40425
- cwd = path47.resolve(evalFileDir, cwd);
40581
+ if (cwd && !path46.isAbsolute(cwd)) {
40582
+ cwd = path46.resolve(evalFileDir, cwd);
40426
40583
  }
40427
40584
  const config2 = { command };
40428
40585
  if (timeoutMs !== void 0) {
@@ -40460,7 +40617,7 @@ function parseWorkspaceHooksConfig(raw, evalFileDir) {
40460
40617
  }
40461
40618
  async function resolveWorkspaceConfig(raw, evalFileDir) {
40462
40619
  if (typeof raw === "string") {
40463
- const workspaceFilePath = path47.resolve(evalFileDir, raw);
40620
+ const workspaceFilePath = path46.resolve(evalFileDir, raw);
40464
40621
  let content;
40465
40622
  try {
40466
40623
  content = await readFile18(workspaceFilePath, "utf8");
@@ -40473,7 +40630,7 @@ async function resolveWorkspaceConfig(raw, evalFileDir) {
40473
40630
  `Invalid workspace file format: ${workspaceFilePath} (expected a YAML object)`
40474
40631
  );
40475
40632
  }
40476
- const workspaceFileDir = path47.dirname(workspaceFilePath);
40633
+ const workspaceFileDir = path46.dirname(workspaceFilePath);
40477
40634
  const resolvedWorkspace = parseWorkspaceConfig(parsed, workspaceFileDir);
40478
40635
  if (resolvedWorkspace) {
40479
40636
  return { ...resolvedWorkspace, workspaceFileDir };
@@ -40507,8 +40664,8 @@ function parseWorkspaceConfig(raw, evalFileDir) {
40507
40664
  throw new Error("workspace.static has been removed. Use workspace.mode='static'.");
40508
40665
  }
40509
40666
  let template = typeof obj.template === "string" ? obj.template : void 0;
40510
- if (template && !path47.isAbsolute(template)) {
40511
- template = path47.resolve(evalFileDir, template);
40667
+ if (template && !path46.isAbsolute(template)) {
40668
+ template = path46.resolve(evalFileDir, template);
40512
40669
  }
40513
40670
  const isolation = obj.isolation === "shared" || obj.isolation === "per_test" ? obj.isolation : void 0;
40514
40671
  const repos = Array.isArray(obj.repos) ? obj.repos.map(parseRepoConfig).filter(Boolean) : void 0;
@@ -40646,7 +40803,7 @@ ${detailBlock}${ANSI_RESET6}`);
40646
40803
  }
40647
40804
  }
40648
40805
  function pathFromRoot(root) {
40649
- return root instanceof URL ? fileURLToPath5(root) : String(root);
40806
+ return root instanceof URL ? fileURLToPath4(root) : String(root);
40650
40807
  }
40651
40808
  function classifyQualityStatus(score, threshold = DEFAULT_THRESHOLD) {
40652
40809
  return score >= threshold ? "ok" : "quality_failure";
@@ -40786,18 +40943,18 @@ function validateDependencyGraph(tests) {
40786
40943
  }
40787
40944
  const visited = /* @__PURE__ */ new Set();
40788
40945
  const visiting = /* @__PURE__ */ new Set();
40789
- function visit(id, path522) {
40946
+ function visit(id, path51) {
40790
40947
  if (visiting.has(id)) {
40791
- const cycle = [...path522.slice(path522.indexOf(id)), id];
40948
+ const cycle = [...path51.slice(path51.indexOf(id)), id];
40792
40949
  throw new Error(`Circular dependency detected: ${cycle.join(" \u2192 ")}`);
40793
40950
  }
40794
40951
  if (visited.has(id)) return;
40795
40952
  visiting.add(id);
40796
- path522.push(id);
40953
+ path51.push(id);
40797
40954
  for (const dep of depMap.get(id) ?? []) {
40798
- visit(dep, path522);
40955
+ visit(dep, path51);
40799
40956
  }
40800
- path522.pop();
40957
+ path51.pop();
40801
40958
  visiting.delete(id);
40802
40959
  visited.add(id);
40803
40960
  }
@@ -40903,7 +41060,7 @@ async function gradePreparedEvalCase(options) {
40903
41060
  model
40904
41061
  });
40905
41062
  const evaluatorRegistry = buildEvaluatorRegistry(evaluators, runtime.resolveGraderProvider);
40906
- const discoveryBaseDir = evalFilePath ? path48.dirname(path48.resolve(evalFilePath)) : process.cwd();
41063
+ const discoveryBaseDir = evalFilePath ? path47.dirname(path47.resolve(evalFilePath)) : process.cwd();
40907
41064
  await discoverAssertions(typeRegistry, discoveryBaseDir);
40908
41065
  await discoverGraders(typeRegistry, discoveryBaseDir);
40909
41066
  let fileChanges;
@@ -41095,7 +41252,7 @@ async function runEvaluation(options) {
41095
41252
  }
41096
41253
  const evaluatorRegistry = buildEvaluatorRegistry(evaluators, resolveGraderProvider);
41097
41254
  const typeRegistry = createBuiltinRegistry();
41098
- const discoveryBaseDir = evalFilePath ? path48.dirname(path48.resolve(evalFilePath)) : process.cwd();
41255
+ const discoveryBaseDir = evalFilePath ? path47.dirname(path47.resolve(evalFilePath)) : process.cwd();
41099
41256
  const evalDir = discoveryBaseDir;
41100
41257
  await discoverAssertions(typeRegistry, discoveryBaseDir);
41101
41258
  await discoverGraders(typeRegistry, discoveryBaseDir);
@@ -42301,7 +42458,8 @@ async function runEvalCaseWithTrials(options, trialsConfig) {
42301
42458
  costUsd: trialCost,
42302
42459
  executionStatus: result.executionStatus,
42303
42460
  failureStage: result.failureStage,
42304
- failureReasonCode: result.failureReasonCode
42461
+ failureReasonCode: result.failureReasonCode,
42462
+ result
42305
42463
  };
42306
42464
  trialResults.push(trial);
42307
42465
  if (trialCost !== void 0) {
@@ -42316,7 +42474,7 @@ async function runEvalCaseWithTrials(options, trialsConfig) {
42316
42474
  costLimited = true;
42317
42475
  break;
42318
42476
  }
42319
- if (trialsConfig.strategy === "pass_at_k" && trialVerdict === "pass") {
42477
+ if (trialsConfig.strategy === "pass_at_k" && trialsConfig.earlyExit !== false && trialVerdict === "pass") {
42320
42478
  break;
42321
42479
  }
42322
42480
  }
@@ -42627,7 +42785,7 @@ async function runEvaluatorList(options) {
42627
42785
  dockerConfig,
42628
42786
  dependencyResults
42629
42787
  };
42630
- const evalFileDir = evalCase.file_paths[0] ? path48.dirname(evalCase.file_paths[0]) : process.cwd();
42788
+ const evalFileDir = evalCase.file_paths[0] ? path47.dirname(evalCase.file_paths[0]) : process.cwd();
42631
42789
  const dispatchContext = {
42632
42790
  graderProvider,
42633
42791
  targetResolver,
@@ -43702,6 +43860,12 @@ function fromResultArtifactPointerWire(pointer) {
43702
43860
  };
43703
43861
  }
43704
43862
  var TOOL_STATUS_VALUES = ["ok", "error", "timeout", "cancelled", "unknown"];
43863
+ var TIMING_SOURCE_VALUES = [
43864
+ "provider_reported",
43865
+ "token_estimated",
43866
+ "aggregate",
43867
+ "unavailable"
43868
+ ];
43705
43869
  var FILE_READ_KEY_SET = /* @__PURE__ */ new Set([
43706
43870
  "file",
43707
43871
  "filename",
@@ -43772,6 +43936,23 @@ var ReasoningBlockWireSchema = external_exports.object({
43772
43936
  event_id: external_exports.string().optional(),
43773
43937
  content: external_exports.string().optional()
43774
43938
  }).strict();
43939
+ var MetricsTimingWireSchema = external_exports.object({
43940
+ total_tokens: external_exports.number().int().nonnegative(),
43941
+ duration_ms: external_exports.number().nonnegative(),
43942
+ total_duration_seconds: external_exports.number().nonnegative(),
43943
+ cost_usd: external_exports.number().nonnegative().nullable(),
43944
+ token_usage: external_exports.object({
43945
+ input: external_exports.number().int().nonnegative(),
43946
+ output: external_exports.number().int().nonnegative(),
43947
+ reasoning: external_exports.number().int().nonnegative()
43948
+ }).strict(),
43949
+ usage_sources: external_exports.object({
43950
+ token_usage: external_exports.enum(TIMING_SOURCE_VALUES),
43951
+ total_tokens: external_exports.enum(TIMING_SOURCE_VALUES),
43952
+ duration: external_exports.enum(TIMING_SOURCE_VALUES),
43953
+ cost: external_exports.enum(TIMING_SOURCE_VALUES)
43954
+ }).strict()
43955
+ }).strict();
43775
43956
  var MetricsWireSchema = external_exports.object({
43776
43957
  tool_calls: external_exports.record(external_exports.string(), external_exports.number().int().nonnegative()),
43777
43958
  tool_call_counts: external_exports.record(external_exports.string(), external_exports.number().int().nonnegative()),
@@ -43813,7 +43994,8 @@ var MetricsArtifactWireSchema = external_exports.object({
43813
43994
  grading_path: external_exports.string().optional(),
43814
43995
  timing_path: external_exports.string().optional()
43815
43996
  }).strict(),
43816
- metrics: MetricsWireSchema
43997
+ metrics: MetricsWireSchema,
43998
+ timing: MetricsTimingWireSchema.optional()
43817
43999
  }).strict();
43818
44000
  function dropUndefined6(value) {
43819
44001
  return Object.fromEntries(
@@ -44399,6 +44581,7 @@ var RESULT_ROW_ALIASES = {
44399
44581
  rawProviderLogPath: "raw_provider_log_path",
44400
44582
  responsePath: "response_path",
44401
44583
  startTime: "start_time",
44584
+ summaryPath: "summary_path",
44402
44585
  targetsPath: "targets_path",
44403
44586
  taskDir: "task_dir",
44404
44587
  testId: "test_id",
@@ -44504,7 +44687,7 @@ function buildSnakeCaseOnlyFieldError(field, context) {
44504
44687
  );
44505
44688
  }
44506
44689
  function looksLikeResultRow(value) {
44507
- return typeof value.test_id === "string" || Object.hasOwn(value, "score") || Object.hasOwn(value, "trace") || Object.hasOwn(value, "spans") || Object.hasOwn(value, "target") || Object.hasOwn(value, "grading_path") || Object.hasOwn(value, "timing_path");
44690
+ return typeof value.test_id === "string" || Object.hasOwn(value, "score") || Object.hasOwn(value, "trace") || Object.hasOwn(value, "spans") || Object.hasOwn(value, "target") || Object.hasOwn(value, "summary_path") || Object.hasOwn(value, "grading_path") || Object.hasOwn(value, "timing_path");
44508
44691
  }
44509
44692
  function normalizeResultRow(value, context = {}) {
44510
44693
  if (!isRecord6(value)) {
@@ -44533,7 +44716,8 @@ function normalizeResultRow(value, context = {}) {
44533
44716
  return normalized;
44534
44717
  }
44535
44718
  var RESULT_INDEX_FILENAME = "index.jsonl";
44536
- var TIMING_SOURCE_VALUES = [
44719
+ var RUN_SUMMARY_FILENAME = "summary.json";
44720
+ var TIMING_SOURCE_VALUES2 = [
44537
44721
  "provider_reported",
44538
44722
  "token_estimated",
44539
44723
  "aggregate",
@@ -44557,30 +44741,27 @@ function deduplicateByTestIdTarget(results) {
44557
44741
  return deduped;
44558
44742
  }
44559
44743
  async function aggregateRunDir(runDir, options) {
44560
- const indexPath = path49.join(runDir, RESULT_INDEX_FILENAME);
44744
+ const indexPath = path48.join(runDir, RESULT_INDEX_FILENAME);
44561
44745
  const content = await readFile20(indexPath, "utf8");
44562
44746
  const allResults = parseJsonlResults(content);
44563
44747
  const results = deduplicateByTestIdTarget(allResults);
44564
- const timing = buildTimingArtifact(results);
44565
- const timingPath = path49.join(runDir, "timing.json");
44566
- await writeFile10(timingPath, `${JSON.stringify(timing, null, 2)}
44567
- `, "utf8");
44568
- const plannedTestCount = options?.plannedTestCount ?? await readPlannedTestCount(path49.join(runDir, "benchmark.json"));
44569
- const benchmark = buildBenchmarkArtifact(
44748
+ const plannedTestCount = options?.plannedTestCount ?? await readPlannedTestCount(path48.join(runDir, RUN_SUMMARY_FILENAME));
44749
+ const summary = buildRunSummaryArtifact(
44570
44750
  results,
44571
44751
  options?.evalFile,
44572
44752
  options?.experiment,
44573
- plannedTestCount
44753
+ plannedTestCount,
44754
+ options?.experimentMetadata
44574
44755
  );
44575
- const benchmarkPath = path49.join(runDir, "benchmark.json");
44576
- await writeFile10(benchmarkPath, `${JSON.stringify(benchmark, null, 2)}
44756
+ const summaryPath = path48.join(runDir, RUN_SUMMARY_FILENAME);
44757
+ await writeFile10(summaryPath, `${JSON.stringify(summary, null, 2)}
44577
44758
  `, "utf8");
44578
44759
  const targetSet = new Set(results.map((r) => r.target ?? "unknown"));
44579
- return { benchmarkPath, timingPath, testCount: results.length, targetCount: targetSet.size };
44760
+ return { summaryPath, testCount: results.length, targetCount: targetSet.size };
44580
44761
  }
44581
- async function readPlannedTestCount(benchmarkPath) {
44762
+ async function readPlannedTestCount(summaryPath) {
44582
44763
  try {
44583
- const raw = await readFile20(benchmarkPath, "utf8");
44764
+ const raw = await readFile20(summaryPath, "utf8");
44584
44765
  const parsed = JSON.parse(raw);
44585
44766
  const value = parsed.metadata?.planned_test_count;
44586
44767
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
@@ -44690,6 +44871,60 @@ function toIndexScore(score) {
44690
44871
  function toIndexScores(scores) {
44691
44872
  return scores?.map(toIndexScore);
44692
44873
  }
44874
+ function trialRunDirName(attempt) {
44875
+ return `run-${attempt + 1}`;
44876
+ }
44877
+ function hasPersistedTrialRuns(result) {
44878
+ return (result.trials ?? []).some((trial) => trial.result !== void 0);
44879
+ }
44880
+ function toTrialArtifacts(trials) {
44881
+ if (!trials || trials.length === 0) {
44882
+ return void 0;
44883
+ }
44884
+ return trials.map((trial) => ({
44885
+ attempt: trial.attempt,
44886
+ run_path: trial.result ? trialRunDirName(trial.attempt) : void 0,
44887
+ score: trial.score,
44888
+ verdict: trial.verdict,
44889
+ scores: toIndexScores(trial.scores),
44890
+ error: trial.error,
44891
+ cost_usd: trial.costUsd,
44892
+ execution_status: trial.executionStatus,
44893
+ failure_stage: trial.failureStage,
44894
+ failure_reason_code: trial.failureReasonCode
44895
+ }));
44896
+ }
44897
+ function toIndexTrialArtifacts(result) {
44898
+ return toTrialArtifacts(result.trials) ?? toTrialArtifacts([singleRunTrial(result)]) ?? [];
44899
+ }
44900
+ function toTrialAggregationArtifact(aggregation) {
44901
+ if (!aggregation) {
44902
+ return void 0;
44903
+ }
44904
+ switch (aggregation.strategy) {
44905
+ case "pass_at_k":
44906
+ return {
44907
+ strategy: aggregation.strategy,
44908
+ passed_attempts: aggregation.passedAttempts,
44909
+ total_attempts: aggregation.totalAttempts
44910
+ };
44911
+ case "mean":
44912
+ return {
44913
+ strategy: aggregation.strategy,
44914
+ mean: aggregation.mean,
44915
+ min: aggregation.min,
44916
+ max: aggregation.max
44917
+ };
44918
+ case "confidence_interval":
44919
+ return {
44920
+ strategy: aggregation.strategy,
44921
+ mean: aggregation.mean,
44922
+ ci95_lower: aggregation.ci95Lower,
44923
+ ci95_upper: aggregation.ci95Upper,
44924
+ stddev: aggregation.stddev
44925
+ };
44926
+ }
44927
+ }
44693
44928
  function dropUndefined7(value) {
44694
44929
  return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
44695
44930
  }
@@ -44711,6 +44946,216 @@ function toIndexRerunSource(value) {
44711
44946
  source_timestamp: value.sourceTimestamp
44712
44947
  });
44713
44948
  }
44949
+ function resultDurationSeconds(result) {
44950
+ const durationMs = result.durationMs ?? result.trace?.durationMs ?? result.evalRun?.durationMs ?? 0;
44951
+ return Math.round(durationMs / 1e3 * 1e3) / 1e3;
44952
+ }
44953
+ function resultDurationMs(result) {
44954
+ const durationMs = result.durationMs ?? result.trace?.durationMs ?? result.evalRun?.durationMs;
44955
+ return typeof durationMs === "number" && Number.isFinite(durationMs) ? durationMs : void 0;
44956
+ }
44957
+ function roundMillis(value) {
44958
+ return Math.round(value * 1e3) / 1e3;
44959
+ }
44960
+ function roundSecondsFromMs(value) {
44961
+ return Math.round(value / 1e3 * 1e3) / 1e3;
44962
+ }
44963
+ function repeatAttemptResults(result) {
44964
+ const trialResults = (result.trials ?? []).map((trial) => trial.result).filter((trialResult) => trialResult !== void 0);
44965
+ return trialResults.length > 0 ? trialResults : [result];
44966
+ }
44967
+ function buildRepeatAggregateTimingArtifact(result) {
44968
+ const attemptResults = repeatAttemptResults(result);
44969
+ const timing = buildTimingArtifact(attemptResults);
44970
+ const durationsMs = attemptResults.map(resultDurationMs).filter((durationMs) => durationMs !== void 0);
44971
+ if (durationsMs.length === 0) {
44972
+ return timing;
44973
+ }
44974
+ const stats = computeStats(durationsMs);
44975
+ const minMs = Math.min(...durationsMs);
44976
+ const maxMs = Math.max(...durationsMs);
44977
+ return {
44978
+ ...timing,
44979
+ mean_duration_ms: stats.mean,
44980
+ mean_duration_seconds: roundSecondsFromMs(stats.mean),
44981
+ duration_stats: {
44982
+ count: durationsMs.length,
44983
+ mean_ms: stats.mean,
44984
+ mean_seconds: roundSecondsFromMs(stats.mean),
44985
+ stddev_ms: stats.stddev,
44986
+ stddev_seconds: roundSecondsFromMs(stats.stddev),
44987
+ min_ms: roundMillis(minMs),
44988
+ max_ms: roundMillis(maxMs)
44989
+ }
44990
+ };
44991
+ }
44992
+ function formatRepeatPassRate(passedRuns, totalRuns) {
44993
+ if (totalRuns === 0) {
44994
+ return "0%";
44995
+ }
44996
+ const percent = Math.round(passedRuns / totalRuns * 1e3) / 10;
44997
+ return `${Number.isInteger(percent) ? percent.toFixed(0) : percent.toFixed(1)}%`;
44998
+ }
44999
+ function fallbackRepeatFingerprint(result) {
45000
+ return createHash7("sha256").update(
45001
+ JSON.stringify({
45002
+ test_id: result.testId ?? "unknown",
45003
+ target: result.target ?? "unknown",
45004
+ trial_count: result.trials?.length ?? 0,
45005
+ aggregation: result.aggregation
45006
+ })
45007
+ ).digest("hex");
45008
+ }
45009
+ function buildRepeatCaseSummaryArtifact(result, timing, fingerprint) {
45010
+ const trials = result.trials ?? [];
45011
+ const totalRuns = trials.length > 0 ? trials.length : 1;
45012
+ const passedRuns = trials.length > 0 ? trials.filter((trial) => trial.verdict === "pass").length : result.executionStatus !== "execution_error" && result.score >= DEFAULT_THRESHOLD ? 1 : 0;
45013
+ const fallbackMeanMs = totalRuns > 0 ? roundMillis(timing.duration_ms / totalRuns) : 0;
45014
+ const meanDurationMs = timing.mean_duration_ms ?? fallbackMeanMs;
45015
+ return {
45016
+ total_runs: totalRuns,
45017
+ passed_runs: passedRuns,
45018
+ pass_rate: formatRepeatPassRate(passedRuns, totalRuns),
45019
+ mean_duration_ms: meanDurationMs,
45020
+ mean_duration_seconds: timing.mean_duration_seconds ?? roundSecondsFromMs(meanDurationMs),
45021
+ fingerprint: fingerprint ?? fallbackRepeatFingerprint(result),
45022
+ total_tokens: timing.total_tokens,
45023
+ duration_ms: timing.duration_ms,
45024
+ total_duration_seconds: timing.total_duration_seconds,
45025
+ duration_stats: timing.duration_stats,
45026
+ cost_usd: timing.cost_usd,
45027
+ token_usage: timing.token_usage,
45028
+ usage_sources: timing.usage_sources
45029
+ };
45030
+ }
45031
+ function toVercelRunStatus(trial, result) {
45032
+ if (trial.executionStatus === "execution_error" || result.executionStatus === "execution_error") {
45033
+ return "error";
45034
+ }
45035
+ return trial.verdict === "pass" ? "passed" : "failed";
45036
+ }
45037
+ function toFilePathList(entries) {
45038
+ return entries.map((entry) => isRecord7(entry) && typeof entry.path === "string" ? entry.path : void 0).filter((entry) => entry !== void 0);
45039
+ }
45040
+ function buildVercelRunResultArtifact(params) {
45041
+ const metrics = params.metricsArtifact.metrics;
45042
+ return dropUndefined7({
45043
+ status: toVercelRunStatus(params.trial, params.result),
45044
+ duration_ms: resultDurationMs(params.result),
45045
+ duration_seconds: resultDurationSeconds(params.result),
45046
+ model: params.result.target ?? "unknown",
45047
+ grading_path: "./grading.json",
45048
+ transcript_path: params.hasTranscript ? "./transcript.json" : void 0,
45049
+ transcript_raw_path: params.hasTranscript ? "./transcript-raw.jsonl" : void 0,
45050
+ o11y: {
45051
+ total_turns: metrics.total_turns,
45052
+ tool_calls: metrics.tool_calls,
45053
+ total_tool_calls: metrics.total_tool_calls,
45054
+ web_fetches: metrics.web_fetches,
45055
+ files_read: toFilePathList(metrics.files_read),
45056
+ files_modified: toFilePathList(metrics.files_modified),
45057
+ shell_commands: metrics.shell_commands,
45058
+ errors: metrics.errors,
45059
+ thinking_blocks: metrics.thinking_blocks
45060
+ },
45061
+ output_paths: params.hasOutput ? { answer: "./outputs/answer.md" } : void 0,
45062
+ timing: params.metricsArtifact.timing
45063
+ });
45064
+ }
45065
+ function singleRunTrial(result) {
45066
+ return {
45067
+ attempt: 0,
45068
+ score: result.score,
45069
+ verdict: result.executionStatus !== "execution_error" && result.score >= DEFAULT_THRESHOLD ? "pass" : "fail",
45070
+ scores: result.scores,
45071
+ error: result.error,
45072
+ costUsd: result.costUsd,
45073
+ executionStatus: result.executionStatus,
45074
+ failureStage: result.failureStage,
45075
+ failureReasonCode: result.failureReasonCode,
45076
+ result
45077
+ };
45078
+ }
45079
+ function materializedRunTrials(result) {
45080
+ const persisted = (result.trials ?? []).filter((trial) => trial.result !== void 0);
45081
+ return persisted.length > 0 ? persisted : [singleRunTrial(result)];
45082
+ }
45083
+ async function writeTrialRunArtifacts(params) {
45084
+ const result = params.trial.result;
45085
+ if (!result) {
45086
+ return;
45087
+ }
45088
+ const runDirName = trialRunDirName(params.trial.attempt);
45089
+ const runDir = path48.join(params.parentTestDir, runDirName);
45090
+ const grading = buildGradingArtifact(result, { includeTrials: false });
45091
+ const timing = buildTimingArtifact([result]);
45092
+ const gradingPath = path48.join(runDir, "grading.json");
45093
+ const timingPath = path48.join(runDir, "timing.json");
45094
+ const metricsPath = path48.join(runDir, CANONICAL_METRICS_ARTIFACT_PATH);
45095
+ const outputsDir = path48.join(runDir, "outputs");
45096
+ const answerOutputPath = result.output.length > 0 ? path48.join(outputsDir, "answer.md") : void 0;
45097
+ const attemptRunId = params.runId ? `${params.runId}:${runDirName}` : `${result.testId}:${result.target}:${runDirName}`;
45098
+ const envelope = buildTraceEnvelopeSidecar({
45099
+ result,
45100
+ outputDir: params.outputDir,
45101
+ testDir: runDir,
45102
+ evalPath: resolveEnvelopeEvalPath(result, params.testByTestId, params.evalFile),
45103
+ experiment: params.experiment,
45104
+ runId: attemptRunId,
45105
+ duplicatePolicy: params.duplicatePolicy
45106
+ });
45107
+ const hasTranscript = hasTranscriptProjection(result, envelope);
45108
+ const transcriptPath = hasTranscript ? path48.join(runDir, "transcript.json") : void 0;
45109
+ const transcriptRawPath = hasTranscript ? path48.join(runDir, "transcript-raw.jsonl") : void 0;
45110
+ await mkdir18(runDir, { recursive: true });
45111
+ await writeFile10(gradingPath, `${JSON.stringify(grading, null, 2)}
45112
+ `, "utf8");
45113
+ await writeFile10(timingPath, `${JSON.stringify(timing, null, 2)}
45114
+ `, "utf8");
45115
+ await mkdir18(outputsDir, { recursive: true });
45116
+ if (answerOutputPath) {
45117
+ await writeFile10(answerOutputPath, result.output, "utf8");
45118
+ }
45119
+ const rawProviderLogSource = rawProviderLogSourcePath(result);
45120
+ if (rawProviderLogSource) {
45121
+ await copyRawProviderLogArtifact(rawProviderLogSource, runDir);
45122
+ }
45123
+ if (transcriptPath && transcriptRawPath) {
45124
+ await writeFile10(
45125
+ transcriptPath,
45126
+ `${JSON.stringify(traceEnvelopeToTranscriptMessages(envelope), null, 2)}
45127
+ `,
45128
+ "utf8"
45129
+ );
45130
+ await writeTranscriptJsonl(transcriptRawPath, result, envelope);
45131
+ }
45132
+ const metricsArtifact = await writeMetricsArtifact({
45133
+ filePath: metricsPath,
45134
+ result,
45135
+ envelope,
45136
+ traceArtifactPath: "transcript.json",
45137
+ transcriptArtifactPath: transcriptRawPath ? "transcript-raw.jsonl" : void 0,
45138
+ gradingArtifactPath: "grading.json",
45139
+ timingArtifactPath: "timing.json",
45140
+ timing
45141
+ });
45142
+ await writeFile10(
45143
+ path48.join(runDir, "result.json"),
45144
+ `${JSON.stringify(
45145
+ buildVercelRunResultArtifact({
45146
+ trial: params.trial,
45147
+ result,
45148
+ metricsArtifact,
45149
+ hasTranscript,
45150
+ hasOutput: result.output.length > 0
45151
+ }),
45152
+ null,
45153
+ 2
45154
+ )}
45155
+ `,
45156
+ "utf8"
45157
+ );
45158
+ }
44714
45159
  function toIndexPreparedAttempt(value) {
44715
45160
  if (!isRecord7(value)) {
44716
45161
  return void 0;
@@ -44764,13 +45209,12 @@ function buildExportMetadata(duplicatePolicy, projectionIdentity, options) {
44764
45209
  skipped: options?.skipped
44765
45210
  };
44766
45211
  }
44767
- function buildGradingArtifact(result) {
45212
+ function buildGradingArtifact(result, options) {
44768
45213
  const assertions = buildAssertions(result);
44769
45214
  const passed = assertions.filter((e) => e.passed).length;
44770
45215
  const failed = assertions.filter((e) => !e.passed).length;
44771
45216
  const total = assertions.length;
44772
- const { toolCalls, total: totalToolCalls } = countToolCalls(result);
44773
- const errorsEncountered = result.error ? 1 : 0;
45217
+ const includeTrials = options?.includeTrials ?? true;
44774
45218
  return {
44775
45219
  assertions,
44776
45220
  summary: {
@@ -44779,17 +45223,14 @@ function buildGradingArtifact(result) {
44779
45223
  total,
44780
45224
  pass_rate: total > 0 ? Math.round(passed / total * 1e3) / 1e3 : 0
44781
45225
  },
44782
- execution_metrics: {
44783
- tool_calls: toolCalls,
44784
- total_tool_calls: totalToolCalls,
44785
- errors_encountered: errorsEncountered
44786
- },
44787
45226
  graders: buildEvaluators(result.scores),
44788
45227
  workspace_changes: parseWorkspaceChanges(result.fileChanges),
44789
45228
  conversation: result.conversationId ? {
44790
45229
  turns: result.trace?.messages.filter((message) => message.role === "assistant").length ?? 0,
44791
45230
  conversation_id: result.conversationId
44792
- } : void 0
45231
+ } : void 0,
45232
+ trials: includeTrials ? toIndexTrialArtifacts(result) : void 0,
45233
+ aggregation: includeTrials ? toTrialAggregationArtifact(result.aggregation) : void 0
44793
45234
  };
44794
45235
  }
44795
45236
  function timingMetadataSource(metadata, sourceKey) {
@@ -44797,7 +45238,7 @@ function timingMetadataSource(metadata, sourceKey) {
44797
45238
  const usageSummary = metadata?.usage_summary;
44798
45239
  const legacyKey = sourceKey === "duration" ? "duration_source" : sourceKey === "cost" ? "cost_source" : "token_usage_source";
44799
45240
  const value = isRecord7(usageSources) ? usageSources[sourceKey] : isRecord7(usageSummary) ? usageSummary[legacyKey] : metadata?.[legacyKey];
44800
- return typeof value === "string" && TIMING_SOURCE_VALUES.includes(value) ? value : void 0;
45241
+ return typeof value === "string" && TIMING_SOURCE_VALUES2.includes(value) ? value : void 0;
44801
45242
  }
44802
45243
  function sumMessageTokenUsage(messages) {
44803
45244
  let sawUsage = false;
@@ -44888,7 +45329,7 @@ function buildTimingArtifact(results) {
44888
45329
  }
44889
45330
  };
44890
45331
  }
44891
- function buildBenchmarkArtifact(results, evalFile = "", experiment, plannedTestCount) {
45332
+ function buildRunSummaryArtifact(results, evalFile = "", experiment, plannedTestCount, experimentMetadata) {
44892
45333
  const targetSet = /* @__PURE__ */ new Set();
44893
45334
  const testIdSet = /* @__PURE__ */ new Set();
44894
45335
  for (const result of results) {
@@ -44961,23 +45402,26 @@ function buildBenchmarkArtifact(results, evalFile = "", experiment, plannedTestC
44961
45402
  targets,
44962
45403
  tests_run: testIds,
44963
45404
  experiment,
45405
+ experiment_config: experimentMetadata,
44964
45406
  planned_test_count: plannedTestCount
44965
45407
  },
44966
45408
  run_summary: runSummary,
44967
45409
  per_grader_summary: perEvaluatorSummary,
45410
+ timing: buildTimingArtifact(results),
44968
45411
  notes
44969
45412
  };
44970
45413
  }
44971
- async function writeInitialBenchmarkArtifact(runDir, options) {
45414
+ async function writeInitialRunSummaryArtifact(runDir, options) {
44972
45415
  await mkdir18(runDir, { recursive: true });
44973
- const stub = buildBenchmarkArtifact(
45416
+ const stub = buildRunSummaryArtifact(
44974
45417
  [],
44975
45418
  options.evalFile,
44976
45419
  options.experiment,
44977
- options.plannedTestCount
45420
+ options.plannedTestCount,
45421
+ options.experimentMetadata
44978
45422
  );
44979
- const benchmarkPath = path49.join(runDir, "benchmark.json");
44980
- await writeFile10(benchmarkPath, `${JSON.stringify(stub, null, 2)}
45423
+ const summaryPath = path48.join(runDir, RUN_SUMMARY_FILENAME);
45424
+ await writeFile10(summaryPath, `${JSON.stringify(stub, null, 2)}
44981
45425
  `, "utf8");
44982
45426
  }
44983
45427
  function buildAggregateGradingArtifact(results) {
@@ -45026,23 +45470,10 @@ function buildArtifactSubdir(result) {
45026
45470
  segments.push(safeArtifactPathSegment(evalSet, "default"));
45027
45471
  }
45028
45472
  segments.push(safeTestId(result.testId));
45029
- return path49.posix.join(...segments);
45030
- }
45031
- function formatOutputMarkdown(output) {
45032
- return output.map((msg) => `@[${msg.role}]:
45033
- ${String(msg.content ?? "")}`).join("\n\n");
45034
- }
45035
- function extractInput(result) {
45036
- const input = result.input;
45037
- if (!input) return null;
45038
- if (typeof input === "string") return input;
45039
- if (Array.isArray(input) && input.length > 0) {
45040
- return formatOutputMarkdown(input);
45041
- }
45042
- return null;
45473
+ return path48.posix.join(...segments);
45043
45474
  }
45044
45475
  function toRelativeArtifactPath(outputDir, filePath) {
45045
- return path49.relative(outputDir, filePath).split(path49.sep).join("/");
45476
+ return path48.relative(outputDir, filePath).split(path48.sep).join("/");
45046
45477
  }
45047
45478
  function findResultSourceTest(result, testByTestId) {
45048
45479
  return testByTestId.get(result.testId ?? "unknown");
@@ -45058,15 +45489,12 @@ function rawProviderLogSourcePath(result) {
45058
45489
  const sourcePath = result.rawProviderLogPath?.trim();
45059
45490
  return sourcePath ? sourcePath : void 0;
45060
45491
  }
45061
- function rawProviderLogArtifactPath(testDir) {
45062
- return path49.join(testDir, "provider.log");
45063
- }
45064
45492
  async function copyRawProviderLogArtifact(sourcePath, testDir) {
45065
- const destinationPath = rawProviderLogArtifactPath(testDir);
45066
- if (path49.resolve(sourcePath) === path49.resolve(destinationPath)) {
45493
+ const destinationPath = path48.join(testDir, "provider.log");
45494
+ if (path48.resolve(sourcePath) === path48.resolve(destinationPath)) {
45067
45495
  return destinationPath;
45068
45496
  }
45069
- await mkdir18(path49.dirname(destinationPath), { recursive: true });
45497
+ await mkdir18(path48.dirname(destinationPath), { recursive: true });
45070
45498
  await copyFile3(sourcePath, destinationPath);
45071
45499
  return destinationPath;
45072
45500
  }
@@ -45074,14 +45502,13 @@ function buildTraceEnvelopeSidecar(params) {
45074
45502
  const hasTranscript = resultHasExecutionTraceTranscript(params.result);
45075
45503
  return buildTraceEnvelopeFromEvaluationResult(params.result, {
45076
45504
  evalPath: params.evalPath,
45077
- runId: params.runId ?? path49.basename(params.outputDir),
45505
+ runId: params.runId ?? path48.basename(params.outputDir),
45078
45506
  experiment: params.experiment,
45079
45507
  source: { path: RESULT_INDEX_FILENAME },
45080
45508
  capture: { content: "full", redactionLevel: "none", redactedFields: [] },
45081
45509
  artifacts: {
45082
45510
  trace_path: CANONICAL_TRACE_ARTIFACT_PATH,
45083
45511
  answer_path: params.result.output.length > 0 ? "outputs/answer.md" : void 0,
45084
- response_path: params.result.output.length > 0 ? "outputs/response.md" : void 0,
45085
45512
  transcript_path: hasTranscript ? CANONICAL_TRANSCRIPT_ARTIFACT_PATH : void 0,
45086
45513
  metrics_path: CANONICAL_METRICS_ARTIFACT_PATH,
45087
45514
  raw_provider_log_path: rawProviderLogSourcePath(params.result) ? "provider.log" : void 0
@@ -45089,59 +45516,6 @@ function buildTraceEnvelopeSidecar(params) {
45089
45516
  duplicatePolicy: params.duplicatePolicy
45090
45517
  });
45091
45518
  }
45092
- async function writeTraceEnvelopeSidecar(params) {
45093
- const envelope = buildTraceEnvelopeSidecar(params);
45094
- await writeFile10(
45095
- path49.join(params.testDir, CANONICAL_TRACE_ARTIFACT_PATH),
45096
- `${JSON.stringify(toTraceEnvelopeWire(envelope), null, 2)}
45097
- `,
45098
- "utf8"
45099
- );
45100
- return envelope;
45101
- }
45102
- function buildSidecarArtifactKey(family, runRelativePath) {
45103
- return path49.posix.join(family, runRelativePath);
45104
- }
45105
- async function buildArtifactPointer(params) {
45106
- const content = await readFile20(params.filePath);
45107
- const sha256 = createHash7("sha256").update(content).digest("hex");
45108
- return toResultArtifactPointerWire({
45109
- ref: AGENTV_RESULTS_ARTIFACTS_REF,
45110
- key: buildSidecarArtifactKey(params.family, params.runRelativePath),
45111
- objectVersion: `sha256:${sha256}`,
45112
- path: params.runRelativePath,
45113
- sha256,
45114
- size: content.byteLength,
45115
- schemaVersion: params.schemaVersion,
45116
- mediaType: params.mediaType,
45117
- family: params.family
45118
- });
45119
- }
45120
- async function buildTracePointer(outputDir, tracePath) {
45121
- return buildArtifactPointer({
45122
- filePath: tracePath,
45123
- runRelativePath: toRelativeArtifactPath(outputDir, tracePath),
45124
- family: "traces",
45125
- schemaVersion: EXECUTION_TRACE_SCHEMA_VERSION,
45126
- mediaType: TRACE_JSON_MEDIA_TYPE
45127
- });
45128
- }
45129
- async function buildTranscriptPointer(outputDir, transcriptPath) {
45130
- const pointer = await buildArtifactPointer({
45131
- filePath: transcriptPath,
45132
- runRelativePath: toRelativeArtifactPath(outputDir, transcriptPath),
45133
- family: "transcripts",
45134
- schemaVersion: TRANSCRIPT_SCHEMA_VERSION,
45135
- mediaType: TRANSCRIPT_JSONL_MEDIA_TYPE
45136
- });
45137
- return pointer;
45138
- }
45139
- async function buildArtifactPointers(params) {
45140
- return {
45141
- trace: await buildTracePointer(params.outputDir, params.tracePath),
45142
- ...params.transcriptPath ? { transcript: await buildTranscriptPointer(params.outputDir, params.transcriptPath) } : {}
45143
- };
45144
- }
45145
45519
  function buildIndexArtifactEntry(result, options) {
45146
45520
  return {
45147
45521
  timestamp: result.timestamp,
@@ -45157,14 +45531,17 @@ function buildIndexArtifactEntry(result, options) {
45157
45531
  start_time: result.startTime,
45158
45532
  end_time: result.endTime,
45159
45533
  scores: toIndexScores(result.scores),
45534
+ trials: toIndexTrialArtifacts(result),
45535
+ aggregation: toTrialAggregationArtifact(result.aggregation),
45160
45536
  execution_status: result.executionStatus,
45161
45537
  error: result.error,
45162
45538
  failure_stage: result.failureStage,
45163
45539
  failure_reason_code: result.failureReasonCode,
45164
45540
  workspace_path: result.workspacePath,
45165
45541
  artifact_dir: options.artifactDir ? toRelativeArtifactPath(options.outputDir, options.artifactDir) : void 0,
45166
- grading_path: toRelativeArtifactPath(options.outputDir, options.gradingPath),
45167
- timing_path: toRelativeArtifactPath(options.outputDir, options.timingPath),
45542
+ grading_path: options.gradingPath ? toRelativeArtifactPath(options.outputDir, options.gradingPath) : void 0,
45543
+ timing_path: options.timingPath ? toRelativeArtifactPath(options.outputDir, options.timingPath) : void 0,
45544
+ summary_path: options.summaryPath ? toRelativeArtifactPath(options.outputDir, options.summaryPath) : void 0,
45168
45545
  output_path: options.outputPath ? toRelativeArtifactPath(options.outputDir, options.outputPath) : void 0,
45169
45546
  answer_path: options.answerPath ? toRelativeArtifactPath(options.outputDir, options.answerPath) : void 0,
45170
45547
  trace_path: options.tracePath ? toRelativeArtifactPath(options.outputDir, options.tracePath) : void 0,
@@ -45172,8 +45549,6 @@ function buildIndexArtifactEntry(result, options) {
45172
45549
  metrics_path: options.metricsPath ? toRelativeArtifactPath(options.outputDir, options.metricsPath) : void 0,
45173
45550
  raw_provider_log_path: options.rawProviderLogPath ? toRelativeArtifactPath(options.outputDir, options.rawProviderLogPath) : void 0,
45174
45551
  artifact_pointers: options.artifactPointers,
45175
- input_path: options.inputPath ? toRelativeArtifactPath(options.outputDir, options.inputPath) : void 0,
45176
- response_path: options.responsePath ? toRelativeArtifactPath(options.outputDir, options.responsePath) : void 0,
45177
45552
  ...options.extraIndexFields,
45178
45553
  external_trace: toIndexExternalTrace(result, options.projectionIdentity?.dimensions.runId),
45179
45554
  projection_identity: options.projectionIdentity ? toProjectionIdentityWire(options.projectionIdentity) : void 0,
@@ -45183,10 +45558,10 @@ function buildIndexArtifactEntry(result, options) {
45183
45558
  }
45184
45559
  function buildResultIndexArtifact(result, extraIndexFields, options) {
45185
45560
  const artifactSubdir = buildArtifactSubdir(result);
45186
- const input = extractInput(result);
45187
45561
  const hasAnswer = result.output.length > 0;
45188
45562
  const hasTranscript = resultHasExecutionTraceTranscript(result);
45189
- const hasRawProviderLog = rawProviderLogSourcePath(result) !== void 0;
45563
+ const isSingleRun = !hasPersistedTrialRuns(result);
45564
+ const singleRunDir = path48.posix.join(artifactSubdir, trialRunDirName(0));
45190
45565
  return {
45191
45566
  timestamp: result.timestamp,
45192
45567
  test_id: result.testId ?? "unknown",
@@ -45201,23 +45576,22 @@ function buildResultIndexArtifact(result, extraIndexFields, options) {
45201
45576
  start_time: result.startTime,
45202
45577
  end_time: result.endTime,
45203
45578
  scores: toIndexScores(result.scores),
45579
+ trials: toIndexTrialArtifacts(result),
45580
+ aggregation: toTrialAggregationArtifact(result.aggregation),
45204
45581
  execution_status: result.executionStatus,
45205
45582
  error: result.error,
45206
45583
  failure_stage: result.failureStage,
45207
45584
  failure_reason_code: result.failureReasonCode,
45208
45585
  workspace_path: result.workspacePath,
45209
45586
  artifact_dir: artifactSubdir,
45210
- grading_path: path49.posix.join(artifactSubdir, "grading.json"),
45211
- timing_path: path49.posix.join(artifactSubdir, "timing.json"),
45212
- input_path: input ? path49.posix.join(artifactSubdir, "input.md") : void 0,
45213
- output_path: hasAnswer ? path49.posix.join(artifactSubdir, "outputs", "answer.md") : void 0,
45214
- answer_path: hasAnswer ? path49.posix.join(artifactSubdir, "outputs", "answer.md") : void 0,
45215
- trace_path: path49.posix.join(artifactSubdir, CANONICAL_TRACE_ARTIFACT_PATH),
45216
- transcript_path: hasTranscript ? path49.posix.join(artifactSubdir, CANONICAL_TRANSCRIPT_ARTIFACT_PATH) : void 0,
45217
- metrics_path: path49.posix.join(artifactSubdir, CANONICAL_METRICS_ARTIFACT_PATH),
45218
- raw_provider_log_path: hasRawProviderLog ? path49.posix.join(artifactSubdir, "provider.log") : void 0,
45587
+ summary_path: path48.posix.join(artifactSubdir, RUN_SUMMARY_FILENAME),
45588
+ grading_path: isSingleRun ? path48.posix.join(singleRunDir, "grading.json") : void 0,
45589
+ timing_path: isSingleRun ? path48.posix.join(singleRunDir, "timing.json") : void 0,
45590
+ metrics_path: isSingleRun ? path48.posix.join(singleRunDir, CANONICAL_METRICS_ARTIFACT_PATH) : void 0,
45591
+ output_path: isSingleRun && hasAnswer ? path48.posix.join(singleRunDir, "outputs", "answer.md") : void 0,
45592
+ answer_path: isSingleRun && hasAnswer ? path48.posix.join(singleRunDir, "outputs", "answer.md") : void 0,
45593
+ transcript_path: isSingleRun && hasTranscript ? path48.posix.join(singleRunDir, "transcript-raw.jsonl") : void 0,
45219
45594
  artifact_pointers: options?.artifactPointers,
45220
- response_path: hasAnswer ? path49.posix.join(artifactSubdir, "outputs", "response.md") : void 0,
45221
45595
  ...extraIndexFields,
45222
45596
  external_trace: toIndexExternalTrace(result, options?.projectionIdentity?.dimensions.runId),
45223
45597
  projection_identity: options?.projectionIdentity ? toProjectionIdentityWire(options.projectionIdentity) : void 0,
@@ -45242,15 +45616,20 @@ async function writeTranscriptJsonl(filePath, result, envelope) {
45242
45616
  ` : "";
45243
45617
  await writeFile10(filePath, content, "utf8");
45244
45618
  }
45245
- async function writeMetricsArtifact(params) {
45619
+ function buildMetricsArtifactPayload(params) {
45246
45620
  const artifact = buildMetricsArtifact(params.result, params.envelope, {
45247
- tracePath: CANONICAL_TRACE_ARTIFACT_PATH,
45248
- transcriptPath: params.transcriptPath ? CANONICAL_TRANSCRIPT_ARTIFACT_PATH : void 0,
45249
- gradingPath: "grading.json",
45250
- timingPath: "timing.json"
45621
+ tracePath: params.traceArtifactPath ?? CANONICAL_TRACE_ARTIFACT_PATH,
45622
+ transcriptPath: params.transcriptArtifactPath ?? (params.transcriptPath ? CANONICAL_TRANSCRIPT_ARTIFACT_PATH : void 0),
45623
+ gradingPath: params.gradingArtifactPath ?? "grading.json",
45624
+ timingPath: params.timingArtifactPath === null ? void 0 : params.timingArtifactPath ?? "timing.json"
45251
45625
  });
45252
- await writeFile10(params.filePath, `${JSON.stringify(artifact, null, 2)}
45626
+ return params.timing ? { ...artifact, timing: params.timing } : artifact;
45627
+ }
45628
+ async function writeMetricsArtifact(params) {
45629
+ const artifactWithTiming = buildMetricsArtifactPayload(params);
45630
+ await writeFile10(params.filePath, `${JSON.stringify(artifactWithTiming, null, 2)}
45253
45631
  `, "utf8");
45632
+ return artifactWithTiming;
45254
45633
  }
45255
45634
  function indexRecordKey(record2) {
45256
45635
  if (!isRecord7(record2)) {
@@ -45268,7 +45647,7 @@ function projectionIdentityRecordKey(record2) {
45268
45647
  return typeof id === "string" && id.trim().length > 0 ? id : void 0;
45269
45648
  }
45270
45649
  async function readExistingIndexRecords(outputDir) {
45271
- const indexPath = path49.join(outputDir, RESULT_INDEX_FILENAME);
45650
+ const indexPath = path48.join(outputDir, RESULT_INDEX_FILENAME);
45272
45651
  const content = await readFile20(indexPath, "utf8").catch(() => void 0);
45273
45652
  if (content === void 0) {
45274
45653
  return [];
@@ -45321,7 +45700,7 @@ async function rewriteExistingIndexRecords(outputDir, replacements) {
45321
45700
  if (replacements.length === 0) {
45322
45701
  return;
45323
45702
  }
45324
- const indexPath = path49.join(outputDir, RESULT_INDEX_FILENAME);
45703
+ const indexPath = path48.join(outputDir, RESULT_INDEX_FILENAME);
45325
45704
  const content = await readFile20(indexPath, "utf8").catch(() => void 0);
45326
45705
  if (content === void 0) {
45327
45706
  return;
@@ -45478,39 +45857,10 @@ async function writePerTestArtifacts(results, outputDir, options) {
45478
45857
  const testByTestId = new Map((options?.sourceTests ?? []).map((test) => [test.id, test]));
45479
45858
  const indexRecords = [];
45480
45859
  for (const result of results) {
45481
- const grading = buildGradingArtifact(result);
45482
- const timing = buildTimingArtifact([result]);
45483
45860
  const artifactSubdir = buildArtifactSubdir(result);
45484
- const testDir = path49.join(outputDir, artifactSubdir);
45861
+ const testDir = path48.join(outputDir, artifactSubdir);
45485
45862
  await mkdir18(testDir, { recursive: true });
45486
- await writeFile10(
45487
- path49.join(testDir, "grading.json"),
45488
- `${JSON.stringify(grading, null, 2)}
45489
- `,
45490
- "utf8"
45491
- );
45492
- await writeFile10(
45493
- path49.join(testDir, "timing.json"),
45494
- `${JSON.stringify(timing, null, 2)}
45495
- `,
45496
- "utf8"
45497
- );
45498
- const input = extractInput(result);
45499
- if (input) {
45500
- await writeFile10(path49.join(testDir, "input.md"), input, "utf8");
45501
- }
45502
- const outputsDir = path49.join(testDir, "outputs");
45503
- await mkdir18(outputsDir, { recursive: true });
45504
- if (result.output.length > 0) {
45505
- await writeFile10(path49.join(outputsDir, "answer.md"), result.output, "utf8");
45506
- await writeFile10(path49.join(outputsDir, "response.md"), result.output, "utf8");
45507
- }
45508
- const rawProviderLogSource = rawProviderLogSourcePath(result);
45509
- if (rawProviderLogSource) {
45510
- await copyRawProviderLogArtifact(rawProviderLogSource, testDir);
45511
- }
45512
- const tracePath = path49.join(testDir, CANONICAL_TRACE_ARTIFACT_PATH);
45513
- const envelope = await writeTraceEnvelopeSidecar({
45863
+ const envelope = buildTraceEnvelopeSidecar({
45514
45864
  result,
45515
45865
  outputDir,
45516
45866
  testDir,
@@ -45519,22 +45869,34 @@ async function writePerTestArtifacts(results, outputDir, options) {
45519
45869
  runId: options?.runId,
45520
45870
  duplicatePolicy
45521
45871
  });
45522
- const transcriptPath = hasTranscriptProjection(result, envelope) ? path49.join(testDir, CANONICAL_TRANSCRIPT_ARTIFACT_PATH) : void 0;
45523
- if (transcriptPath) {
45524
- await writeTranscriptJsonl(transcriptPath, result, envelope);
45872
+ const projectionIdentity = envelope.projectionIdentity;
45873
+ if (!projectionIdentity) {
45874
+ throw new Error(`Result ${result.testId ?? "unknown"} is missing projection identity`);
45525
45875
  }
45526
- const metricsPath = path49.join(testDir, CANONICAL_METRICS_ARTIFACT_PATH);
45527
- await writeMetricsArtifact({
45528
- filePath: metricsPath,
45529
- result,
45530
- envelope,
45531
- transcriptPath
45532
- });
45533
- const artifactPointers = await buildArtifactPointers({
45534
- outputDir,
45535
- tracePath,
45536
- transcriptPath
45537
- });
45876
+ const caseSummaryPath = path48.join(testDir, RUN_SUMMARY_FILENAME);
45877
+ const aggregateTiming = buildRepeatAggregateTimingArtifact(result);
45878
+ const summary = buildRepeatCaseSummaryArtifact(result, aggregateTiming, projectionIdentity.id);
45879
+ await writeFile10(caseSummaryPath, `${JSON.stringify(summary, null, 2)}
45880
+ `, "utf8");
45881
+ for (const trial of materializedRunTrials(result)) {
45882
+ await writeTrialRunArtifacts({
45883
+ trial,
45884
+ parentTestDir: testDir,
45885
+ outputDir,
45886
+ evalFile: options?.evalFile,
45887
+ experiment: options?.experiment,
45888
+ runId: options?.runId,
45889
+ duplicatePolicy,
45890
+ testByTestId
45891
+ });
45892
+ }
45893
+ const isSingleRun = !hasPersistedTrialRuns(result);
45894
+ const singleRunDir = path48.join(testDir, trialRunDirName(0));
45895
+ const singleAnswerPath = isSingleRun && result.output.length > 0 ? path48.join(singleRunDir, "outputs", "answer.md") : void 0;
45896
+ const singleTranscriptPath = isSingleRun && hasTranscriptProjection(result, envelope) ? path48.join(singleRunDir, "transcript-raw.jsonl") : void 0;
45897
+ const singleGradingPath = isSingleRun ? path48.join(singleRunDir, "grading.json") : void 0;
45898
+ const singleTimingPath = isSingleRun ? path48.join(singleRunDir, "timing.json") : void 0;
45899
+ const singleMetricsPath = isSingleRun ? path48.join(singleRunDir, CANONICAL_METRICS_ARTIFACT_PATH) : void 0;
45538
45900
  const extraIndexFields = await collectAdditionalIndexFields(
45539
45901
  result,
45540
45902
  outputDir,
@@ -45543,10 +45905,19 @@ async function writePerTestArtifacts(results, outputDir, options) {
45543
45905
  options?.additionalArtifacts
45544
45906
  );
45545
45907
  indexRecords.push({
45546
- ...buildResultIndexArtifact(result, extraIndexFields, {
45547
- projectionIdentity: envelope.projectionIdentity,
45548
- duplicatePolicy,
45549
- artifactPointers
45908
+ ...buildIndexArtifactEntry(result, {
45909
+ outputDir,
45910
+ artifactDir: testDir,
45911
+ summaryPath: caseSummaryPath,
45912
+ gradingPath: singleGradingPath,
45913
+ timingPath: singleTimingPath,
45914
+ metricsPath: singleMetricsPath,
45915
+ outputPath: singleAnswerPath,
45916
+ answerPath: singleAnswerPath,
45917
+ transcriptPath: singleTranscriptPath,
45918
+ extraIndexFields,
45919
+ projectionIdentity,
45920
+ duplicatePolicy
45550
45921
  }),
45551
45922
  experiment: options?.experiment
45552
45923
  });
@@ -45555,9 +45926,8 @@ async function writePerTestArtifacts(results, outputDir, options) {
45555
45926
  }
45556
45927
  async function writeArtifactsFromResults(results, outputDir, options) {
45557
45928
  const testArtifactDir = outputDir;
45558
- const timingPath = path49.join(outputDir, "timing.json");
45559
- const benchmarkPath = path49.join(outputDir, "benchmark.json");
45560
- const indexPath = path49.join(outputDir, RESULT_INDEX_FILENAME);
45929
+ const summaryPath = path48.join(outputDir, RUN_SUMMARY_FILENAME);
45930
+ const indexPath = path48.join(outputDir, RESULT_INDEX_FILENAME);
45561
45931
  await mkdir18(outputDir, { recursive: true });
45562
45932
  const duplicatePolicy = options?.duplicatePolicy ?? "update";
45563
45933
  const existingRecords = await readExistingIndexRecords(outputDir);
@@ -45566,17 +45936,9 @@ async function writeArtifactsFromResults(results, outputDir, options) {
45566
45936
  const testByTestId = new Map((options?.sourceTests ?? []).map((test) => [test.id, test]));
45567
45937
  const emittedIdentityIds = /* @__PURE__ */ new Set();
45568
45938
  const plans = results.map((result) => {
45569
- const grading = buildGradingArtifact(result);
45570
- const timing2 = buildTimingArtifact([result]);
45571
45939
  const artifactSubdir = buildArtifactSubdir(result);
45572
- const testDir = path49.join(outputDir, artifactSubdir);
45573
- const gradingPath = path49.join(testDir, "grading.json");
45574
- const perTestTimingPath = path49.join(testDir, "timing.json");
45575
- const input = extractInput(result);
45576
- const inputPath = input ? path49.join(testDir, "input.md") : void 0;
45577
- const outputsDir = path49.join(testDir, "outputs");
45578
- const answerPath = result.output.length > 0 ? path49.join(outputsDir, "answer.md") : void 0;
45579
- const responsePath = result.output.length > 0 ? path49.join(outputsDir, "response.md") : void 0;
45940
+ const testDir = path48.join(outputDir, artifactSubdir);
45941
+ const caseSummaryPath = path48.join(testDir, RUN_SUMMARY_FILENAME);
45580
45942
  const envelope = buildTraceEnvelopeSidecar({
45581
45943
  result,
45582
45944
  outputDir,
@@ -45586,35 +45948,29 @@ async function writeArtifactsFromResults(results, outputDir, options) {
45586
45948
  runId: options?.runId,
45587
45949
  duplicatePolicy
45588
45950
  });
45589
- const transcriptPath = hasTranscriptProjection(result, envelope) ? path49.join(testDir, CANONICAL_TRANSCRIPT_ARTIFACT_PATH) : void 0;
45590
- const tracePath = path49.join(testDir, CANONICAL_TRACE_ARTIFACT_PATH);
45591
- const metricsPath = path49.join(testDir, CANONICAL_METRICS_ARTIFACT_PATH);
45592
- const rawProviderLogSource = rawProviderLogSourcePath(result);
45593
- const rawProviderLogPath = rawProviderLogSource ? rawProviderLogArtifactPath(testDir) : void 0;
45594
45951
  const projectionIdentity = envelope.projectionIdentity;
45595
45952
  if (!projectionIdentity) {
45596
45953
  throw new Error(`Result ${result.testId ?? "unknown"} is missing projection identity`);
45597
45954
  }
45598
45955
  const identityId = projectionIdentity.id;
45956
+ const isSingleRun = !hasPersistedTrialRuns(result);
45957
+ const singleRunDir = path48.join(testDir, trialRunDirName(0));
45958
+ const singleAnswerPath = isSingleRun && result.output.length > 0 ? path48.join(singleRunDir, "outputs", "answer.md") : void 0;
45959
+ const singleTranscriptPath = isSingleRun && hasTranscriptProjection(result, envelope) ? path48.join(singleRunDir, "transcript-raw.jsonl") : void 0;
45960
+ const singleGradingPath = isSingleRun ? path48.join(singleRunDir, "grading.json") : void 0;
45961
+ const singleTimingPath = isSingleRun ? path48.join(singleRunDir, "timing.json") : void 0;
45962
+ const singleMetricsPath = isSingleRun ? path48.join(singleRunDir, CANONICAL_METRICS_ARTIFACT_PATH) : void 0;
45599
45963
  return {
45600
45964
  result,
45601
- grading,
45602
- timing: timing2,
45603
45965
  testDir,
45604
- gradingPath,
45605
- perTestTimingPath,
45606
- input,
45607
- inputPath,
45608
- outputsDir,
45609
- answerPath,
45610
- responsePath,
45611
- tracePath,
45612
- metricsPath,
45613
- envelope,
45966
+ caseSummaryPath,
45614
45967
  projectionIdentity,
45615
- transcriptPath,
45616
- rawProviderLogSource,
45617
- rawProviderLogPath,
45968
+ isSingleRun,
45969
+ singleAnswerPath,
45970
+ singleTranscriptPath,
45971
+ singleGradingPath,
45972
+ singleTimingPath,
45973
+ singleMetricsPath,
45618
45974
  identityId
45619
45975
  };
45620
45976
  });
@@ -45631,7 +45987,7 @@ async function writeArtifactsFromResults(results, outputDir, options) {
45631
45987
  }
45632
45988
  }
45633
45989
  for (const plan of plans) {
45634
- const { result, envelope, identityId } = plan;
45990
+ const { result, identityId } = plan;
45635
45991
  const existing = existingByIdentity.get(identityId);
45636
45992
  if (duplicatePolicy === "skip" && existing) {
45637
45993
  indexRecords.push(skippedExistingRecord(existing, plan.projectionIdentity, duplicatePolicy));
@@ -45642,41 +45998,26 @@ async function writeArtifactsFromResults(results, outputDir, options) {
45642
45998
  continue;
45643
45999
  }
45644
46000
  await mkdir18(plan.testDir, { recursive: true });
45645
- await writeFile10(plan.gradingPath, `${JSON.stringify(plan.grading, null, 2)}
45646
- `, "utf8");
45647
- await writeFile10(plan.perTestTimingPath, `${JSON.stringify(plan.timing, null, 2)}
45648
- `, "utf8");
45649
- if (plan.inputPath && plan.input) {
45650
- await writeFile10(plan.inputPath, plan.input, "utf8");
45651
- }
45652
- await mkdir18(plan.outputsDir, { recursive: true });
45653
- if (plan.answerPath && plan.responsePath) {
45654
- await writeFile10(plan.answerPath, result.output, "utf8");
45655
- await writeFile10(plan.responsePath, result.output, "utf8");
45656
- }
45657
- if (plan.rawProviderLogSource) {
45658
- await copyRawProviderLogArtifact(plan.rawProviderLogSource, plan.testDir);
45659
- }
45660
- await writeFile10(
45661
- plan.tracePath,
45662
- `${JSON.stringify(toTraceEnvelopeWire(envelope), null, 2)}
45663
- `,
45664
- "utf8"
46001
+ const aggregateTiming = buildRepeatAggregateTimingArtifact(result);
46002
+ const summary2 = buildRepeatCaseSummaryArtifact(
46003
+ result,
46004
+ aggregateTiming,
46005
+ options?.experimentMetadata?.fingerprint ?? plan.projectionIdentity.id
45665
46006
  );
45666
- if (plan.transcriptPath) {
45667
- await writeTranscriptJsonl(plan.transcriptPath, result, envelope);
46007
+ await writeFile10(plan.caseSummaryPath, `${JSON.stringify(summary2, null, 2)}
46008
+ `, "utf8");
46009
+ for (const trial of materializedRunTrials(result)) {
46010
+ await writeTrialRunArtifacts({
46011
+ trial,
46012
+ parentTestDir: plan.testDir,
46013
+ outputDir,
46014
+ evalFile: options?.evalFile,
46015
+ experiment: options?.experiment,
46016
+ runId: options?.runId,
46017
+ duplicatePolicy,
46018
+ testByTestId
46019
+ });
45668
46020
  }
45669
- await writeMetricsArtifact({
45670
- filePath: plan.metricsPath,
45671
- result,
45672
- envelope,
45673
- transcriptPath: plan.transcriptPath
45674
- });
45675
- const artifactPointers = await buildArtifactPointers({
45676
- outputDir,
45677
- tracePath: plan.tracePath,
45678
- transcriptPath: plan.transcriptPath
45679
- });
45680
46021
  const extraIndexFields = await collectAdditionalIndexFields(
45681
46022
  result,
45682
46023
  outputDir,
@@ -45688,17 +46029,13 @@ async function writeArtifactsFromResults(results, outputDir, options) {
45688
46029
  ...buildIndexArtifactEntry(result, {
45689
46030
  outputDir,
45690
46031
  artifactDir: plan.testDir,
45691
- gradingPath: plan.gradingPath,
45692
- timingPath: plan.perTestTimingPath,
45693
- outputPath: plan.answerPath,
45694
- answerPath: plan.answerPath,
45695
- tracePath: plan.tracePath,
45696
- transcriptPath: plan.transcriptPath,
45697
- metricsPath: plan.metricsPath,
45698
- artifactPointers,
45699
- rawProviderLogPath: plan.rawProviderLogPath,
45700
- inputPath: plan.inputPath,
45701
- responsePath: plan.responsePath,
46032
+ summaryPath: plan.caseSummaryPath,
46033
+ gradingPath: plan.singleGradingPath,
46034
+ timingPath: plan.singleTimingPath,
46035
+ metricsPath: plan.singleMetricsPath,
46036
+ outputPath: plan.singleAnswerPath,
46037
+ answerPath: plan.singleAnswerPath,
46038
+ transcriptPath: plan.singleTranscriptPath,
45702
46039
  extraIndexFields,
45703
46040
  projectionIdentity: plan.projectionIdentity,
45704
46041
  duplicatePolicy
@@ -45717,20 +46054,18 @@ async function writeArtifactsFromResults(results, outputDir, options) {
45717
46054
  }
45718
46055
  emittedIdentityIds.add(identityId);
45719
46056
  }
45720
- const timing = buildTimingArtifact(results);
45721
- await writeFile10(timingPath, `${JSON.stringify(timing, null, 2)}
45722
- `, "utf8");
45723
- const plannedTestCount = options?.plannedTestCount ?? await readPlannedTestCount(benchmarkPath);
45724
- const benchmark = buildBenchmarkArtifact(
46057
+ const plannedTestCount = options?.plannedTestCount ?? await readPlannedTestCount(summaryPath);
46058
+ const summary = buildRunSummaryArtifact(
45725
46059
  results,
45726
46060
  options?.evalFile,
45727
46061
  options?.experiment,
45728
- plannedTestCount
46062
+ plannedTestCount,
46063
+ options?.experimentMetadata
45729
46064
  );
45730
- await writeFile10(benchmarkPath, `${JSON.stringify(benchmark, null, 2)}
46065
+ await writeFile10(summaryPath, `${JSON.stringify(summary, null, 2)}
45731
46066
  `, "utf8");
45732
46067
  await writeJsonlFile(indexPath, indexRecords);
45733
- return { testArtifactDir, timingPath, benchmarkPath, indexPath };
46068
+ return { testArtifactDir, summaryPath, indexPath };
45734
46069
  }
45735
46070
  async function evaluate(config2) {
45736
46071
  const startTime = Date.now();
@@ -45777,7 +46112,7 @@ async function evaluate(config2) {
45777
46112
  cliNoCache: false,
45778
46113
  yamlCache: config2.cache === void 0 ? materialized.cache : void 0
45779
46114
  });
45780
- const cache = cacheEnabled ? new ResponseCache(materialized.cachePath ? path50.resolve(materialized.cachePath) : void 0) : void 0;
46115
+ const cache = cacheEnabled ? new ResponseCache(materialized.cachePath ? path49.resolve(materialized.cachePath) : void 0) : void 0;
45781
46116
  const results = await runEvaluation({
45782
46117
  testFilePath,
45783
46118
  repoRoot,
@@ -45800,16 +46135,15 @@ async function evaluate(config2) {
45800
46135
  });
45801
46136
  const allResults = collectedResults.length > 0 ? collectedResults : [...results];
45802
46137
  const durationMs = Date.now() - startTime;
45803
- const outputDir = config2.outputDir ? path50.resolve(config2.outputDir) : void 0;
46138
+ const outputDir = config2.outputDir ? path49.resolve(config2.outputDir) : void 0;
45804
46139
  const artifacts = outputDir ? await writeArtifactsFromResults(allResults, outputDir, {
45805
46140
  evalFile: config2.specFile ? testFilePath : "",
45806
46141
  experiment: config2.experiment,
45807
46142
  sourceTests: materialized.tests
45808
- }).then(({ benchmarkPath, indexPath, timingPath }) => ({
46143
+ }).then(({ summaryPath, indexPath }) => ({
45809
46144
  runDir: outputDir,
45810
- benchmarkPath,
45811
- indexPath,
45812
- timingPath
46145
+ summaryPath,
46146
+ indexPath
45813
46147
  })) : void 0;
45814
46148
  return {
45815
46149
  results: allResults,
@@ -45820,7 +46154,7 @@ async function evaluate(config2) {
45820
46154
  async function materializeEvalConfig(config2, options) {
45821
46155
  const baseDir = options?.baseDir ?? process.cwd();
45822
46156
  const repoRoot = options?.repoRoot ?? await findGitRoot(baseDir) ?? baseDir;
45823
- const testFilePath = config2.specFile ? path50.resolve(baseDir, config2.specFile) : path50.join(baseDir, "__programmatic__.yaml");
46157
+ const testFilePath = config2.specFile ? path49.resolve(baseDir, config2.specFile) : path49.join(baseDir, "__programmatic__.yaml");
45824
46158
  const effectiveFilter = options?.filter ?? config2.filter;
45825
46159
  if (config2.specFile) {
45826
46160
  const suite = await loadTestSuite(testFilePath, repoRoot, {
@@ -45897,7 +46231,7 @@ function convertAssertions(entries) {
45897
46231
  }
45898
46232
  function buildInlineEvalTests(config2, options) {
45899
46233
  const suiteWorkspace = config2.beforeAll ? { hooks: { before_all: toBeforeAllHook(config2.beforeAll) } } : void 0;
45900
- const derivedSuiteName = path50.basename(options.testFilePath).replace(/\.eval\.[cm]?ts$/i, "").replace(/\.[cm]?ts$/i, "");
46234
+ const derivedSuiteName = path49.basename(options.testFilePath).replace(/\.eval\.[cm]?ts$/i, "").replace(/\.[cm]?ts$/i, "");
45901
46235
  const suiteName = config2.metadata?.name ?? (derivedSuiteName || "eval");
45902
46236
  return (config2.tests ?? []).filter((test) => !options.filter || matchesFilter4(test.id, options.filter)).map((test) => {
45903
46237
  const isConversation = test.mode === "conversation" || test.turns && test.turns.length > 0;
@@ -45993,10 +46327,10 @@ function computeSummary(results, durationMs, threshold = DEFAULT_THRESHOLD) {
45993
46327
  var TARGET_FILE_CANDIDATES = [".agentv/targets.yaml", ".agentv/targets.yml"];
45994
46328
  async function discoverDefaultTarget(repoRoot) {
45995
46329
  const cwd = process.cwd();
45996
- const chain = buildDirectoryChain(path50.join(cwd, "_placeholder"), repoRoot);
46330
+ const chain = buildDirectoryChain(path49.join(cwd, "_placeholder"), repoRoot);
45997
46331
  for (const dir of chain) {
45998
46332
  for (const candidate of TARGET_FILE_CANDIDATES) {
45999
- const targetsPath = path50.join(dir, candidate);
46333
+ const targetsPath = path49.join(dir, candidate);
46000
46334
  if (!existsSync7(targetsPath)) continue;
46001
46335
  try {
46002
46336
  const definitions = await readTargetDefinitions(targetsPath);
@@ -46013,7 +46347,7 @@ async function loadEnvHierarchy(repoRoot, startPath) {
46013
46347
  const chain = buildDirectoryChain(startPath, repoRoot);
46014
46348
  const envFiles = [];
46015
46349
  for (const dir of chain) {
46016
- const envPath = path50.join(dir, ".env");
46350
+ const envPath = path49.join(dir, ".env");
46017
46351
  if (existsSync7(envPath)) envFiles.push(envPath);
46018
46352
  }
46019
46353
  for (let i = 0; i < envFiles.length; i++) {
@@ -46041,7 +46375,7 @@ var EXPORT_NAMES = ["default", "config", "evalConfig"];
46041
46375
  var SDK_EVAL_SUITE_SYMBOL = Symbol.for("@agentv/sdk/eval-suite");
46042
46376
  var SDK_TO_EVAL_YAML_OBJECT_SYMBOL = Symbol.for("@agentv/sdk/to-eval-yaml-object");
46043
46377
  async function loadTsEvalFile(filePath) {
46044
- const absolutePath = path51.resolve(filePath);
46378
+ const absolutePath = path50.resolve(filePath);
46045
46379
  const moduleUrl = pathToFileURL2(absolutePath).href;
46046
46380
  const module = await import(moduleUrl);
46047
46381
  let config2;
@@ -46071,7 +46405,7 @@ async function loadTsEvalSuite(filePath, repoRoot, options) {
46071
46405
  }
46072
46406
  const materialized = await materializeEvalConfig(config2, {
46073
46407
  repoRoot,
46074
- baseDir: path51.dirname(absolutePath),
46408
+ baseDir: path50.dirname(absolutePath),
46075
46409
  filter: options?.filter,
46076
46410
  category: options?.category
46077
46411
  });
@@ -46124,6 +46458,14 @@ export {
46124
46458
  isGraderKind,
46125
46459
  RUBRIC_OPERATOR_VALUES,
46126
46460
  parseYamlValue,
46461
+ AGENTV_CONFIG_FILE_NAME,
46462
+ AGENTV_CONFIG_YML_FILE_NAME,
46463
+ AGENTV_LOCAL_CONFIG_FILE_NAME,
46464
+ AGENTV_LOCAL_CONFIG_YML_FILE_NAME,
46465
+ getLocalConfigPath,
46466
+ isAgentVConfigFileName,
46467
+ isPlainConfigObject,
46468
+ mergeConfigObjects,
46127
46469
  getAgentvConfigDir,
46128
46470
  getAgentvHome,
46129
46471
  getAgentvDataDir,
@@ -46151,6 +46493,8 @@ export {
46151
46493
  interpolateEnv,
46152
46494
  loadCasesFromFile,
46153
46495
  loadCasesFromDirectory,
46496
+ buildSearchRoots2,
46497
+ loadPromptMdFallback,
46154
46498
  ResponseCache,
46155
46499
  shouldEnableCache,
46156
46500
  shouldSkipCacheForTemperature,
@@ -46356,10 +46700,10 @@ export {
46356
46700
  extractTargetsFromSuite,
46357
46701
  extractWorkersFromSuite,
46358
46702
  extractTargetsFromTestCase,
46359
- extractTrialsConfig,
46360
46703
  extractCacheConfig,
46361
46704
  extractFailOnError,
46362
46705
  extractThreshold,
46706
+ resolveDefaultExperimentReference,
46363
46707
  resolveResultsConfigForProject,
46364
46708
  detectFormat,
46365
46709
  parseRepoConfig,
@@ -46403,13 +46747,14 @@ export {
46403
46747
  ResultRowSchemaError,
46404
46748
  normalizeResultRow,
46405
46749
  RESULT_INDEX_FILENAME,
46750
+ RUN_SUMMARY_FILENAME,
46406
46751
  buildTestTargetKey,
46407
46752
  deduplicateByTestIdTarget,
46408
46753
  aggregateRunDir,
46409
46754
  buildGradingArtifact,
46410
46755
  buildTimingArtifact,
46411
- buildBenchmarkArtifact,
46412
- writeInitialBenchmarkArtifact,
46756
+ buildRunSummaryArtifact,
46757
+ writeInitialRunSummaryArtifact,
46413
46758
  buildAggregateGradingArtifact,
46414
46759
  buildIndexArtifactEntry,
46415
46760
  buildResultIndexArtifact,
@@ -46421,4 +46766,4 @@ export {
46421
46766
  loadTsEvalFile,
46422
46767
  loadTsEvalSuite
46423
46768
  };
46424
- //# sourceMappingURL=chunk-5DYGN547.js.map
46769
+ //# sourceMappingURL=chunk-GZJMODLW.js.map