agentv 4.3.4 → 4.4.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.
@@ -1638,8 +1638,8 @@ function resolveCliConfig(target, env, evalFilePath) {
1638
1638
  const parseResult = CliTargetInputSchema.safeParse(target, { errorMap: cliErrorMap });
1639
1639
  if (!parseResult.success) {
1640
1640
  const firstError = parseResult.error.errors[0];
1641
- const path47 = firstError?.path.join(".") || "";
1642
- const prefix = path47 ? `${target.name} ${path47}: ` : `${target.name}: `;
1641
+ const path48 = firstError?.path.join(".") || "";
1642
+ const prefix = path48 ? `${target.name} ${path48}: ` : `${target.name}: `;
1643
1643
  throw new Error(`${prefix}${firstError?.message}`);
1644
1644
  }
1645
1645
  const normalized = normalizeCliTargetInput(parseResult.data, env, evalFilePath);
@@ -6722,7 +6722,7 @@ function createOpenRouter(options = {}) {
6722
6722
  );
6723
6723
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
6724
6724
  provider: "openrouter.chat",
6725
- url: ({ path: path47 }) => `${baseURL}${path47}`,
6725
+ url: ({ path: path48 }) => `${baseURL}${path48}`,
6726
6726
  headers: getHeaders,
6727
6727
  compatibility,
6728
6728
  fetch: options.fetch,
@@ -6730,7 +6730,7 @@ function createOpenRouter(options = {}) {
6730
6730
  });
6731
6731
  const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
6732
6732
  provider: "openrouter.completion",
6733
- url: ({ path: path47 }) => `${baseURL}${path47}`,
6733
+ url: ({ path: path48 }) => `${baseURL}${path48}`,
6734
6734
  headers: getHeaders,
6735
6735
  compatibility,
6736
6736
  fetch: options.fetch,
@@ -6738,14 +6738,14 @@ function createOpenRouter(options = {}) {
6738
6738
  });
6739
6739
  const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
6740
6740
  provider: "openrouter.embedding",
6741
- url: ({ path: path47 }) => `${baseURL}${path47}`,
6741
+ url: ({ path: path48 }) => `${baseURL}${path48}`,
6742
6742
  headers: getHeaders,
6743
6743
  fetch: options.fetch,
6744
6744
  extraBody: options.extraBody
6745
6745
  });
6746
6746
  const createImageModel = (modelId, settings = {}) => new OpenRouterImageModel(modelId, settings, {
6747
6747
  provider: "openrouter.image",
6748
- url: ({ path: path47 }) => `${baseURL}${path47}`,
6748
+ url: ({ path: path48 }) => `${baseURL}${path48}`,
6749
6749
  headers: getHeaders,
6750
6750
  fetch: options.fetch,
6751
6751
  extraBody: options.extraBody
@@ -14338,6 +14338,9 @@ import { existsSync as existsSync4 } from "node:fs";
14338
14338
  import path45 from "node:path";
14339
14339
  import { mkdir as mkdir15, readFile as readFile13, writeFile as writeFile8 } from "node:fs/promises";
14340
14340
  import path46 from "node:path";
14341
+ import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync2, readdirSync as readdirSync3, statSync as statSync2, writeFileSync } from "node:fs";
14342
+ import path47 from "node:path";
14343
+ import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
14341
14344
  function computeTraceSummary(messages) {
14342
14345
  const toolCallCounts = {};
14343
14346
  const toolDurations = {};
@@ -24370,13 +24373,13 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
24370
24373
  async function execShellWithStdin(command, stdinPayload, options = {}) {
24371
24374
  const { mkdir: mkdir16, readFile: readFile14, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
24372
24375
  const { tmpdir: tmpdir3 } = await import("node:os");
24373
- const path47 = await import("node:path");
24376
+ const path48 = await import("node:path");
24374
24377
  const { randomUUID: randomUUID10 } = await import("node:crypto");
24375
- const dir = path47.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
24378
+ const dir = path48.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
24376
24379
  await mkdir16(dir, { recursive: true });
24377
- const stdinPath = path47.join(dir, "stdin.txt");
24378
- const stdoutPath = path47.join(dir, "stdout.txt");
24379
- const stderrPath = path47.join(dir, "stderr.txt");
24380
+ const stdinPath = path48.join(dir, "stdin.txt");
24381
+ const stdoutPath = path48.join(dir, "stdout.txt");
24382
+ const stderrPath = path48.join(dir, "stderr.txt");
24380
24383
  await writeFile9(stdinPath, stdinPayload, "utf8");
24381
24384
  const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
24382
24385
  const { spawn: spawn5 } = await import("node:child_process");
@@ -26564,115 +26567,115 @@ var FieldAccuracyEvaluator = class {
26564
26567
  * Evaluate a single field against the expected value.
26565
26568
  */
26566
26569
  evaluateField(fieldConfig, candidateData, expectedData) {
26567
- const { path: path47, match, required = true, weight = 1 } = fieldConfig;
26568
- const candidateValue = resolvePath(candidateData, path47);
26569
- const expectedValue = resolvePath(expectedData, path47);
26570
+ const { path: path48, match, required = true, weight = 1 } = fieldConfig;
26571
+ const candidateValue = resolvePath(candidateData, path48);
26572
+ const expectedValue = resolvePath(expectedData, path48);
26570
26573
  if (expectedValue === void 0) {
26571
26574
  return {
26572
- path: path47,
26575
+ path: path48,
26573
26576
  score: 1,
26574
26577
  // No expected value means no comparison needed
26575
26578
  weight,
26576
26579
  hit: true,
26577
- message: `${path47}: no expected value`
26580
+ message: `${path48}: no expected value`
26578
26581
  };
26579
26582
  }
26580
26583
  if (candidateValue === void 0) {
26581
26584
  if (required) {
26582
26585
  return {
26583
- path: path47,
26586
+ path: path48,
26584
26587
  score: 0,
26585
26588
  weight,
26586
26589
  hit: false,
26587
- message: `${path47} (required, missing)`
26590
+ message: `${path48} (required, missing)`
26588
26591
  };
26589
26592
  }
26590
26593
  return {
26591
- path: path47,
26594
+ path: path48,
26592
26595
  score: 1,
26593
26596
  // Don't penalize missing optional fields
26594
26597
  weight: 0,
26595
26598
  // Zero weight means it won't affect the score
26596
26599
  hit: true,
26597
- message: `${path47}: optional field missing`
26600
+ message: `${path48}: optional field missing`
26598
26601
  };
26599
26602
  }
26600
26603
  switch (match) {
26601
26604
  case "exact":
26602
- return this.compareExact(path47, candidateValue, expectedValue, weight);
26605
+ return this.compareExact(path48, candidateValue, expectedValue, weight);
26603
26606
  case "numeric_tolerance":
26604
26607
  return this.compareNumericTolerance(
26605
- path47,
26608
+ path48,
26606
26609
  candidateValue,
26607
26610
  expectedValue,
26608
26611
  fieldConfig,
26609
26612
  weight
26610
26613
  );
26611
26614
  case "date":
26612
- return this.compareDate(path47, candidateValue, expectedValue, fieldConfig, weight);
26615
+ return this.compareDate(path48, candidateValue, expectedValue, fieldConfig, weight);
26613
26616
  default:
26614
26617
  return {
26615
- path: path47,
26618
+ path: path48,
26616
26619
  score: 0,
26617
26620
  weight,
26618
26621
  hit: false,
26619
- message: `${path47}: unknown match type "${match}"`
26622
+ message: `${path48}: unknown match type "${match}"`
26620
26623
  };
26621
26624
  }
26622
26625
  }
26623
26626
  /**
26624
26627
  * Exact equality comparison.
26625
26628
  */
26626
- compareExact(path47, candidateValue, expectedValue, weight) {
26629
+ compareExact(path48, candidateValue, expectedValue, weight) {
26627
26630
  if (deepEqual(candidateValue, expectedValue)) {
26628
26631
  return {
26629
- path: path47,
26632
+ path: path48,
26630
26633
  score: 1,
26631
26634
  weight,
26632
26635
  hit: true,
26633
- message: path47
26636
+ message: path48
26634
26637
  };
26635
26638
  }
26636
26639
  if (typeof candidateValue !== typeof expectedValue) {
26637
26640
  return {
26638
- path: path47,
26641
+ path: path48,
26639
26642
  score: 0,
26640
26643
  weight,
26641
26644
  hit: false,
26642
- message: `${path47} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
26645
+ message: `${path48} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
26643
26646
  };
26644
26647
  }
26645
26648
  return {
26646
- path: path47,
26649
+ path: path48,
26647
26650
  score: 0,
26648
26651
  weight,
26649
26652
  hit: false,
26650
- message: `${path47} (value mismatch)`
26653
+ message: `${path48} (value mismatch)`
26651
26654
  };
26652
26655
  }
26653
26656
  /**
26654
26657
  * Numeric comparison with absolute or relative tolerance.
26655
26658
  */
26656
- compareNumericTolerance(path47, candidateValue, expectedValue, fieldConfig, weight) {
26659
+ compareNumericTolerance(path48, candidateValue, expectedValue, fieldConfig, weight) {
26657
26660
  const { tolerance = 0, relative = false } = fieldConfig;
26658
26661
  const candidateNum = toNumber(candidateValue);
26659
26662
  const expectedNum = toNumber(expectedValue);
26660
26663
  if (candidateNum === null || expectedNum === null) {
26661
26664
  return {
26662
- path: path47,
26665
+ path: path48,
26663
26666
  score: 0,
26664
26667
  weight,
26665
26668
  hit: false,
26666
- message: `${path47} (non-numeric value)`
26669
+ message: `${path48} (non-numeric value)`
26667
26670
  };
26668
26671
  }
26669
26672
  if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
26670
26673
  return {
26671
- path: path47,
26674
+ path: path48,
26672
26675
  score: 0,
26673
26676
  weight,
26674
26677
  hit: false,
26675
- message: `${path47} (invalid numeric value)`
26678
+ message: `${path48} (invalid numeric value)`
26676
26679
  };
26677
26680
  }
26678
26681
  const diff = Math.abs(candidateNum - expectedNum);
@@ -26685,61 +26688,61 @@ var FieldAccuracyEvaluator = class {
26685
26688
  }
26686
26689
  if (withinTolerance) {
26687
26690
  return {
26688
- path: path47,
26691
+ path: path48,
26689
26692
  score: 1,
26690
26693
  weight,
26691
26694
  hit: true,
26692
- message: `${path47} (within tolerance: diff=${diff.toFixed(2)})`
26695
+ message: `${path48} (within tolerance: diff=${diff.toFixed(2)})`
26693
26696
  };
26694
26697
  }
26695
26698
  return {
26696
- path: path47,
26699
+ path: path48,
26697
26700
  score: 0,
26698
26701
  weight,
26699
26702
  hit: false,
26700
- message: `${path47} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
26703
+ message: `${path48} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
26701
26704
  };
26702
26705
  }
26703
26706
  /**
26704
26707
  * Date comparison with format normalization.
26705
26708
  */
26706
- compareDate(path47, candidateValue, expectedValue, fieldConfig, weight) {
26709
+ compareDate(path48, candidateValue, expectedValue, fieldConfig, weight) {
26707
26710
  const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
26708
26711
  const candidateDate = parseDate(String(candidateValue), formats);
26709
26712
  const expectedDate = parseDate(String(expectedValue), formats);
26710
26713
  if (candidateDate === null) {
26711
26714
  return {
26712
- path: path47,
26715
+ path: path48,
26713
26716
  score: 0,
26714
26717
  weight,
26715
26718
  hit: false,
26716
- message: `${path47} (unparseable candidate date)`
26719
+ message: `${path48} (unparseable candidate date)`
26717
26720
  };
26718
26721
  }
26719
26722
  if (expectedDate === null) {
26720
26723
  return {
26721
- path: path47,
26724
+ path: path48,
26722
26725
  score: 0,
26723
26726
  weight,
26724
26727
  hit: false,
26725
- message: `${path47} (unparseable expected date)`
26728
+ message: `${path48} (unparseable expected date)`
26726
26729
  };
26727
26730
  }
26728
26731
  if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
26729
26732
  return {
26730
- path: path47,
26733
+ path: path48,
26731
26734
  score: 1,
26732
26735
  weight,
26733
26736
  hit: true,
26734
- message: path47
26737
+ message: path48
26735
26738
  };
26736
26739
  }
26737
26740
  return {
26738
- path: path47,
26741
+ path: path48,
26739
26742
  score: 0,
26740
26743
  weight,
26741
26744
  hit: false,
26742
- message: `${path47} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
26745
+ message: `${path48} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
26743
26746
  };
26744
26747
  }
26745
26748
  /**
@@ -26772,11 +26775,11 @@ var FieldAccuracyEvaluator = class {
26772
26775
  };
26773
26776
  }
26774
26777
  };
26775
- function resolvePath(obj, path47) {
26776
- if (!path47 || !obj) {
26778
+ function resolvePath(obj, path48) {
26779
+ if (!path48 || !obj) {
26777
26780
  return void 0;
26778
26781
  }
26779
- const parts = path47.split(/\.|\[|\]/).filter((p) => p.length > 0);
26782
+ const parts = path48.split(/\.|\[|\]/).filter((p) => p.length > 0);
26780
26783
  let current = obj;
26781
26784
  for (const part of parts) {
26782
26785
  if (current === null || current === void 0) {
@@ -27250,8 +27253,8 @@ var TokenUsageEvaluator = class {
27250
27253
  };
27251
27254
  }
27252
27255
  };
27253
- function getNestedValue(obj, path47) {
27254
- const parts = path47.split(".");
27256
+ function getNestedValue(obj, path48) {
27257
+ const parts = path48.split(".");
27255
27258
  let current = obj;
27256
27259
  for (const part of parts) {
27257
27260
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -31421,7 +31424,7 @@ async function discoverDefaultTarget(repoRoot) {
31421
31424
  return null;
31422
31425
  }
31423
31426
  async function loadEnvHierarchy(repoRoot, startPath) {
31424
- const { readFileSync: readFileSync2 } = await import("node:fs");
31427
+ const { readFileSync: readFileSync3 } = await import("node:fs");
31425
31428
  const chain = buildDirectoryChain(startPath, repoRoot);
31426
31429
  const envFiles = [];
31427
31430
  for (const dir of chain) {
@@ -31430,7 +31433,7 @@ async function loadEnvHierarchy(repoRoot, startPath) {
31430
31433
  }
31431
31434
  for (let i = 0; i < envFiles.length; i++) {
31432
31435
  try {
31433
- const content = readFileSync2(envFiles[i], "utf8");
31436
+ const content = readFileSync3(envFiles[i], "utf8");
31434
31437
  for (const line of content.split("\n")) {
31435
31438
  const trimmed = line.trim();
31436
31439
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -31499,12 +31502,12 @@ var CONFIG_FILE_NAMES = [
31499
31502
  ".agentv/config.js"
31500
31503
  ];
31501
31504
  async function loadTsConfig(projectRoot) {
31502
- const { existsSync: existsSync5 } = await import("node:fs");
31505
+ const { existsSync: existsSync6 } = await import("node:fs");
31503
31506
  const { pathToFileURL } = await import("node:url");
31504
31507
  const { join: join2 } = await import("node:path");
31505
31508
  for (const fileName of CONFIG_FILE_NAMES) {
31506
31509
  const filePath = join2(projectRoot, fileName);
31507
- if (!existsSync5(filePath)) {
31510
+ if (!existsSync6(filePath)) {
31508
31511
  continue;
31509
31512
  }
31510
31513
  try {
@@ -31632,6 +31635,116 @@ function shouldSkipCacheForTemperature(targetConfig) {
31632
31635
  }
31633
31636
  return false;
31634
31637
  }
31638
+ function getProjectsRegistryPath() {
31639
+ return path47.join(getAgentvHome(), "projects.yaml");
31640
+ }
31641
+ function loadProjectRegistry() {
31642
+ const registryPath = getProjectsRegistryPath();
31643
+ if (!existsSync5(registryPath)) {
31644
+ return { projects: [] };
31645
+ }
31646
+ try {
31647
+ const raw = readFileSync2(registryPath, "utf-8");
31648
+ const parsed = parseYaml3(raw);
31649
+ if (!parsed || !Array.isArray(parsed.projects)) {
31650
+ return { projects: [] };
31651
+ }
31652
+ return { projects: parsed.projects };
31653
+ } catch {
31654
+ return { projects: [] };
31655
+ }
31656
+ }
31657
+ function saveProjectRegistry(registry) {
31658
+ const registryPath = getProjectsRegistryPath();
31659
+ const dir = path47.dirname(registryPath);
31660
+ if (!existsSync5(dir)) {
31661
+ mkdirSync(dir, { recursive: true });
31662
+ }
31663
+ writeFileSync(registryPath, stringifyYaml(registry), "utf-8");
31664
+ }
31665
+ function deriveProjectId(dirPath, existingIds) {
31666
+ const base = path47.basename(dirPath).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
31667
+ let candidate = base || "project";
31668
+ let suffix = 2;
31669
+ while (existingIds.includes(candidate)) {
31670
+ candidate = `${base}-${suffix}`;
31671
+ suffix++;
31672
+ }
31673
+ return candidate;
31674
+ }
31675
+ function addProject(projectPath) {
31676
+ const absPath = path47.resolve(projectPath);
31677
+ if (!existsSync5(absPath)) {
31678
+ throw new Error(`Directory not found: ${absPath}`);
31679
+ }
31680
+ if (!existsSync5(path47.join(absPath, ".agentv"))) {
31681
+ throw new Error(`No .agentv/ directory found in ${absPath}. Run an evaluation first.`);
31682
+ }
31683
+ const registry = loadProjectRegistry();
31684
+ const existing = registry.projects.find((p) => p.path === absPath);
31685
+ if (existing) {
31686
+ return existing;
31687
+ }
31688
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
31689
+ const entry = {
31690
+ id: deriveProjectId(
31691
+ absPath,
31692
+ registry.projects.map((p) => p.id)
31693
+ ),
31694
+ name: path47.basename(absPath),
31695
+ path: absPath,
31696
+ addedAt: now2,
31697
+ lastOpenedAt: now2
31698
+ };
31699
+ registry.projects.push(entry);
31700
+ saveProjectRegistry(registry);
31701
+ return entry;
31702
+ }
31703
+ function removeProject(projectId) {
31704
+ const registry = loadProjectRegistry();
31705
+ const idx = registry.projects.findIndex((p) => p.id === projectId);
31706
+ if (idx < 0) return false;
31707
+ registry.projects.splice(idx, 1);
31708
+ saveProjectRegistry(registry);
31709
+ return true;
31710
+ }
31711
+ function getProject(projectId) {
31712
+ return loadProjectRegistry().projects.find((p) => p.id === projectId);
31713
+ }
31714
+ function touchProject(projectId) {
31715
+ const registry = loadProjectRegistry();
31716
+ const entry = registry.projects.find((p) => p.id === projectId);
31717
+ if (entry) {
31718
+ entry.lastOpenedAt = (/* @__PURE__ */ new Date()).toISOString();
31719
+ saveProjectRegistry(registry);
31720
+ }
31721
+ }
31722
+ function discoverProjects(rootDir, maxDepth = 2) {
31723
+ const absRoot = path47.resolve(rootDir);
31724
+ if (!existsSync5(absRoot) || !statSync2(absRoot).isDirectory()) {
31725
+ return [];
31726
+ }
31727
+ const results = [];
31728
+ function scan(dir, depth) {
31729
+ if (depth > maxDepth) return;
31730
+ if (existsSync5(path47.join(dir, ".agentv"))) {
31731
+ results.push(dir);
31732
+ return;
31733
+ }
31734
+ if (depth === maxDepth) return;
31735
+ try {
31736
+ const entries = readdirSync3(dir, { withFileTypes: true });
31737
+ for (const entry of entries) {
31738
+ if (!entry.isDirectory()) continue;
31739
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
31740
+ scan(path47.join(dir, entry.name), depth + 1);
31741
+ }
31742
+ } catch {
31743
+ }
31744
+ }
31745
+ scan(absRoot, 0);
31746
+ return results;
31747
+ }
31635
31748
  var STRIPPED_TOP_LEVEL_FIELDS = /* @__PURE__ */ new Set([
31636
31749
  "requests",
31637
31750
  "trace",
@@ -32335,6 +32448,15 @@ export {
32335
32448
  ResponseCache,
32336
32449
  shouldEnableCache,
32337
32450
  shouldSkipCacheForTemperature,
32451
+ getProjectsRegistryPath,
32452
+ loadProjectRegistry,
32453
+ saveProjectRegistry,
32454
+ deriveProjectId,
32455
+ addProject,
32456
+ removeProject,
32457
+ getProject,
32458
+ touchProject,
32459
+ discoverProjects,
32338
32460
  trimBaselineResult,
32339
32461
  DEFAULT_CATEGORY,
32340
32462
  deriveCategory,
@@ -32343,4 +32465,4 @@ export {
32343
32465
  OtelStreamingObserver,
32344
32466
  createAgentKernel
32345
32467
  };
32346
- //# sourceMappingURL=chunk-HMOXP7T5.js.map
32468
+ //# sourceMappingURL=chunk-63NDZ6UC.js.map