@agentv/core 4.8.0 → 4.9.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.
package/dist/index.cjs CHANGED
@@ -1355,13 +1355,13 @@ function serializeAttributeValue(value) {
1355
1355
  if (Array.isArray(value)) return { arrayValue: { values: value.map(serializeAttributeValue) } };
1356
1356
  return { stringValue: String(value) };
1357
1357
  }
1358
- var import_promises35, import_node_path52, OtlpJsonFileExporter;
1358
+ var import_promises36, import_node_path53, OtlpJsonFileExporter;
1359
1359
  var init_otlp_json_file_exporter = __esm({
1360
1360
  "src/observability/otlp-json-file-exporter.ts"() {
1361
1361
  "use strict";
1362
1362
  init_cjs_shims();
1363
- import_promises35 = require("fs/promises");
1364
- import_node_path52 = require("path");
1363
+ import_promises36 = require("fs/promises");
1364
+ import_node_path53 = require("path");
1365
1365
  OtlpJsonFileExporter = class {
1366
1366
  // biome-ignore lint/suspicious/noExplicitAny: serialized span data
1367
1367
  spans = [];
@@ -1400,7 +1400,7 @@ var init_otlp_json_file_exporter = __esm({
1400
1400
  }
1401
1401
  async flush() {
1402
1402
  if (this.spans.length === 0) return;
1403
- await (0, import_promises35.mkdir)((0, import_node_path52.dirname)(this.filePath), { recursive: true });
1403
+ await (0, import_promises36.mkdir)((0, import_node_path53.dirname)(this.filePath), { recursive: true });
1404
1404
  const otlpJson = {
1405
1405
  resourceSpans: [
1406
1406
  {
@@ -1583,6 +1583,7 @@ __export(index_exports, {
1583
1583
  runRegexAssertion: () => runRegexAssertion,
1584
1584
  runStartsWithAssertion: () => runStartsWithAssertion,
1585
1585
  saveProjectRegistry: () => saveProjectRegistry,
1586
+ scanRepoDeps: () => scanRepoDeps,
1586
1587
  scoreToVerdict: () => scoreToVerdict,
1587
1588
  shouldEnableCache: () => shouldEnableCache,
1588
1589
  shouldSkipCacheForTemperature: () => shouldSkipCacheForTemperature,
@@ -4741,6 +4742,61 @@ function parseMetadata(suite) {
4741
4742
  });
4742
4743
  }
4743
4744
 
4745
+ // src/evaluation/workspace/repo-config-parser.ts
4746
+ init_cjs_shims();
4747
+ function parseRepoSource(raw) {
4748
+ if (!isJsonObject(raw)) return void 0;
4749
+ const obj = raw;
4750
+ if (obj.type === "git" && typeof obj.url === "string") {
4751
+ return { type: "git", url: obj.url };
4752
+ }
4753
+ if (obj.type === "local" && typeof obj.path === "string") {
4754
+ return { type: "local", path: obj.path };
4755
+ }
4756
+ return void 0;
4757
+ }
4758
+ function parseRepoCheckout(raw) {
4759
+ if (!isJsonObject(raw)) return void 0;
4760
+ const obj = raw;
4761
+ const ref = typeof obj.ref === "string" ? obj.ref : void 0;
4762
+ const resolve = obj.resolve === "remote" || obj.resolve === "local" ? obj.resolve : void 0;
4763
+ const ancestor = typeof obj.ancestor === "number" ? obj.ancestor : void 0;
4764
+ if (!ref && !resolve && ancestor === void 0) return void 0;
4765
+ return {
4766
+ ...ref !== void 0 && { ref },
4767
+ ...resolve !== void 0 && { resolve },
4768
+ ...ancestor !== void 0 && { ancestor }
4769
+ };
4770
+ }
4771
+ function parseRepoClone(raw) {
4772
+ if (!isJsonObject(raw)) return void 0;
4773
+ const obj = raw;
4774
+ const depth = typeof obj.depth === "number" ? obj.depth : void 0;
4775
+ const filter = typeof obj.filter === "string" ? obj.filter : void 0;
4776
+ const sparse = Array.isArray(obj.sparse) ? obj.sparse.filter((s) => typeof s === "string") : void 0;
4777
+ if (depth === void 0 && !filter && !sparse) return void 0;
4778
+ return {
4779
+ ...depth !== void 0 && { depth },
4780
+ ...filter !== void 0 && { filter },
4781
+ ...sparse !== void 0 && { sparse }
4782
+ };
4783
+ }
4784
+ function parseRepoConfig(raw) {
4785
+ if (!isJsonObject(raw)) return void 0;
4786
+ const obj = raw;
4787
+ const repoPath = typeof obj.path === "string" ? obj.path : void 0;
4788
+ const source = parseRepoSource(obj.source);
4789
+ if (!repoPath || !source) return void 0;
4790
+ const checkout = parseRepoCheckout(obj.checkout);
4791
+ const clone = parseRepoClone(obj.clone);
4792
+ return {
4793
+ path: repoPath,
4794
+ source,
4795
+ ...checkout !== void 0 && { checkout },
4796
+ ...clone !== void 0 && { clone }
4797
+ };
4798
+ }
4799
+
4744
4800
  // src/evaluation/formatting/prompt-builder.ts
4745
4801
  init_cjs_shims();
4746
4802
  async function buildPromptInputs(testCase, mode = "lm") {
@@ -5136,58 +5192,6 @@ function parseWorkspaceScriptConfig(raw, evalFileDir) {
5136
5192
  }
5137
5193
  return cwd ? { ...config, cwd } : config;
5138
5194
  }
5139
- function parseRepoSource(raw) {
5140
- if (!isJsonObject(raw)) return void 0;
5141
- const obj = raw;
5142
- if (obj.type === "git" && typeof obj.url === "string") {
5143
- return { type: "git", url: obj.url };
5144
- }
5145
- if (obj.type === "local" && typeof obj.path === "string") {
5146
- return { type: "local", path: obj.path };
5147
- }
5148
- return void 0;
5149
- }
5150
- function parseRepoCheckout(raw) {
5151
- if (!isJsonObject(raw)) return void 0;
5152
- const obj = raw;
5153
- const ref = typeof obj.ref === "string" ? obj.ref : void 0;
5154
- const resolve = obj.resolve === "remote" || obj.resolve === "local" ? obj.resolve : void 0;
5155
- const ancestor = typeof obj.ancestor === "number" ? obj.ancestor : void 0;
5156
- if (!ref && !resolve && ancestor === void 0) return void 0;
5157
- return {
5158
- ...ref !== void 0 && { ref },
5159
- ...resolve !== void 0 && { resolve },
5160
- ...ancestor !== void 0 && { ancestor }
5161
- };
5162
- }
5163
- function parseRepoClone(raw) {
5164
- if (!isJsonObject(raw)) return void 0;
5165
- const obj = raw;
5166
- const depth = typeof obj.depth === "number" ? obj.depth : void 0;
5167
- const filter = typeof obj.filter === "string" ? obj.filter : void 0;
5168
- const sparse = Array.isArray(obj.sparse) ? obj.sparse.filter((s) => typeof s === "string") : void 0;
5169
- if (depth === void 0 && !filter && !sparse) return void 0;
5170
- return {
5171
- ...depth !== void 0 && { depth },
5172
- ...filter !== void 0 && { filter },
5173
- ...sparse !== void 0 && { sparse }
5174
- };
5175
- }
5176
- function parseRepoConfig(raw) {
5177
- if (!isJsonObject(raw)) return void 0;
5178
- const obj = raw;
5179
- const repoPath = typeof obj.path === "string" ? obj.path : void 0;
5180
- const source = parseRepoSource(obj.source);
5181
- if (!repoPath || !source) return void 0;
5182
- const checkout = parseRepoCheckout(obj.checkout);
5183
- const clone = parseRepoClone(obj.clone);
5184
- return {
5185
- path: repoPath,
5186
- source,
5187
- ...checkout !== void 0 && { checkout },
5188
- ...clone !== void 0 && { clone }
5189
- };
5190
- }
5191
5195
  function parseWorkspaceHookConfig(raw, evalFileDir) {
5192
5196
  if (!isJsonObject(raw)) return void 0;
5193
5197
  const script = parseWorkspaceScriptConfig(raw, evalFileDir);
@@ -12291,8 +12295,8 @@ function resolveCliConfig(target, env, evalFilePath) {
12291
12295
  const parseResult = CliTargetInputSchema.safeParse(target, { errorMap: cliErrorMap });
12292
12296
  if (!parseResult.success) {
12293
12297
  const firstError = parseResult.error.errors[0];
12294
- const path53 = firstError?.path.join(".") || "";
12295
- const prefix = path53 ? `${target.name} ${path53}: ` : `${target.name}: `;
12298
+ const path54 = firstError?.path.join(".") || "";
12299
+ const prefix = path54 ? `${target.name} ${path54}: ` : `${target.name}: `;
12296
12300
  throw new Error(`${prefix}${firstError?.message}`);
12297
12301
  }
12298
12302
  const normalized = normalizeCliTargetInput(parseResult.data, env, evalFilePath);
@@ -14337,15 +14341,15 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
14337
14341
  });
14338
14342
  }
14339
14343
  async function execShellWithStdin(command, stdinPayload, options = {}) {
14340
- const { mkdir: mkdir17, readFile: readFile17, rm: rm6, writeFile: writeFile9 } = await import("fs/promises");
14344
+ const { mkdir: mkdir17, readFile: readFile18, rm: rm6, writeFile: writeFile9 } = await import("fs/promises");
14341
14345
  const { tmpdir: tmpdir3 } = await import("os");
14342
- const path53 = await import("path");
14346
+ const path54 = await import("path");
14343
14347
  const { randomUUID: randomUUID10 } = await import("crypto");
14344
- const dir = path53.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
14348
+ const dir = path54.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
14345
14349
  await mkdir17(dir, { recursive: true });
14346
- const stdinPath = path53.join(dir, "stdin.txt");
14347
- const stdoutPath = path53.join(dir, "stdout.txt");
14348
- const stderrPath = path53.join(dir, "stderr.txt");
14350
+ const stdinPath = path54.join(dir, "stdin.txt");
14351
+ const stdoutPath = path54.join(dir, "stdout.txt");
14352
+ const stderrPath = path54.join(dir, "stderr.txt");
14349
14353
  await writeFile9(stdinPath, stdinPayload, "utf8");
14350
14354
  const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
14351
14355
  const { spawn: spawn5 } = await import("child_process");
@@ -14375,8 +14379,8 @@ async function execShellWithStdin(command, stdinPayload, options = {}) {
14375
14379
  resolve(code ?? 0);
14376
14380
  });
14377
14381
  });
14378
- const stdout = (await readFile17(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
14379
- const stderr = (await readFile17(stderrPath, "utf8")).replace(/\r\n/g, "\n");
14382
+ const stdout = (await readFile18(stdoutPath, "utf8")).replace(/\r\n/g, "\n");
14383
+ const stderr = (await readFile18(stderrPath, "utf8")).replace(/\r\n/g, "\n");
14380
14384
  return { stdout, stderr, exitCode };
14381
14385
  } finally {
14382
14386
  await rm6(dir, { recursive: true, force: true });
@@ -16642,115 +16646,115 @@ var FieldAccuracyEvaluator = class {
16642
16646
  * Evaluate a single field against the expected value.
16643
16647
  */
16644
16648
  evaluateField(fieldConfig, candidateData, expectedData) {
16645
- const { path: path53, match, required = true, weight = 1 } = fieldConfig;
16646
- const candidateValue = resolvePath(candidateData, path53);
16647
- const expectedValue = resolvePath(expectedData, path53);
16649
+ const { path: path54, match, required = true, weight = 1 } = fieldConfig;
16650
+ const candidateValue = resolvePath(candidateData, path54);
16651
+ const expectedValue = resolvePath(expectedData, path54);
16648
16652
  if (expectedValue === void 0) {
16649
16653
  return {
16650
- path: path53,
16654
+ path: path54,
16651
16655
  score: 1,
16652
16656
  // No expected value means no comparison needed
16653
16657
  weight,
16654
16658
  hit: true,
16655
- message: `${path53}: no expected value`
16659
+ message: `${path54}: no expected value`
16656
16660
  };
16657
16661
  }
16658
16662
  if (candidateValue === void 0) {
16659
16663
  if (required) {
16660
16664
  return {
16661
- path: path53,
16665
+ path: path54,
16662
16666
  score: 0,
16663
16667
  weight,
16664
16668
  hit: false,
16665
- message: `${path53} (required, missing)`
16669
+ message: `${path54} (required, missing)`
16666
16670
  };
16667
16671
  }
16668
16672
  return {
16669
- path: path53,
16673
+ path: path54,
16670
16674
  score: 1,
16671
16675
  // Don't penalize missing optional fields
16672
16676
  weight: 0,
16673
16677
  // Zero weight means it won't affect the score
16674
16678
  hit: true,
16675
- message: `${path53}: optional field missing`
16679
+ message: `${path54}: optional field missing`
16676
16680
  };
16677
16681
  }
16678
16682
  switch (match) {
16679
16683
  case "exact":
16680
- return this.compareExact(path53, candidateValue, expectedValue, weight);
16684
+ return this.compareExact(path54, candidateValue, expectedValue, weight);
16681
16685
  case "numeric_tolerance":
16682
16686
  return this.compareNumericTolerance(
16683
- path53,
16687
+ path54,
16684
16688
  candidateValue,
16685
16689
  expectedValue,
16686
16690
  fieldConfig,
16687
16691
  weight
16688
16692
  );
16689
16693
  case "date":
16690
- return this.compareDate(path53, candidateValue, expectedValue, fieldConfig, weight);
16694
+ return this.compareDate(path54, candidateValue, expectedValue, fieldConfig, weight);
16691
16695
  default:
16692
16696
  return {
16693
- path: path53,
16697
+ path: path54,
16694
16698
  score: 0,
16695
16699
  weight,
16696
16700
  hit: false,
16697
- message: `${path53}: unknown match type "${match}"`
16701
+ message: `${path54}: unknown match type "${match}"`
16698
16702
  };
16699
16703
  }
16700
16704
  }
16701
16705
  /**
16702
16706
  * Exact equality comparison.
16703
16707
  */
16704
- compareExact(path53, candidateValue, expectedValue, weight) {
16708
+ compareExact(path54, candidateValue, expectedValue, weight) {
16705
16709
  if (deepEqual(candidateValue, expectedValue)) {
16706
16710
  return {
16707
- path: path53,
16711
+ path: path54,
16708
16712
  score: 1,
16709
16713
  weight,
16710
16714
  hit: true,
16711
- message: path53
16715
+ message: path54
16712
16716
  };
16713
16717
  }
16714
16718
  if (typeof candidateValue !== typeof expectedValue) {
16715
16719
  return {
16716
- path: path53,
16720
+ path: path54,
16717
16721
  score: 0,
16718
16722
  weight,
16719
16723
  hit: false,
16720
- message: `${path53} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
16724
+ message: `${path54} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
16721
16725
  };
16722
16726
  }
16723
16727
  return {
16724
- path: path53,
16728
+ path: path54,
16725
16729
  score: 0,
16726
16730
  weight,
16727
16731
  hit: false,
16728
- message: `${path53} (value mismatch)`
16732
+ message: `${path54} (value mismatch)`
16729
16733
  };
16730
16734
  }
16731
16735
  /**
16732
16736
  * Numeric comparison with absolute or relative tolerance.
16733
16737
  */
16734
- compareNumericTolerance(path53, candidateValue, expectedValue, fieldConfig, weight) {
16738
+ compareNumericTolerance(path54, candidateValue, expectedValue, fieldConfig, weight) {
16735
16739
  const { tolerance = 0, relative = false } = fieldConfig;
16736
16740
  const candidateNum = toNumber(candidateValue);
16737
16741
  const expectedNum = toNumber(expectedValue);
16738
16742
  if (candidateNum === null || expectedNum === null) {
16739
16743
  return {
16740
- path: path53,
16744
+ path: path54,
16741
16745
  score: 0,
16742
16746
  weight,
16743
16747
  hit: false,
16744
- message: `${path53} (non-numeric value)`
16748
+ message: `${path54} (non-numeric value)`
16745
16749
  };
16746
16750
  }
16747
16751
  if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
16748
16752
  return {
16749
- path: path53,
16753
+ path: path54,
16750
16754
  score: 0,
16751
16755
  weight,
16752
16756
  hit: false,
16753
- message: `${path53} (invalid numeric value)`
16757
+ message: `${path54} (invalid numeric value)`
16754
16758
  };
16755
16759
  }
16756
16760
  const diff = Math.abs(candidateNum - expectedNum);
@@ -16763,61 +16767,61 @@ var FieldAccuracyEvaluator = class {
16763
16767
  }
16764
16768
  if (withinTolerance) {
16765
16769
  return {
16766
- path: path53,
16770
+ path: path54,
16767
16771
  score: 1,
16768
16772
  weight,
16769
16773
  hit: true,
16770
- message: `${path53} (within tolerance: diff=${diff.toFixed(2)})`
16774
+ message: `${path54} (within tolerance: diff=${diff.toFixed(2)})`
16771
16775
  };
16772
16776
  }
16773
16777
  return {
16774
- path: path53,
16778
+ path: path54,
16775
16779
  score: 0,
16776
16780
  weight,
16777
16781
  hit: false,
16778
- message: `${path53} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
16782
+ message: `${path54} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
16779
16783
  };
16780
16784
  }
16781
16785
  /**
16782
16786
  * Date comparison with format normalization.
16783
16787
  */
16784
- compareDate(path53, candidateValue, expectedValue, fieldConfig, weight) {
16788
+ compareDate(path54, candidateValue, expectedValue, fieldConfig, weight) {
16785
16789
  const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
16786
16790
  const candidateDate = parseDate(String(candidateValue), formats);
16787
16791
  const expectedDate = parseDate(String(expectedValue), formats);
16788
16792
  if (candidateDate === null) {
16789
16793
  return {
16790
- path: path53,
16794
+ path: path54,
16791
16795
  score: 0,
16792
16796
  weight,
16793
16797
  hit: false,
16794
- message: `${path53} (unparseable candidate date)`
16798
+ message: `${path54} (unparseable candidate date)`
16795
16799
  };
16796
16800
  }
16797
16801
  if (expectedDate === null) {
16798
16802
  return {
16799
- path: path53,
16803
+ path: path54,
16800
16804
  score: 0,
16801
16805
  weight,
16802
16806
  hit: false,
16803
- message: `${path53} (unparseable expected date)`
16807
+ message: `${path54} (unparseable expected date)`
16804
16808
  };
16805
16809
  }
16806
16810
  if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
16807
16811
  return {
16808
- path: path53,
16812
+ path: path54,
16809
16813
  score: 1,
16810
16814
  weight,
16811
16815
  hit: true,
16812
- message: path53
16816
+ message: path54
16813
16817
  };
16814
16818
  }
16815
16819
  return {
16816
- path: path53,
16820
+ path: path54,
16817
16821
  score: 0,
16818
16822
  weight,
16819
16823
  hit: false,
16820
- message: `${path53} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
16824
+ message: `${path54} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
16821
16825
  };
16822
16826
  }
16823
16827
  /**
@@ -16850,11 +16854,11 @@ var FieldAccuracyEvaluator = class {
16850
16854
  };
16851
16855
  }
16852
16856
  };
16853
- function resolvePath(obj, path53) {
16854
- if (!path53 || !obj) {
16857
+ function resolvePath(obj, path54) {
16858
+ if (!path54 || !obj) {
16855
16859
  return void 0;
16856
16860
  }
16857
- const parts = path53.split(/\.|\[|\]/).filter((p) => p.length > 0);
16861
+ const parts = path54.split(/\.|\[|\]/).filter((p) => p.length > 0);
16858
16862
  let current = obj;
16859
16863
  for (const part of parts) {
16860
16864
  if (current === null || current === void 0) {
@@ -17351,8 +17355,8 @@ var TokenUsageEvaluator = class {
17351
17355
 
17352
17356
  // src/evaluation/evaluators/tool-trajectory.ts
17353
17357
  init_cjs_shims();
17354
- function getNestedValue(obj, path53) {
17355
- const parts = path53.split(".");
17358
+ function getNestedValue(obj, path54) {
17359
+ const parts = path54.split(".");
17356
17360
  let current = obj;
17357
17361
  for (const part of parts) {
17358
17362
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -17975,6 +17979,7 @@ function runEqualsAssertion(output, value) {
17975
17979
  // src/evaluation/orchestrator.ts
17976
17980
  init_cjs_shims();
17977
17981
  var import_node_crypto11 = require("crypto");
17982
+ var import_node_fs16 = require("fs");
17978
17983
  var import_promises33 = require("fs/promises");
17979
17984
  var import_node_path48 = __toESM(require("path"), 1);
17980
17985
  var import_micromatch3 = __toESM(require("micromatch"), 1);
@@ -19776,8 +19781,8 @@ async function runEvaluation(options) {
19776
19781
  const poolSlotBaselines = /* @__PURE__ */ new Map();
19777
19782
  const poolMaxSlots = Math.min(configPoolMaxSlots ?? 10, 50);
19778
19783
  let staticMaterialised = false;
19784
+ const isYamlConfiguredPath = !cliWorkspacePath && !!yamlWorkspacePath;
19779
19785
  if (useStaticWorkspace && configuredStaticPath) {
19780
- const isYamlConfiguredPath = !cliWorkspacePath && !!yamlWorkspacePath;
19781
19786
  const dirExists = await (0, import_promises33.stat)(configuredStaticPath).then(
19782
19787
  (s) => s.isDirectory(),
19783
19788
  () => false
@@ -19842,14 +19847,28 @@ async function runEvaluation(options) {
19842
19847
  } catch {
19843
19848
  }
19844
19849
  }
19845
- const needsRepoMaterialisation = !!suiteWorkspace?.repos?.length && !usePool && (!useStaticWorkspace || staticMaterialised);
19846
- const repoManager = needsRepoMaterialisation ? new RepoManager(verbose) : void 0;
19847
- if (repoManager && sharedWorkspacePath && suiteWorkspace?.repos && !isPerTestIsolation) {
19848
- setupLog(
19849
- `materializing ${suiteWorkspace.repos.length} shared repo(s) into ${sharedWorkspacePath}`
19850
- );
19850
+ const hasReposToMaterialize = !!suiteWorkspace?.repos?.length && !usePool && !isPerTestIsolation;
19851
+ const needsRepoMaterialisation = hasReposToMaterialize && (!useStaticWorkspace || staticMaterialised);
19852
+ const needsPerRepoCheck = hasReposToMaterialize && useStaticWorkspace && !staticMaterialised && isYamlConfiguredPath;
19853
+ const repoManager = needsRepoMaterialisation || needsPerRepoCheck ? new RepoManager(verbose) : void 0;
19854
+ if (repoManager && sharedWorkspacePath && suiteWorkspace?.repos) {
19851
19855
  try {
19852
- await repoManager.materializeAll(suiteWorkspace.repos, sharedWorkspacePath);
19856
+ if (needsPerRepoCheck) {
19857
+ for (const repo of suiteWorkspace.repos) {
19858
+ const targetDir = import_node_path48.default.join(sharedWorkspacePath, repo.path);
19859
+ if ((0, import_node_fs16.existsSync)(targetDir)) {
19860
+ setupLog(`reusing existing repo at: ${targetDir}`);
19861
+ continue;
19862
+ }
19863
+ setupLog(`materializing missing repo: ${repo.path}`);
19864
+ await repoManager.materialize(repo, sharedWorkspacePath);
19865
+ }
19866
+ } else {
19867
+ setupLog(
19868
+ `materializing ${suiteWorkspace.repos.length} shared repo(s) into ${sharedWorkspacePath}`
19869
+ );
19870
+ await repoManager.materializeAll(suiteWorkspace.repos, sharedWorkspacePath);
19871
+ }
19853
19872
  setupLog("shared repo materialization complete");
19854
19873
  } catch (error) {
19855
19874
  const message = error instanceof Error ? error.message : String(error);
@@ -21524,7 +21543,7 @@ function computeWeightedMean(entries) {
21524
21543
 
21525
21544
  // src/evaluation/evaluate.ts
21526
21545
  init_cjs_shims();
21527
- var import_node_fs16 = require("fs");
21546
+ var import_node_fs17 = require("fs");
21528
21547
  var import_node_path49 = __toESM(require("path"), 1);
21529
21548
 
21530
21549
  // src/evaluation/providers/function-provider.ts
@@ -21682,7 +21701,7 @@ async function discoverDefaultTarget(repoRoot) {
21682
21701
  for (const dir of chain) {
21683
21702
  for (const candidate of TARGET_FILE_CANDIDATES) {
21684
21703
  const targetsPath = import_node_path49.default.join(dir, candidate);
21685
- if (!(0, import_node_fs16.existsSync)(targetsPath)) continue;
21704
+ if (!(0, import_node_fs17.existsSync)(targetsPath)) continue;
21686
21705
  try {
21687
21706
  const definitions = await readTargetDefinitions(targetsPath);
21688
21707
  const defaultTarget = definitions.find((d) => d.name === "default");
@@ -21699,7 +21718,7 @@ async function loadEnvHierarchy(repoRoot, startPath) {
21699
21718
  const envFiles = [];
21700
21719
  for (const dir of chain) {
21701
21720
  const envPath = import_node_path49.default.join(dir, ".env");
21702
- if ((0, import_node_fs16.existsSync)(envPath)) envFiles.push(envPath);
21721
+ if ((0, import_node_fs17.existsSync)(envPath)) envFiles.push(envPath);
21703
21722
  }
21704
21723
  for (let i = 0; i < envFiles.length; i++) {
21705
21724
  try {
@@ -21776,12 +21795,12 @@ var CONFIG_FILE_NAMES = [
21776
21795
  ".agentv/config.js"
21777
21796
  ];
21778
21797
  async function loadTsConfig(projectRoot) {
21779
- const { existsSync: existsSync7 } = await import("fs");
21798
+ const { existsSync: existsSync8 } = await import("fs");
21780
21799
  const { pathToFileURL: pathToFileURL2 } = await import("url");
21781
21800
  const { join: join2 } = await import("path");
21782
21801
  for (const fileName of CONFIG_FILE_NAMES) {
21783
21802
  const filePath = join2(projectRoot, fileName);
21784
- if (!existsSync7(filePath)) {
21803
+ if (!existsSync8(filePath)) {
21785
21804
  continue;
21786
21805
  }
21787
21806
  try {
@@ -21884,10 +21903,108 @@ function buildPrompt(criteria, question, referenceAnswer) {
21884
21903
  // src/evaluation/workspace/index.ts
21885
21904
  init_cjs_shims();
21886
21905
 
21887
- // src/evaluation/cache/response-cache.ts
21906
+ // src/evaluation/workspace/deps-scanner.ts
21888
21907
  init_cjs_shims();
21889
21908
  var import_promises34 = require("fs/promises");
21890
21909
  var import_node_path50 = __toESM(require("path"), 1);
21910
+ var import_yaml8 = require("yaml");
21911
+ function normalizeGitUrl(url) {
21912
+ let normalized = url.replace(/\.git$/, "");
21913
+ try {
21914
+ const parsed = new URL(normalized);
21915
+ parsed.hostname = parsed.hostname.toLowerCase();
21916
+ normalized = parsed.toString().replace(/\/$/, "");
21917
+ } catch {
21918
+ }
21919
+ return normalized;
21920
+ }
21921
+ async function scanRepoDeps(evalFilePaths) {
21922
+ const seen = /* @__PURE__ */ new Map();
21923
+ const errors = [];
21924
+ for (const filePath of evalFilePaths) {
21925
+ try {
21926
+ const repos = await extractReposFromEvalFile(filePath);
21927
+ for (const repo of repos) {
21928
+ if (repo.source.type !== "git") continue;
21929
+ const ref = repo.checkout?.ref;
21930
+ const key = `${normalizeGitUrl(repo.source.url)}\0${ref ?? ""}`;
21931
+ const existing = seen.get(key);
21932
+ if (existing) {
21933
+ existing.usedBy.push(filePath);
21934
+ } else {
21935
+ const { ref: _ref, ...checkoutRest } = repo.checkout ?? {};
21936
+ const hasCheckout = Object.keys(checkoutRest).length > 0;
21937
+ seen.set(key, {
21938
+ url: repo.source.url,
21939
+ ref,
21940
+ clone: repo.clone,
21941
+ checkout: hasCheckout ? checkoutRest : void 0,
21942
+ usedBy: [filePath]
21943
+ });
21944
+ }
21945
+ }
21946
+ } catch (err) {
21947
+ errors.push({
21948
+ file: filePath,
21949
+ message: err instanceof Error ? err.message : String(err)
21950
+ });
21951
+ }
21952
+ }
21953
+ return { repos: [...seen.values()], errors };
21954
+ }
21955
+ async function extractReposFromEvalFile(filePath) {
21956
+ const content = await (0, import_promises34.readFile)(filePath, "utf8");
21957
+ const parsed = interpolateEnv((0, import_yaml8.parse)(content), process.env);
21958
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return [];
21959
+ const obj = parsed;
21960
+ const evalFileDir = import_node_path50.default.dirname(import_node_path50.default.resolve(filePath));
21961
+ const repos = [];
21962
+ const suiteRepos = await extractReposFromWorkspaceRaw(obj.workspace, evalFileDir);
21963
+ repos.push(...suiteRepos);
21964
+ const tests = Array.isArray(obj.tests) ? obj.tests : [];
21965
+ for (const test of tests) {
21966
+ if (test && typeof test === "object" && !Array.isArray(test)) {
21967
+ const testObj = test;
21968
+ const testRepos = await extractReposFromWorkspaceRaw(testObj.workspace, evalFileDir);
21969
+ repos.push(...testRepos);
21970
+ }
21971
+ }
21972
+ return repos;
21973
+ }
21974
+ async function extractReposFromWorkspaceRaw(raw, evalFileDir) {
21975
+ if (typeof raw === "string") {
21976
+ const workspaceFilePath = import_node_path50.default.resolve(evalFileDir, raw);
21977
+ const content = await (0, import_promises34.readFile)(workspaceFilePath, "utf8");
21978
+ const parsed = interpolateEnv((0, import_yaml8.parse)(content), process.env);
21979
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return [];
21980
+ return extractReposFromObject(parsed);
21981
+ }
21982
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
21983
+ return extractReposFromObject(raw);
21984
+ }
21985
+ return [];
21986
+ }
21987
+ function extractReposFromObject(obj) {
21988
+ const rawRepos = Array.isArray(obj.repos) ? obj.repos : [];
21989
+ const result = [];
21990
+ for (const r of rawRepos) {
21991
+ if (!r || typeof r !== "object" || Array.isArray(r)) continue;
21992
+ const repo = r;
21993
+ const source = parseRepoSource(repo.source);
21994
+ if (!source) continue;
21995
+ result.push({
21996
+ source,
21997
+ checkout: parseRepoCheckout(repo.checkout),
21998
+ clone: parseRepoClone(repo.clone)
21999
+ });
22000
+ }
22001
+ return result;
22002
+ }
22003
+
22004
+ // src/evaluation/cache/response-cache.ts
22005
+ init_cjs_shims();
22006
+ var import_promises35 = require("fs/promises");
22007
+ var import_node_path51 = __toESM(require("path"), 1);
21891
22008
  var DEFAULT_CACHE_PATH = ".agentv/cache";
21892
22009
  var ResponseCache = class {
21893
22010
  cachePath;
@@ -21897,7 +22014,7 @@ var ResponseCache = class {
21897
22014
  async get(key) {
21898
22015
  const filePath = this.keyToPath(key);
21899
22016
  try {
21900
- const data = await (0, import_promises34.readFile)(filePath, "utf8");
22017
+ const data = await (0, import_promises35.readFile)(filePath, "utf8");
21901
22018
  return JSON.parse(data);
21902
22019
  } catch {
21903
22020
  return void 0;
@@ -21905,13 +22022,13 @@ var ResponseCache = class {
21905
22022
  }
21906
22023
  async set(key, value) {
21907
22024
  const filePath = this.keyToPath(key);
21908
- const dir = import_node_path50.default.dirname(filePath);
21909
- await (0, import_promises34.mkdir)(dir, { recursive: true });
21910
- await (0, import_promises34.writeFile)(filePath, JSON.stringify(value, null, 2), "utf8");
22025
+ const dir = import_node_path51.default.dirname(filePath);
22026
+ await (0, import_promises35.mkdir)(dir, { recursive: true });
22027
+ await (0, import_promises35.writeFile)(filePath, JSON.stringify(value, null, 2), "utf8");
21911
22028
  }
21912
22029
  keyToPath(key) {
21913
22030
  const prefix = key.slice(0, 2);
21914
- return import_node_path50.default.join(this.cachePath, prefix, `${key}.json`);
22031
+ return import_node_path51.default.join(this.cachePath, prefix, `${key}.json`);
21915
22032
  }
21916
22033
  };
21917
22034
  function shouldEnableCache(params) {
@@ -21928,20 +22045,20 @@ function shouldSkipCacheForTemperature(targetConfig) {
21928
22045
 
21929
22046
  // src/projects.ts
21930
22047
  init_cjs_shims();
21931
- var import_node_fs17 = require("fs");
21932
- var import_node_path51 = __toESM(require("path"), 1);
21933
- var import_yaml8 = require("yaml");
22048
+ var import_node_fs18 = require("fs");
22049
+ var import_node_path52 = __toESM(require("path"), 1);
22050
+ var import_yaml9 = require("yaml");
21934
22051
  function getProjectsRegistryPath() {
21935
- return import_node_path51.default.join(getAgentvHome(), "projects.yaml");
22052
+ return import_node_path52.default.join(getAgentvHome(), "projects.yaml");
21936
22053
  }
21937
22054
  function loadProjectRegistry() {
21938
22055
  const registryPath = getProjectsRegistryPath();
21939
- if (!(0, import_node_fs17.existsSync)(registryPath)) {
22056
+ if (!(0, import_node_fs18.existsSync)(registryPath)) {
21940
22057
  return { projects: [] };
21941
22058
  }
21942
22059
  try {
21943
- const raw = (0, import_node_fs17.readFileSync)(registryPath, "utf-8");
21944
- const parsed = (0, import_yaml8.parse)(raw);
22060
+ const raw = (0, import_node_fs18.readFileSync)(registryPath, "utf-8");
22061
+ const parsed = (0, import_yaml9.parse)(raw);
21945
22062
  if (!parsed || !Array.isArray(parsed.projects)) {
21946
22063
  return { projects: [] };
21947
22064
  }
@@ -21952,14 +22069,14 @@ function loadProjectRegistry() {
21952
22069
  }
21953
22070
  function saveProjectRegistry(registry) {
21954
22071
  const registryPath = getProjectsRegistryPath();
21955
- const dir = import_node_path51.default.dirname(registryPath);
21956
- if (!(0, import_node_fs17.existsSync)(dir)) {
21957
- (0, import_node_fs17.mkdirSync)(dir, { recursive: true });
22072
+ const dir = import_node_path52.default.dirname(registryPath);
22073
+ if (!(0, import_node_fs18.existsSync)(dir)) {
22074
+ (0, import_node_fs18.mkdirSync)(dir, { recursive: true });
21958
22075
  }
21959
- (0, import_node_fs17.writeFileSync)(registryPath, (0, import_yaml8.stringify)(registry), "utf-8");
22076
+ (0, import_node_fs18.writeFileSync)(registryPath, (0, import_yaml9.stringify)(registry), "utf-8");
21960
22077
  }
21961
22078
  function deriveProjectId(dirPath, existingIds) {
21962
- const base = import_node_path51.default.basename(dirPath).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
22079
+ const base = import_node_path52.default.basename(dirPath).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
21963
22080
  let candidate = base || "project";
21964
22081
  let suffix = 2;
21965
22082
  while (existingIds.includes(candidate)) {
@@ -21969,11 +22086,11 @@ function deriveProjectId(dirPath, existingIds) {
21969
22086
  return candidate;
21970
22087
  }
21971
22088
  function addProject(projectPath) {
21972
- const absPath = import_node_path51.default.resolve(projectPath);
21973
- if (!(0, import_node_fs17.existsSync)(absPath)) {
22089
+ const absPath = import_node_path52.default.resolve(projectPath);
22090
+ if (!(0, import_node_fs18.existsSync)(absPath)) {
21974
22091
  throw new Error(`Directory not found: ${absPath}`);
21975
22092
  }
21976
- if (!(0, import_node_fs17.existsSync)(import_node_path51.default.join(absPath, ".agentv"))) {
22093
+ if (!(0, import_node_fs18.existsSync)(import_node_path52.default.join(absPath, ".agentv"))) {
21977
22094
  throw new Error(`No .agentv/ directory found in ${absPath}. Run an evaluation first.`);
21978
22095
  }
21979
22096
  const registry = loadProjectRegistry();
@@ -21987,7 +22104,7 @@ function addProject(projectPath) {
21987
22104
  absPath,
21988
22105
  registry.projects.map((p) => p.id)
21989
22106
  ),
21990
- name: import_node_path51.default.basename(absPath),
22107
+ name: import_node_path52.default.basename(absPath),
21991
22108
  path: absPath,
21992
22109
  addedAt: now,
21993
22110
  lastOpenedAt: now
@@ -22016,24 +22133,24 @@ function touchProject(projectId) {
22016
22133
  }
22017
22134
  }
22018
22135
  function discoverProjects(rootDir, maxDepth = 2) {
22019
- const absRoot = import_node_path51.default.resolve(rootDir);
22020
- if (!(0, import_node_fs17.existsSync)(absRoot) || !(0, import_node_fs17.statSync)(absRoot).isDirectory()) {
22136
+ const absRoot = import_node_path52.default.resolve(rootDir);
22137
+ if (!(0, import_node_fs18.existsSync)(absRoot) || !(0, import_node_fs18.statSync)(absRoot).isDirectory()) {
22021
22138
  return [];
22022
22139
  }
22023
22140
  const results = [];
22024
22141
  function scan(dir, depth) {
22025
22142
  if (depth > maxDepth) return;
22026
- if ((0, import_node_fs17.existsSync)(import_node_path51.default.join(dir, ".agentv"))) {
22143
+ if ((0, import_node_fs18.existsSync)(import_node_path52.default.join(dir, ".agentv"))) {
22027
22144
  results.push(dir);
22028
22145
  return;
22029
22146
  }
22030
22147
  if (depth === maxDepth) return;
22031
22148
  try {
22032
- const entries = (0, import_node_fs17.readdirSync)(dir, { withFileTypes: true });
22149
+ const entries = (0, import_node_fs18.readdirSync)(dir, { withFileTypes: true });
22033
22150
  for (const entry of entries) {
22034
22151
  if (!entry.isDirectory()) continue;
22035
22152
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
22036
- scan(import_node_path51.default.join(dir, entry.name), depth + 1);
22153
+ scan(import_node_path52.default.join(dir, entry.name), depth + 1);
22037
22154
  }
22038
22155
  } catch {
22039
22156
  }
@@ -22959,33 +23076,33 @@ function extractResponseItemContent(content) {
22959
23076
 
22960
23077
  // src/import/codex-session-discovery.ts
22961
23078
  init_cjs_shims();
22962
- var import_promises36 = require("fs/promises");
23079
+ var import_promises37 = require("fs/promises");
22963
23080
  var import_node_os8 = require("os");
22964
- var import_node_path53 = __toESM(require("path"), 1);
22965
- var DEFAULT_SESSIONS_DIR = () => import_node_path53.default.join((0, import_node_os8.homedir)(), ".codex", "sessions");
23081
+ var import_node_path54 = __toESM(require("path"), 1);
23082
+ var DEFAULT_SESSIONS_DIR = () => import_node_path54.default.join((0, import_node_os8.homedir)(), ".codex", "sessions");
22966
23083
  async function discoverCodexSessions(opts) {
22967
23084
  const sessionsDir = opts?.sessionsDir ?? DEFAULT_SESSIONS_DIR();
22968
23085
  const limit = opts?.latest ? 1 : opts?.limit ?? 10;
22969
23086
  const sessions = [];
22970
23087
  let yearDirs;
22971
23088
  try {
22972
- yearDirs = await (0, import_promises36.readdir)(sessionsDir);
23089
+ yearDirs = await (0, import_promises37.readdir)(sessionsDir);
22973
23090
  } catch {
22974
23091
  return [];
22975
23092
  }
22976
23093
  for (const year of yearDirs) {
22977
- const yearPath = import_node_path53.default.join(sessionsDir, year);
23094
+ const yearPath = import_node_path54.default.join(sessionsDir, year);
22978
23095
  let monthDirs;
22979
23096
  try {
22980
- monthDirs = await (0, import_promises36.readdir)(yearPath);
23097
+ monthDirs = await (0, import_promises37.readdir)(yearPath);
22981
23098
  } catch {
22982
23099
  continue;
22983
23100
  }
22984
23101
  for (const month of monthDirs) {
22985
- const monthPath = import_node_path53.default.join(yearPath, month);
23102
+ const monthPath = import_node_path54.default.join(yearPath, month);
22986
23103
  let dayDirs;
22987
23104
  try {
22988
- dayDirs = await (0, import_promises36.readdir)(monthPath);
23105
+ dayDirs = await (0, import_promises37.readdir)(monthPath);
22989
23106
  } catch {
22990
23107
  continue;
22991
23108
  }
@@ -22994,22 +23111,22 @@ async function discoverCodexSessions(opts) {
22994
23111
  const dirDate = `${year}-${month}-${day}`;
22995
23112
  if (dirDate !== opts.date) continue;
22996
23113
  }
22997
- const dayPath = import_node_path53.default.join(monthPath, day);
23114
+ const dayPath = import_node_path54.default.join(monthPath, day);
22998
23115
  let files;
22999
23116
  try {
23000
- files = await (0, import_promises36.readdir)(dayPath);
23117
+ files = await (0, import_promises37.readdir)(dayPath);
23001
23118
  } catch {
23002
23119
  continue;
23003
23120
  }
23004
23121
  for (const file of files) {
23005
23122
  if (!file.startsWith("rollout-") || !file.endsWith(".jsonl")) continue;
23006
- const filePath = import_node_path53.default.join(dayPath, file);
23123
+ const filePath = import_node_path54.default.join(dayPath, file);
23007
23124
  const nameWithoutExt = file.replace(/\.jsonl$/, "");
23008
23125
  const parts = nameWithoutExt.split("-");
23009
23126
  const sessionId = parts.length >= 6 ? parts.slice(-5).join("-") : nameWithoutExt;
23010
23127
  let updatedAt;
23011
23128
  try {
23012
- const fileStat = await (0, import_promises36.stat)(filePath);
23129
+ const fileStat = await (0, import_promises37.stat)(filePath);
23013
23130
  updatedAt = fileStat.mtime;
23014
23131
  } catch {
23015
23132
  updatedAt = /* @__PURE__ */ new Date(0);
@@ -23025,10 +23142,10 @@ async function discoverCodexSessions(opts) {
23025
23142
 
23026
23143
  // src/import/session-discovery.ts
23027
23144
  init_cjs_shims();
23028
- var import_promises37 = require("fs/promises");
23145
+ var import_promises38 = require("fs/promises");
23029
23146
  var import_node_os9 = require("os");
23030
- var import_node_path54 = __toESM(require("path"), 1);
23031
- var DEFAULT_PROJECTS_DIR = () => import_node_path54.default.join((0, import_node_os9.homedir)(), ".claude", "projects");
23147
+ var import_node_path55 = __toESM(require("path"), 1);
23148
+ var DEFAULT_PROJECTS_DIR = () => import_node_path55.default.join((0, import_node_os9.homedir)(), ".claude", "projects");
23032
23149
  function encodeProjectPath(projectPath) {
23033
23150
  return projectPath.replace(/\//g, "-");
23034
23151
  }
@@ -23037,7 +23154,7 @@ async function discoverClaudeSessions(opts) {
23037
23154
  const limit = opts?.latest ? 1 : opts?.limit ?? 10;
23038
23155
  let projectDirs;
23039
23156
  try {
23040
- projectDirs = await (0, import_promises37.readdir)(projectsDir);
23157
+ projectDirs = await (0, import_promises38.readdir)(projectsDir);
23041
23158
  } catch {
23042
23159
  return [];
23043
23160
  }
@@ -23047,10 +23164,10 @@ async function discoverClaudeSessions(opts) {
23047
23164
  }
23048
23165
  const sessions = [];
23049
23166
  for (const projectDir of projectDirs) {
23050
- const dirPath = import_node_path54.default.join(projectsDir, projectDir);
23167
+ const dirPath = import_node_path55.default.join(projectsDir, projectDir);
23051
23168
  let entries;
23052
23169
  try {
23053
- entries = await (0, import_promises37.readdir)(dirPath);
23170
+ entries = await (0, import_promises38.readdir)(dirPath);
23054
23171
  } catch {
23055
23172
  continue;
23056
23173
  }
@@ -23058,10 +23175,10 @@ async function discoverClaudeSessions(opts) {
23058
23175
  if (!entry.endsWith(".jsonl")) continue;
23059
23176
  const sessionId = entry.replace(/\.jsonl$/, "");
23060
23177
  if (opts?.sessionId && sessionId !== opts.sessionId) continue;
23061
- const filePath = import_node_path54.default.join(dirPath, entry);
23178
+ const filePath = import_node_path55.default.join(dirPath, entry);
23062
23179
  let updatedAt;
23063
23180
  try {
23064
- const fileStat = await (0, import_promises37.stat)(filePath);
23181
+ const fileStat = await (0, import_promises38.stat)(filePath);
23065
23182
  updatedAt = fileStat.mtime;
23066
23183
  } catch {
23067
23184
  updatedAt = /* @__PURE__ */ new Date(0);
@@ -23083,7 +23200,7 @@ init_cjs_shims();
23083
23200
 
23084
23201
  // src/import/types.ts
23085
23202
  init_cjs_shims();
23086
- var import_promises38 = require("fs/promises");
23203
+ var import_promises39 = require("fs/promises");
23087
23204
  function toTranscriptJsonLine(entry) {
23088
23205
  const firstUserMessage = entry.messages.find((m) => m.role === "user");
23089
23206
  const input = typeof firstUserMessage?.content === "string" ? firstUserMessage.content : "";
@@ -23109,11 +23226,11 @@ function toTranscriptJsonLine(entry) {
23109
23226
  };
23110
23227
  }
23111
23228
  async function readTranscriptJsonl(filePath) {
23112
- const text = await (0, import_promises38.readFile)(filePath, "utf8");
23229
+ const text = await (0, import_promises39.readFile)(filePath, "utf8");
23113
23230
  return text.split("\n").filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
23114
23231
  }
23115
23232
  async function readTranscriptFile(filePath) {
23116
- return (0, import_promises38.readFile)(filePath, "utf8");
23233
+ return (0, import_promises39.readFile)(filePath, "utf8");
23117
23234
  }
23118
23235
 
23119
23236
  // src/import/transcript-provider.ts
@@ -23328,6 +23445,7 @@ function createAgentKernel() {
23328
23445
  runRegexAssertion,
23329
23446
  runStartsWithAssertion,
23330
23447
  saveProjectRegistry,
23448
+ scanRepoDeps,
23331
23449
  scoreToVerdict,
23332
23450
  shouldEnableCache,
23333
23451
  shouldSkipCacheForTemperature,