agentv 4.7.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -301,7 +301,7 @@ var require_dist = __commonJS({
301
301
  }
302
302
  });
303
303
 
304
- // ../../packages/core/dist/chunk-75RFVESM.js
304
+ // ../../packages/core/dist/chunk-VCVVKCC4.js
305
305
  import { constants } from "node:fs";
306
306
  import { access, readFile } from "node:fs/promises";
307
307
  import path from "node:path";
@@ -419,7 +419,7 @@ __export(external_exports2, {
419
419
  void: () => voidType
420
420
  });
421
421
 
422
- // ../../packages/core/dist/chunk-75RFVESM.js
422
+ // ../../packages/core/dist/chunk-VCVVKCC4.js
423
423
  import { readFile as readFile2 } from "node:fs/promises";
424
424
  import path3 from "node:path";
425
425
  import fg from "fast-glob";
@@ -1416,6 +1416,52 @@ function resolveCopilotSdkConfig(target, env, evalFilePath) {
1416
1416
  );
1417
1417
  const logFormat = normalizeCopilotLogFormat(logFormatSource);
1418
1418
  const systemPrompt = typeof systemPromptSource === "string" && systemPromptSource.trim().length > 0 ? systemPromptSource.trim() : void 0;
1419
+ const byok = target.byok;
1420
+ let byokType;
1421
+ let byokBaseUrl;
1422
+ let byokApiKey;
1423
+ let byokBearerToken;
1424
+ let byokApiVersion;
1425
+ let byokWireApi;
1426
+ if (byok && typeof byok === "object") {
1427
+ byokType = resolveOptionalString(byok.type, env, `${target.name} byok type`, {
1428
+ allowLiteral: true,
1429
+ optionalEnv: true
1430
+ });
1431
+ byokBaseUrl = resolveOptionalString(byok.base_url, env, `${target.name} byok base URL`, {
1432
+ allowLiteral: true,
1433
+ optionalEnv: true
1434
+ });
1435
+ byokApiKey = resolveOptionalString(byok.api_key, env, `${target.name} byok API key`, {
1436
+ allowLiteral: false,
1437
+ optionalEnv: true
1438
+ });
1439
+ byokBearerToken = resolveOptionalString(
1440
+ byok.bearer_token,
1441
+ env,
1442
+ `${target.name} byok bearer token`,
1443
+ {
1444
+ allowLiteral: false,
1445
+ optionalEnv: true
1446
+ }
1447
+ );
1448
+ byokApiVersion = resolveOptionalString(
1449
+ byok.api_version,
1450
+ env,
1451
+ `${target.name} byok API version`,
1452
+ {
1453
+ allowLiteral: true,
1454
+ optionalEnv: true
1455
+ }
1456
+ );
1457
+ byokWireApi = resolveOptionalString(byok.wire_api, env, `${target.name} byok wire API`, {
1458
+ allowLiteral: true,
1459
+ optionalEnv: true
1460
+ });
1461
+ if (!byokBaseUrl) {
1462
+ throw new Error(`${target.name}: 'byok.base_url' is required when 'byok' is specified`);
1463
+ }
1464
+ }
1419
1465
  return {
1420
1466
  cliUrl,
1421
1467
  cliPath,
@@ -1426,7 +1472,13 @@ function resolveCopilotSdkConfig(target, env, evalFilePath) {
1426
1472
  timeoutMs,
1427
1473
  logDir,
1428
1474
  logFormat,
1429
- systemPrompt
1475
+ systemPrompt,
1476
+ byokType,
1477
+ byokBaseUrl,
1478
+ byokApiKey,
1479
+ byokBearerToken,
1480
+ byokApiVersion,
1481
+ byokWireApi
1430
1482
  };
1431
1483
  }
1432
1484
  function resolveCopilotCliConfig(target, env, evalFilePath) {
@@ -6889,7 +6941,7 @@ function createOpenRouter(options = {}) {
6889
6941
  );
6890
6942
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
6891
6943
  provider: "openrouter.chat",
6892
- url: ({ path: path50 }) => `${baseURL}${path50}`,
6944
+ url: ({ path: path51 }) => `${baseURL}${path51}`,
6893
6945
  headers: getHeaders,
6894
6946
  compatibility,
6895
6947
  fetch: options.fetch,
@@ -6897,7 +6949,7 @@ function createOpenRouter(options = {}) {
6897
6949
  });
6898
6950
  const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
6899
6951
  provider: "openrouter.completion",
6900
- url: ({ path: path50 }) => `${baseURL}${path50}`,
6952
+ url: ({ path: path51 }) => `${baseURL}${path51}`,
6901
6953
  headers: getHeaders,
6902
6954
  compatibility,
6903
6955
  fetch: options.fetch,
@@ -6905,14 +6957,14 @@ function createOpenRouter(options = {}) {
6905
6957
  });
6906
6958
  const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
6907
6959
  provider: "openrouter.embedding",
6908
- url: ({ path: path50 }) => `${baseURL}${path50}`,
6960
+ url: ({ path: path51 }) => `${baseURL}${path51}`,
6909
6961
  headers: getHeaders,
6910
6962
  fetch: options.fetch,
6911
6963
  extraBody: options.extraBody
6912
6964
  });
6913
6965
  const createImageModel = (modelId, settings = {}) => new OpenRouterImageModel(modelId, settings, {
6914
6966
  provider: "openrouter.image",
6915
- url: ({ path: path50 }) => `${baseURL}${path50}`,
6967
+ url: ({ path: path51 }) => `${baseURL}${path51}`,
6916
6968
  headers: getHeaders,
6917
6969
  fetch: options.fetch,
6918
6970
  extraBody: options.extraBody
@@ -14504,18 +14556,21 @@ import { readdir as readdir6, stat as stat7 } from "node:fs/promises";
14504
14556
  import path43 from "node:path";
14505
14557
  import { existsSync as existsSync5 } from "node:fs";
14506
14558
  import path45 from "node:path";
14507
- import { mkdir as mkdir15, readFile as readFile13, writeFile as writeFile8 } from "node:fs/promises";
14559
+ import { readFile as readFile13 } from "node:fs/promises";
14508
14560
  import path46 from "node:path";
14509
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync as readdirSync3, statSync as statSync2, writeFileSync } from "node:fs";
14561
+ import { parse as parse5 } from "yaml";
14562
+ import { mkdir as mkdir15, readFile as readFile14, writeFile as writeFile8 } from "node:fs/promises";
14510
14563
  import path47 from "node:path";
14564
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync as readdirSync3, statSync as statSync2, writeFileSync } from "node:fs";
14565
+ import path48 from "node:path";
14511
14566
  import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
14512
14567
  import { readdir as readdir8, stat as stat9 } from "node:fs/promises";
14513
14568
  import { homedir as homedir3 } from "node:os";
14514
- import path48 from "node:path";
14569
+ import path49 from "node:path";
14515
14570
  import { readdir as readdir9, stat as stat10 } from "node:fs/promises";
14516
14571
  import { homedir as homedir4 } from "node:os";
14517
- import path49 from "node:path";
14518
- import { readFile as readFile14 } from "node:fs/promises";
14572
+ import path50 from "node:path";
14573
+ import { readFile as readFile15 } from "node:fs/promises";
14519
14574
  function computeTraceSummary(messages) {
14520
14575
  const toolCallCounts = {};
14521
14576
  const toolDurations = {};
@@ -17337,6 +17392,58 @@ function parseMetadata(suite) {
17337
17392
  requires: suite.requires
17338
17393
  });
17339
17394
  }
17395
+ function parseRepoSource(raw) {
17396
+ if (!isJsonObject(raw)) return void 0;
17397
+ const obj = raw;
17398
+ if (obj.type === "git" && typeof obj.url === "string") {
17399
+ return { type: "git", url: obj.url };
17400
+ }
17401
+ if (obj.type === "local" && typeof obj.path === "string") {
17402
+ return { type: "local", path: obj.path };
17403
+ }
17404
+ return void 0;
17405
+ }
17406
+ function parseRepoCheckout(raw) {
17407
+ if (!isJsonObject(raw)) return void 0;
17408
+ const obj = raw;
17409
+ const ref = typeof obj.ref === "string" ? obj.ref : void 0;
17410
+ const resolve2 = obj.resolve === "remote" || obj.resolve === "local" ? obj.resolve : void 0;
17411
+ const ancestor = typeof obj.ancestor === "number" ? obj.ancestor : void 0;
17412
+ if (!ref && !resolve2 && ancestor === void 0) return void 0;
17413
+ return {
17414
+ ...ref !== void 0 && { ref },
17415
+ ...resolve2 !== void 0 && { resolve: resolve2 },
17416
+ ...ancestor !== void 0 && { ancestor }
17417
+ };
17418
+ }
17419
+ function parseRepoClone(raw) {
17420
+ if (!isJsonObject(raw)) return void 0;
17421
+ const obj = raw;
17422
+ const depth = typeof obj.depth === "number" ? obj.depth : void 0;
17423
+ const filter2 = typeof obj.filter === "string" ? obj.filter : void 0;
17424
+ const sparse = Array.isArray(obj.sparse) ? obj.sparse.filter((s) => typeof s === "string") : void 0;
17425
+ if (depth === void 0 && !filter2 && !sparse) return void 0;
17426
+ return {
17427
+ ...depth !== void 0 && { depth },
17428
+ ...filter2 !== void 0 && { filter: filter2 },
17429
+ ...sparse !== void 0 && { sparse }
17430
+ };
17431
+ }
17432
+ function parseRepoConfig(raw) {
17433
+ if (!isJsonObject(raw)) return void 0;
17434
+ const obj = raw;
17435
+ const repoPath = typeof obj.path === "string" ? obj.path : void 0;
17436
+ const source = parseRepoSource(obj.source);
17437
+ if (!repoPath || !source) return void 0;
17438
+ const checkout = parseRepoCheckout(obj.checkout);
17439
+ const clone = parseRepoClone(obj.clone);
17440
+ return {
17441
+ path: repoPath,
17442
+ source,
17443
+ ...checkout !== void 0 && { checkout },
17444
+ ...clone !== void 0 && { clone }
17445
+ };
17446
+ }
17340
17447
  async function buildPromptInputs(testCase, mode = "lm") {
17341
17448
  const segmentsByMessage = testCase.input.map(
17342
17449
  (message) => extractContentSegments(message.content)
@@ -17728,58 +17835,6 @@ function parseWorkspaceScriptConfig(raw, evalFileDir) {
17728
17835
  }
17729
17836
  return cwd ? { ...config, cwd } : config;
17730
17837
  }
17731
- function parseRepoSource(raw) {
17732
- if (!isJsonObject(raw)) return void 0;
17733
- const obj = raw;
17734
- if (obj.type === "git" && typeof obj.url === "string") {
17735
- return { type: "git", url: obj.url };
17736
- }
17737
- if (obj.type === "local" && typeof obj.path === "string") {
17738
- return { type: "local", path: obj.path };
17739
- }
17740
- return void 0;
17741
- }
17742
- function parseRepoCheckout(raw) {
17743
- if (!isJsonObject(raw)) return void 0;
17744
- const obj = raw;
17745
- const ref = typeof obj.ref === "string" ? obj.ref : void 0;
17746
- const resolve2 = obj.resolve === "remote" || obj.resolve === "local" ? obj.resolve : void 0;
17747
- const ancestor = typeof obj.ancestor === "number" ? obj.ancestor : void 0;
17748
- if (!ref && !resolve2 && ancestor === void 0) return void 0;
17749
- return {
17750
- ...ref !== void 0 && { ref },
17751
- ...resolve2 !== void 0 && { resolve: resolve2 },
17752
- ...ancestor !== void 0 && { ancestor }
17753
- };
17754
- }
17755
- function parseRepoClone(raw) {
17756
- if (!isJsonObject(raw)) return void 0;
17757
- const obj = raw;
17758
- const depth = typeof obj.depth === "number" ? obj.depth : void 0;
17759
- const filter2 = typeof obj.filter === "string" ? obj.filter : void 0;
17760
- const sparse = Array.isArray(obj.sparse) ? obj.sparse.filter((s) => typeof s === "string") : void 0;
17761
- if (depth === void 0 && !filter2 && !sparse) return void 0;
17762
- return {
17763
- ...depth !== void 0 && { depth },
17764
- ...filter2 !== void 0 && { filter: filter2 },
17765
- ...sparse !== void 0 && { sparse }
17766
- };
17767
- }
17768
- function parseRepoConfig(raw) {
17769
- if (!isJsonObject(raw)) return void 0;
17770
- const obj = raw;
17771
- const repoPath = typeof obj.path === "string" ? obj.path : void 0;
17772
- const source = parseRepoSource(obj.source);
17773
- if (!repoPath || !source) return void 0;
17774
- const checkout = parseRepoCheckout(obj.checkout);
17775
- const clone = parseRepoClone(obj.clone);
17776
- return {
17777
- path: repoPath,
17778
- source,
17779
- ...checkout !== void 0 && { checkout },
17780
- ...clone !== void 0 && { clone }
17781
- };
17782
- }
17783
17838
  function parseWorkspaceHookConfig(raw, evalFileDir) {
17784
17839
  if (!isJsonObject(raw)) return void 0;
17785
17840
  const script = parseWorkspaceScriptConfig(raw, evalFileDir);
@@ -21457,6 +21512,25 @@ var CopilotSdkProvider = class {
21457
21512
  content: systemPrompt
21458
21513
  };
21459
21514
  }
21515
+ if (this.config.byokBaseUrl) {
21516
+ const byokType = this.config.byokType ?? "openai";
21517
+ const provider = {
21518
+ type: byokType,
21519
+ baseUrl: normalizeByokBaseUrl(this.config.byokBaseUrl, byokType)
21520
+ };
21521
+ if (this.config.byokBearerToken) {
21522
+ provider.bearerToken = this.config.byokBearerToken;
21523
+ } else if (this.config.byokApiKey) {
21524
+ provider.apiKey = this.config.byokApiKey;
21525
+ }
21526
+ if (this.config.byokWireApi) {
21527
+ provider.wireApi = this.config.byokWireApi;
21528
+ }
21529
+ if (this.config.byokType === "azure" && this.config.byokApiVersion) {
21530
+ provider.azure = { apiVersion: this.config.byokApiVersion };
21531
+ }
21532
+ sessionOptions.provider = provider;
21533
+ }
21460
21534
  let session;
21461
21535
  try {
21462
21536
  session = await client.createSession(sessionOptions);
@@ -21688,6 +21762,16 @@ function resolveSkillDirectories(cwd) {
21688
21762
  ];
21689
21763
  return candidates.filter((dir) => existsSync2(dir));
21690
21764
  }
21765
+ function normalizeByokBaseUrl(baseUrl, type) {
21766
+ const trimmed = baseUrl.trim().replace(/\/+$/, "");
21767
+ if (/^https?:\/\//i.test(trimmed)) {
21768
+ return trimmed;
21769
+ }
21770
+ if (type === "azure") {
21771
+ return `https://${trimmed}.openai.azure.com`;
21772
+ }
21773
+ return trimmed;
21774
+ }
21691
21775
  function summarizeSdkEvent(eventType, data) {
21692
21776
  if (!data || typeof data !== "object") {
21693
21777
  return eventType;
@@ -24995,15 +25079,15 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
24995
25079
  });
24996
25080
  }
24997
25081
  async function execShellWithStdin(command, stdinPayload, options = {}) {
24998
- const { mkdir: mkdir16, readFile: readFile15, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
25082
+ const { mkdir: mkdir16, readFile: readFile16, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
24999
25083
  const { tmpdir: tmpdir3 } = await import("node:os");
25000
- const path50 = await import("node:path");
25084
+ const path51 = await import("node:path");
25001
25085
  const { randomUUID: randomUUID10 } = await import("node:crypto");
25002
- const dir = path50.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
25086
+ const dir = path51.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
25003
25087
  await mkdir16(dir, { recursive: true });
25004
- const stdinPath = path50.join(dir, "stdin.txt");
25005
- const stdoutPath = path50.join(dir, "stdout.txt");
25006
- const stderrPath = path50.join(dir, "stderr.txt");
25088
+ const stdinPath = path51.join(dir, "stdin.txt");
25089
+ const stdoutPath = path51.join(dir, "stdout.txt");
25090
+ const stderrPath = path51.join(dir, "stderr.txt");
25007
25091
  await writeFile9(stdinPath, stdinPayload, "utf8");
25008
25092
  const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
25009
25093
  const { spawn: spawn5 } = await import("node:child_process");
@@ -25033,8 +25117,8 @@ async function execShellWithStdin(command, stdinPayload, options = {}) {
25033
25117
  resolve2(code ?? 0);
25034
25118
  });
25035
25119
  });
25036
- const stdout = (await readFile15(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
25037
- const stderr = (await readFile15(stderrPath, "utf8")).replace(/\r\n/g, "\n");
25120
+ const stdout = (await readFile16(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
25121
+ const stderr = (await readFile16(stderrPath, "utf8")).replace(/\r\n/g, "\n");
25038
25122
  return { stdout, stderr, exitCode };
25039
25123
  } finally {
25040
25124
  await rm6(dir, { recursive: true, force: true });
@@ -27268,115 +27352,115 @@ var FieldAccuracyEvaluator = class {
27268
27352
  * Evaluate a single field against the expected value.
27269
27353
  */
27270
27354
  evaluateField(fieldConfig, candidateData, expectedData) {
27271
- const { path: path50, match, required = true, weight = 1 } = fieldConfig;
27272
- const candidateValue = resolvePath(candidateData, path50);
27273
- const expectedValue = resolvePath(expectedData, path50);
27355
+ const { path: path51, match, required = true, weight = 1 } = fieldConfig;
27356
+ const candidateValue = resolvePath(candidateData, path51);
27357
+ const expectedValue = resolvePath(expectedData, path51);
27274
27358
  if (expectedValue === void 0) {
27275
27359
  return {
27276
- path: path50,
27360
+ path: path51,
27277
27361
  score: 1,
27278
27362
  // No expected value means no comparison needed
27279
27363
  weight,
27280
27364
  hit: true,
27281
- message: `${path50}: no expected value`
27365
+ message: `${path51}: no expected value`
27282
27366
  };
27283
27367
  }
27284
27368
  if (candidateValue === void 0) {
27285
27369
  if (required) {
27286
27370
  return {
27287
- path: path50,
27371
+ path: path51,
27288
27372
  score: 0,
27289
27373
  weight,
27290
27374
  hit: false,
27291
- message: `${path50} (required, missing)`
27375
+ message: `${path51} (required, missing)`
27292
27376
  };
27293
27377
  }
27294
27378
  return {
27295
- path: path50,
27379
+ path: path51,
27296
27380
  score: 1,
27297
27381
  // Don't penalize missing optional fields
27298
27382
  weight: 0,
27299
27383
  // Zero weight means it won't affect the score
27300
27384
  hit: true,
27301
- message: `${path50}: optional field missing`
27385
+ message: `${path51}: optional field missing`
27302
27386
  };
27303
27387
  }
27304
27388
  switch (match) {
27305
27389
  case "exact":
27306
- return this.compareExact(path50, candidateValue, expectedValue, weight);
27390
+ return this.compareExact(path51, candidateValue, expectedValue, weight);
27307
27391
  case "numeric_tolerance":
27308
27392
  return this.compareNumericTolerance(
27309
- path50,
27393
+ path51,
27310
27394
  candidateValue,
27311
27395
  expectedValue,
27312
27396
  fieldConfig,
27313
27397
  weight
27314
27398
  );
27315
27399
  case "date":
27316
- return this.compareDate(path50, candidateValue, expectedValue, fieldConfig, weight);
27400
+ return this.compareDate(path51, candidateValue, expectedValue, fieldConfig, weight);
27317
27401
  default:
27318
27402
  return {
27319
- path: path50,
27403
+ path: path51,
27320
27404
  score: 0,
27321
27405
  weight,
27322
27406
  hit: false,
27323
- message: `${path50}: unknown match type "${match}"`
27407
+ message: `${path51}: unknown match type "${match}"`
27324
27408
  };
27325
27409
  }
27326
27410
  }
27327
27411
  /**
27328
27412
  * Exact equality comparison.
27329
27413
  */
27330
- compareExact(path50, candidateValue, expectedValue, weight) {
27414
+ compareExact(path51, candidateValue, expectedValue, weight) {
27331
27415
  if (deepEqual(candidateValue, expectedValue)) {
27332
27416
  return {
27333
- path: path50,
27417
+ path: path51,
27334
27418
  score: 1,
27335
27419
  weight,
27336
27420
  hit: true,
27337
- message: path50
27421
+ message: path51
27338
27422
  };
27339
27423
  }
27340
27424
  if (typeof candidateValue !== typeof expectedValue) {
27341
27425
  return {
27342
- path: path50,
27426
+ path: path51,
27343
27427
  score: 0,
27344
27428
  weight,
27345
27429
  hit: false,
27346
- message: `${path50} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
27430
+ message: `${path51} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
27347
27431
  };
27348
27432
  }
27349
27433
  return {
27350
- path: path50,
27434
+ path: path51,
27351
27435
  score: 0,
27352
27436
  weight,
27353
27437
  hit: false,
27354
- message: `${path50} (value mismatch)`
27438
+ message: `${path51} (value mismatch)`
27355
27439
  };
27356
27440
  }
27357
27441
  /**
27358
27442
  * Numeric comparison with absolute or relative tolerance.
27359
27443
  */
27360
- compareNumericTolerance(path50, candidateValue, expectedValue, fieldConfig, weight) {
27444
+ compareNumericTolerance(path51, candidateValue, expectedValue, fieldConfig, weight) {
27361
27445
  const { tolerance = 0, relative = false } = fieldConfig;
27362
27446
  const candidateNum = toNumber(candidateValue);
27363
27447
  const expectedNum = toNumber(expectedValue);
27364
27448
  if (candidateNum === null || expectedNum === null) {
27365
27449
  return {
27366
- path: path50,
27450
+ path: path51,
27367
27451
  score: 0,
27368
27452
  weight,
27369
27453
  hit: false,
27370
- message: `${path50} (non-numeric value)`
27454
+ message: `${path51} (non-numeric value)`
27371
27455
  };
27372
27456
  }
27373
27457
  if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
27374
27458
  return {
27375
- path: path50,
27459
+ path: path51,
27376
27460
  score: 0,
27377
27461
  weight,
27378
27462
  hit: false,
27379
- message: `${path50} (invalid numeric value)`
27463
+ message: `${path51} (invalid numeric value)`
27380
27464
  };
27381
27465
  }
27382
27466
  const diff = Math.abs(candidateNum - expectedNum);
@@ -27389,61 +27473,61 @@ var FieldAccuracyEvaluator = class {
27389
27473
  }
27390
27474
  if (withinTolerance) {
27391
27475
  return {
27392
- path: path50,
27476
+ path: path51,
27393
27477
  score: 1,
27394
27478
  weight,
27395
27479
  hit: true,
27396
- message: `${path50} (within tolerance: diff=${diff.toFixed(2)})`
27480
+ message: `${path51} (within tolerance: diff=${diff.toFixed(2)})`
27397
27481
  };
27398
27482
  }
27399
27483
  return {
27400
- path: path50,
27484
+ path: path51,
27401
27485
  score: 0,
27402
27486
  weight,
27403
27487
  hit: false,
27404
- message: `${path50} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
27488
+ message: `${path51} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
27405
27489
  };
27406
27490
  }
27407
27491
  /**
27408
27492
  * Date comparison with format normalization.
27409
27493
  */
27410
- compareDate(path50, candidateValue, expectedValue, fieldConfig, weight) {
27494
+ compareDate(path51, candidateValue, expectedValue, fieldConfig, weight) {
27411
27495
  const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
27412
27496
  const candidateDate = parseDate(String(candidateValue), formats);
27413
27497
  const expectedDate = parseDate(String(expectedValue), formats);
27414
27498
  if (candidateDate === null) {
27415
27499
  return {
27416
- path: path50,
27500
+ path: path51,
27417
27501
  score: 0,
27418
27502
  weight,
27419
27503
  hit: false,
27420
- message: `${path50} (unparseable candidate date)`
27504
+ message: `${path51} (unparseable candidate date)`
27421
27505
  };
27422
27506
  }
27423
27507
  if (expectedDate === null) {
27424
27508
  return {
27425
- path: path50,
27509
+ path: path51,
27426
27510
  score: 0,
27427
27511
  weight,
27428
27512
  hit: false,
27429
- message: `${path50} (unparseable expected date)`
27513
+ message: `${path51} (unparseable expected date)`
27430
27514
  };
27431
27515
  }
27432
27516
  if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
27433
27517
  return {
27434
- path: path50,
27518
+ path: path51,
27435
27519
  score: 1,
27436
27520
  weight,
27437
27521
  hit: true,
27438
- message: path50
27522
+ message: path51
27439
27523
  };
27440
27524
  }
27441
27525
  return {
27442
- path: path50,
27526
+ path: path51,
27443
27527
  score: 0,
27444
27528
  weight,
27445
27529
  hit: false,
27446
- message: `${path50} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
27530
+ message: `${path51} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
27447
27531
  };
27448
27532
  }
27449
27533
  /**
@@ -27476,11 +27560,11 @@ var FieldAccuracyEvaluator = class {
27476
27560
  };
27477
27561
  }
27478
27562
  };
27479
- function resolvePath(obj, path50) {
27480
- if (!path50 || !obj) {
27563
+ function resolvePath(obj, path51) {
27564
+ if (!path51 || !obj) {
27481
27565
  return void 0;
27482
27566
  }
27483
- const parts = path50.split(/\.|\[|\]/).filter((p) => p.length > 0);
27567
+ const parts = path51.split(/\.|\[|\]/).filter((p) => p.length > 0);
27484
27568
  let current = obj;
27485
27569
  for (const part of parts) {
27486
27570
  if (current === null || current === void 0) {
@@ -27962,8 +28046,8 @@ var TokenUsageEvaluator = class {
27962
28046
  };
27963
28047
  }
27964
28048
  };
27965
- function getNestedValue(obj, path50) {
27966
- const parts = path50.split(".");
28049
+ function getNestedValue(obj, path51) {
28050
+ const parts = path51.split(".");
27967
28051
  let current = obj;
27968
28052
  for (const part of parts) {
27969
28053
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -32382,6 +32466,98 @@ function buildPrompt(criteria, question, referenceAnswer) {
32382
32466
  }
32383
32467
  return parts.join("\n");
32384
32468
  }
32469
+ function normalizeGitUrl(url) {
32470
+ let normalized = url.replace(/\.git$/, "");
32471
+ try {
32472
+ const parsed = new URL(normalized);
32473
+ parsed.hostname = parsed.hostname.toLowerCase();
32474
+ normalized = parsed.toString().replace(/\/$/, "");
32475
+ } catch {
32476
+ }
32477
+ return normalized;
32478
+ }
32479
+ async function scanRepoDeps(evalFilePaths) {
32480
+ const seen = /* @__PURE__ */ new Map();
32481
+ const errors = [];
32482
+ for (const filePath of evalFilePaths) {
32483
+ try {
32484
+ const repos = await extractReposFromEvalFile(filePath);
32485
+ for (const repo of repos) {
32486
+ if (repo.source.type !== "git") continue;
32487
+ const ref = repo.checkout?.ref;
32488
+ const key = `${normalizeGitUrl(repo.source.url)}\0${ref ?? ""}`;
32489
+ const existing = seen.get(key);
32490
+ if (existing) {
32491
+ existing.usedBy.push(filePath);
32492
+ } else {
32493
+ const { ref: _ref, ...checkoutRest } = repo.checkout ?? {};
32494
+ const hasCheckout = Object.keys(checkoutRest).length > 0;
32495
+ seen.set(key, {
32496
+ url: repo.source.url,
32497
+ ref,
32498
+ clone: repo.clone,
32499
+ checkout: hasCheckout ? checkoutRest : void 0,
32500
+ usedBy: [filePath]
32501
+ });
32502
+ }
32503
+ }
32504
+ } catch (err) {
32505
+ errors.push({
32506
+ file: filePath,
32507
+ message: err instanceof Error ? err.message : String(err)
32508
+ });
32509
+ }
32510
+ }
32511
+ return { repos: [...seen.values()], errors };
32512
+ }
32513
+ async function extractReposFromEvalFile(filePath) {
32514
+ const content = await readFile13(filePath, "utf8");
32515
+ const parsed = interpolateEnv(parse5(content), process.env);
32516
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return [];
32517
+ const obj = parsed;
32518
+ const evalFileDir = path46.dirname(path46.resolve(filePath));
32519
+ const repos = [];
32520
+ const suiteRepos = await extractReposFromWorkspaceRaw(obj.workspace, evalFileDir);
32521
+ repos.push(...suiteRepos);
32522
+ const tests = Array.isArray(obj.tests) ? obj.tests : [];
32523
+ for (const test of tests) {
32524
+ if (test && typeof test === "object" && !Array.isArray(test)) {
32525
+ const testObj = test;
32526
+ const testRepos = await extractReposFromWorkspaceRaw(testObj.workspace, evalFileDir);
32527
+ repos.push(...testRepos);
32528
+ }
32529
+ }
32530
+ return repos;
32531
+ }
32532
+ async function extractReposFromWorkspaceRaw(raw, evalFileDir) {
32533
+ if (typeof raw === "string") {
32534
+ const workspaceFilePath = path46.resolve(evalFileDir, raw);
32535
+ const content = await readFile13(workspaceFilePath, "utf8");
32536
+ const parsed = interpolateEnv(parse5(content), process.env);
32537
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return [];
32538
+ return extractReposFromObject(parsed);
32539
+ }
32540
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
32541
+ return extractReposFromObject(raw);
32542
+ }
32543
+ return [];
32544
+ }
32545
+ function extractReposFromObject(obj) {
32546
+ const rawRepos = Array.isArray(obj.repos) ? obj.repos : [];
32547
+ const result = [];
32548
+ for (const r of rawRepos) {
32549
+ if (!r || typeof r !== "object" || Array.isArray(r)) continue;
32550
+ const repo = r;
32551
+ const source = parseRepoSource(repo.source);
32552
+ if (!source) continue;
32553
+ result.push({
32554
+ source,
32555
+ checkout: parseRepoCheckout(repo.checkout),
32556
+ clone: parseRepoClone(repo.clone)
32557
+ });
32558
+ }
32559
+ return result;
32560
+ }
32385
32561
  var DEFAULT_CACHE_PATH = ".agentv/cache";
32386
32562
  var ResponseCache = class {
32387
32563
  cachePath;
@@ -32391,7 +32567,7 @@ var ResponseCache = class {
32391
32567
  async get(key) {
32392
32568
  const filePath = this.keyToPath(key);
32393
32569
  try {
32394
- const data = await readFile13(filePath, "utf8");
32570
+ const data = await readFile14(filePath, "utf8");
32395
32571
  return JSON.parse(data);
32396
32572
  } catch {
32397
32573
  return void 0;
@@ -32399,13 +32575,13 @@ var ResponseCache = class {
32399
32575
  }
32400
32576
  async set(key, value) {
32401
32577
  const filePath = this.keyToPath(key);
32402
- const dir = path46.dirname(filePath);
32578
+ const dir = path47.dirname(filePath);
32403
32579
  await mkdir15(dir, { recursive: true });
32404
32580
  await writeFile8(filePath, JSON.stringify(value, null, 2), "utf8");
32405
32581
  }
32406
32582
  keyToPath(key) {
32407
32583
  const prefix = key.slice(0, 2);
32408
- return path46.join(this.cachePath, prefix, `${key}.json`);
32584
+ return path47.join(this.cachePath, prefix, `${key}.json`);
32409
32585
  }
32410
32586
  };
32411
32587
  function shouldEnableCache(params) {
@@ -32420,7 +32596,7 @@ function shouldSkipCacheForTemperature(targetConfig) {
32420
32596
  return false;
32421
32597
  }
32422
32598
  function getProjectsRegistryPath() {
32423
- return path47.join(getAgentvHome(), "projects.yaml");
32599
+ return path48.join(getAgentvHome(), "projects.yaml");
32424
32600
  }
32425
32601
  function loadProjectRegistry() {
32426
32602
  const registryPath = getProjectsRegistryPath();
@@ -32440,14 +32616,14 @@ function loadProjectRegistry() {
32440
32616
  }
32441
32617
  function saveProjectRegistry(registry) {
32442
32618
  const registryPath = getProjectsRegistryPath();
32443
- const dir = path47.dirname(registryPath);
32619
+ const dir = path48.dirname(registryPath);
32444
32620
  if (!existsSync6(dir)) {
32445
32621
  mkdirSync2(dir, { recursive: true });
32446
32622
  }
32447
32623
  writeFileSync(registryPath, stringifyYaml(registry), "utf-8");
32448
32624
  }
32449
32625
  function deriveProjectId(dirPath, existingIds) {
32450
- const base = path47.basename(dirPath).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
32626
+ const base = path48.basename(dirPath).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
32451
32627
  let candidate = base || "project";
32452
32628
  let suffix = 2;
32453
32629
  while (existingIds.includes(candidate)) {
@@ -32457,11 +32633,11 @@ function deriveProjectId(dirPath, existingIds) {
32457
32633
  return candidate;
32458
32634
  }
32459
32635
  function addProject(projectPath) {
32460
- const absPath = path47.resolve(projectPath);
32636
+ const absPath = path48.resolve(projectPath);
32461
32637
  if (!existsSync6(absPath)) {
32462
32638
  throw new Error(`Directory not found: ${absPath}`);
32463
32639
  }
32464
- if (!existsSync6(path47.join(absPath, ".agentv"))) {
32640
+ if (!existsSync6(path48.join(absPath, ".agentv"))) {
32465
32641
  throw new Error(`No .agentv/ directory found in ${absPath}. Run an evaluation first.`);
32466
32642
  }
32467
32643
  const registry = loadProjectRegistry();
@@ -32475,7 +32651,7 @@ function addProject(projectPath) {
32475
32651
  absPath,
32476
32652
  registry.projects.map((p) => p.id)
32477
32653
  ),
32478
- name: path47.basename(absPath),
32654
+ name: path48.basename(absPath),
32479
32655
  path: absPath,
32480
32656
  addedAt: now2,
32481
32657
  lastOpenedAt: now2
@@ -32504,14 +32680,14 @@ function touchProject(projectId) {
32504
32680
  }
32505
32681
  }
32506
32682
  function discoverProjects(rootDir, maxDepth = 2) {
32507
- const absRoot = path47.resolve(rootDir);
32683
+ const absRoot = path48.resolve(rootDir);
32508
32684
  if (!existsSync6(absRoot) || !statSync2(absRoot).isDirectory()) {
32509
32685
  return [];
32510
32686
  }
32511
32687
  const results = [];
32512
32688
  function scan(dir, depth) {
32513
32689
  if (depth > maxDepth) return;
32514
- if (existsSync6(path47.join(dir, ".agentv"))) {
32690
+ if (existsSync6(path48.join(dir, ".agentv"))) {
32515
32691
  results.push(dir);
32516
32692
  return;
32517
32693
  }
@@ -32521,7 +32697,7 @@ function discoverProjects(rootDir, maxDepth = 2) {
32521
32697
  for (const entry of entries) {
32522
32698
  if (!entry.isDirectory()) continue;
32523
32699
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
32524
- scan(path47.join(dir, entry.name), depth + 1);
32700
+ scan(path48.join(dir, entry.name), depth + 1);
32525
32701
  }
32526
32702
  } catch {
32527
32703
  }
@@ -33420,7 +33596,7 @@ function extractResponseItemContent(content) {
33420
33596
  }
33421
33597
  return parts.length > 0 ? parts.join("") : void 0;
33422
33598
  }
33423
- var DEFAULT_SESSIONS_DIR = () => path48.join(homedir3(), ".codex", "sessions");
33599
+ var DEFAULT_SESSIONS_DIR = () => path49.join(homedir3(), ".codex", "sessions");
33424
33600
  async function discoverCodexSessions(opts) {
33425
33601
  const sessionsDir = opts?.sessionsDir ?? DEFAULT_SESSIONS_DIR();
33426
33602
  const limit = opts?.latest ? 1 : opts?.limit ?? 10;
@@ -33432,7 +33608,7 @@ async function discoverCodexSessions(opts) {
33432
33608
  return [];
33433
33609
  }
33434
33610
  for (const year of yearDirs) {
33435
- const yearPath = path48.join(sessionsDir, year);
33611
+ const yearPath = path49.join(sessionsDir, year);
33436
33612
  let monthDirs;
33437
33613
  try {
33438
33614
  monthDirs = await readdir8(yearPath);
@@ -33440,7 +33616,7 @@ async function discoverCodexSessions(opts) {
33440
33616
  continue;
33441
33617
  }
33442
33618
  for (const month of monthDirs) {
33443
- const monthPath = path48.join(yearPath, month);
33619
+ const monthPath = path49.join(yearPath, month);
33444
33620
  let dayDirs;
33445
33621
  try {
33446
33622
  dayDirs = await readdir8(monthPath);
@@ -33452,7 +33628,7 @@ async function discoverCodexSessions(opts) {
33452
33628
  const dirDate = `${year}-${month}-${day}`;
33453
33629
  if (dirDate !== opts.date) continue;
33454
33630
  }
33455
- const dayPath = path48.join(monthPath, day);
33631
+ const dayPath = path49.join(monthPath, day);
33456
33632
  let files;
33457
33633
  try {
33458
33634
  files = await readdir8(dayPath);
@@ -33461,7 +33637,7 @@ async function discoverCodexSessions(opts) {
33461
33637
  }
33462
33638
  for (const file of files) {
33463
33639
  if (!file.startsWith("rollout-") || !file.endsWith(".jsonl")) continue;
33464
- const filePath = path48.join(dayPath, file);
33640
+ const filePath = path49.join(dayPath, file);
33465
33641
  const nameWithoutExt = file.replace(/\.jsonl$/, "");
33466
33642
  const parts = nameWithoutExt.split("-");
33467
33643
  const sessionId = parts.length >= 6 ? parts.slice(-5).join("-") : nameWithoutExt;
@@ -33480,7 +33656,7 @@ async function discoverCodexSessions(opts) {
33480
33656
  sessions.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());
33481
33657
  return sessions.slice(0, limit);
33482
33658
  }
33483
- var DEFAULT_PROJECTS_DIR = () => path49.join(homedir4(), ".claude", "projects");
33659
+ var DEFAULT_PROJECTS_DIR = () => path50.join(homedir4(), ".claude", "projects");
33484
33660
  function encodeProjectPath(projectPath) {
33485
33661
  return projectPath.replace(/\//g, "-");
33486
33662
  }
@@ -33499,7 +33675,7 @@ async function discoverClaudeSessions(opts) {
33499
33675
  }
33500
33676
  const sessions = [];
33501
33677
  for (const projectDir of projectDirs) {
33502
- const dirPath = path49.join(projectsDir, projectDir);
33678
+ const dirPath = path50.join(projectsDir, projectDir);
33503
33679
  let entries;
33504
33680
  try {
33505
33681
  entries = await readdir9(dirPath);
@@ -33510,7 +33686,7 @@ async function discoverClaudeSessions(opts) {
33510
33686
  if (!entry.endsWith(".jsonl")) continue;
33511
33687
  const sessionId = entry.replace(/\.jsonl$/, "");
33512
33688
  if (opts?.sessionId && sessionId !== opts.sessionId) continue;
33513
- const filePath = path49.join(dirPath, entry);
33689
+ const filePath = path50.join(dirPath, entry);
33514
33690
  let updatedAt;
33515
33691
  try {
33516
33692
  const fileStat = await stat10(filePath);
@@ -33554,11 +33730,11 @@ function toTranscriptJsonLine(entry) {
33554
33730
  };
33555
33731
  }
33556
33732
  async function readTranscriptJsonl(filePath) {
33557
- const text2 = await readFile14(filePath, "utf8");
33733
+ const text2 = await readFile15(filePath, "utf8");
33558
33734
  return text2.split("\n").filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
33559
33735
  }
33560
33736
  async function readTranscriptFile(filePath) {
33561
- return readFile14(filePath, "utf8");
33737
+ return readFile15(filePath, "utf8");
33562
33738
  }
33563
33739
  var TranscriptProvider = class _TranscriptProvider {
33564
33740
  id;
@@ -33761,6 +33937,7 @@ export {
33761
33937
  defineConfig,
33762
33938
  loadTsConfig,
33763
33939
  generateRubrics,
33940
+ scanRepoDeps,
33764
33941
  ResponseCache,
33765
33942
  shouldEnableCache,
33766
33943
  shouldSkipCacheForTemperature,
@@ -33789,4 +33966,4 @@ export {
33789
33966
  TranscriptProvider,
33790
33967
  createAgentKernel
33791
33968
  };
33792
- //# sourceMappingURL=chunk-I6UE4LHZ.js.map
33969
+ //# sourceMappingURL=chunk-7K5LYK5B.js.map