@agentv/core 2.17.3 → 2.18.2

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.d.cts CHANGED
@@ -528,6 +528,8 @@ type WorkspaceHookConfig = {
528
528
  readonly reset?: 'none' | 'fast' | 'strict';
529
529
  };
530
530
  type WorkspaceHooksConfig = {
531
+ /** Whether hooks are enabled (default: true). When false, all hooks are skipped. */
532
+ readonly enabled?: boolean;
531
533
  /** Runs once before first test in the workspace lifecycle */
532
534
  readonly before_all?: WorkspaceHookConfig;
533
535
  /** Runs before each test case */
@@ -548,11 +550,9 @@ type WorkspaceConfig = {
548
550
  /** Workspace lifecycle hooks */
549
551
  readonly hooks?: WorkspaceHooksConfig;
550
552
  /** Workspace materialization mode */
551
- readonly mode?: 'pooled' | 'ephemeral' | 'static';
553
+ readonly mode?: 'pooled' | 'temp' | 'static';
552
554
  /** Required when mode=static: use this existing directory directly */
553
- readonly static_path?: string;
554
- /** @deprecated Use mode=pooled|ephemeral|static */
555
- readonly pool?: boolean;
555
+ readonly path?: string;
556
556
  };
557
557
  type CodeEvaluatorConfig = {
558
558
  readonly name: string;
@@ -2479,7 +2479,7 @@ interface RunEvaluationOptions {
2479
2479
  /** Pre-existing workspace directory to use directly (skips clone/copy/pool) */
2480
2480
  readonly workspace?: string;
2481
2481
  /** Workspace materialization mode override */
2482
- readonly workspaceMode?: 'pooled' | 'ephemeral' | 'static';
2482
+ readonly workspaceMode?: 'pooled' | 'temp' | 'static';
2483
2483
  /** Static workspace path override (used when workspaceMode=static) */
2484
2484
  readonly workspacePath?: string;
2485
2485
  /** Workspace clean policy override for pooled reset */
@@ -2601,7 +2601,7 @@ interface EvalConfig {
2601
2601
  readonly workers?: number;
2602
2602
  /** Maximum retries on failure (default: 2) */
2603
2603
  readonly maxRetries?: number;
2604
- /** Agent timeout in milliseconds (default: 120000) */
2604
+ /** Agent timeout in milliseconds. No timeout if not set. */
2605
2605
  readonly agentTimeoutMs?: number;
2606
2606
  /** Enable response caching */
2607
2607
  readonly cache?: boolean;
@@ -2708,7 +2708,7 @@ declare const AgentVConfigSchema: z.ZodObject<{
2708
2708
  workers: z.ZodOptional<z.ZodNumber>;
2709
2709
  /** Maximum retries on failure (default: 2) */
2710
2710
  maxRetries: z.ZodOptional<z.ZodNumber>;
2711
- /** Agent timeout in milliseconds (default: 120000) */
2711
+ /** Agent timeout in milliseconds. No timeout if not set. */
2712
2712
  agentTimeoutMs: z.ZodOptional<z.ZodNumber>;
2713
2713
  /** Enable verbose logging */
2714
2714
  verbose: z.ZodOptional<z.ZodBoolean>;
package/dist/index.d.ts CHANGED
@@ -528,6 +528,8 @@ type WorkspaceHookConfig = {
528
528
  readonly reset?: 'none' | 'fast' | 'strict';
529
529
  };
530
530
  type WorkspaceHooksConfig = {
531
+ /** Whether hooks are enabled (default: true). When false, all hooks are skipped. */
532
+ readonly enabled?: boolean;
531
533
  /** Runs once before first test in the workspace lifecycle */
532
534
  readonly before_all?: WorkspaceHookConfig;
533
535
  /** Runs before each test case */
@@ -548,11 +550,9 @@ type WorkspaceConfig = {
548
550
  /** Workspace lifecycle hooks */
549
551
  readonly hooks?: WorkspaceHooksConfig;
550
552
  /** Workspace materialization mode */
551
- readonly mode?: 'pooled' | 'ephemeral' | 'static';
553
+ readonly mode?: 'pooled' | 'temp' | 'static';
552
554
  /** Required when mode=static: use this existing directory directly */
553
- readonly static_path?: string;
554
- /** @deprecated Use mode=pooled|ephemeral|static */
555
- readonly pool?: boolean;
555
+ readonly path?: string;
556
556
  };
557
557
  type CodeEvaluatorConfig = {
558
558
  readonly name: string;
@@ -2479,7 +2479,7 @@ interface RunEvaluationOptions {
2479
2479
  /** Pre-existing workspace directory to use directly (skips clone/copy/pool) */
2480
2480
  readonly workspace?: string;
2481
2481
  /** Workspace materialization mode override */
2482
- readonly workspaceMode?: 'pooled' | 'ephemeral' | 'static';
2482
+ readonly workspaceMode?: 'pooled' | 'temp' | 'static';
2483
2483
  /** Static workspace path override (used when workspaceMode=static) */
2484
2484
  readonly workspacePath?: string;
2485
2485
  /** Workspace clean policy override for pooled reset */
@@ -2601,7 +2601,7 @@ interface EvalConfig {
2601
2601
  readonly workers?: number;
2602
2602
  /** Maximum retries on failure (default: 2) */
2603
2603
  readonly maxRetries?: number;
2604
- /** Agent timeout in milliseconds (default: 120000) */
2604
+ /** Agent timeout in milliseconds. No timeout if not set. */
2605
2605
  readonly agentTimeoutMs?: number;
2606
2606
  /** Enable response caching */
2607
2607
  readonly cache?: boolean;
@@ -2708,7 +2708,7 @@ declare const AgentVConfigSchema: z.ZodObject<{
2708
2708
  workers: z.ZodOptional<z.ZodNumber>;
2709
2709
  /** Maximum retries on failure (default: 2) */
2710
2710
  maxRetries: z.ZodOptional<z.ZodNumber>;
2711
- /** Agent timeout in milliseconds (default: 120000) */
2711
+ /** Agent timeout in milliseconds. No timeout if not set. */
2712
2712
  agentTimeoutMs: z.ZodOptional<z.ZodNumber>;
2713
2713
  /** Enable verbose logging */
2714
2714
  verbose: z.ZodOptional<z.ZodBoolean>;
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  readTextFile,
18
18
  resolveFileReference,
19
19
  resolveTargetDefinition
20
- } from "./chunk-PSYFRPNT.js";
20
+ } from "./chunk-V42NUK73.js";
21
21
  import {
22
22
  OtlpJsonFileExporter
23
23
  } from "./chunk-HFSYZHGF.js";
@@ -3152,11 +3152,13 @@ function parseWorkspaceHookConfig(raw, evalFileDir) {
3152
3152
  function parseWorkspaceHooksConfig(raw, evalFileDir) {
3153
3153
  if (!isJsonObject(raw)) return void 0;
3154
3154
  const obj = raw;
3155
+ const enabled = typeof obj.enabled === "boolean" ? obj.enabled : void 0;
3155
3156
  const beforeAll = parseWorkspaceHookConfig(obj.before_all, evalFileDir);
3156
3157
  const beforeEach = parseWorkspaceHookConfig(obj.before_each, evalFileDir);
3157
3158
  const afterEach = parseWorkspaceHookConfig(obj.after_each, evalFileDir);
3158
3159
  const afterAll = parseWorkspaceHookConfig(obj.after_all, evalFileDir);
3159
3160
  const hooks = {
3161
+ ...enabled !== void 0 && { enabled },
3160
3162
  ...beforeAll !== void 0 && { before_all: beforeAll },
3161
3163
  ...beforeEach !== void 0 && { before_each: beforeEach },
3162
3164
  ...afterEach !== void 0 && { after_each: afterEach },
@@ -3187,6 +3189,17 @@ async function resolveWorkspaceConfig(raw, evalFileDir) {
3187
3189
  function parseWorkspaceConfig(raw, evalFileDir) {
3188
3190
  if (!isJsonObject(raw)) return void 0;
3189
3191
  const obj = raw;
3192
+ if ("static_path" in obj) {
3193
+ throw new Error(
3194
+ "workspace.static_path has been removed. Use workspace.path with workspace.mode=static."
3195
+ );
3196
+ }
3197
+ if ("pool" in obj) {
3198
+ throw new Error("workspace.pool has been removed. Use workspace.mode='pooled' or 'temp'.");
3199
+ }
3200
+ if ("static" in obj) {
3201
+ throw new Error("workspace.static has been removed. Use workspace.mode='static'.");
3202
+ }
3190
3203
  let template = typeof obj.template === "string" ? obj.template : void 0;
3191
3204
  if (template && !path8.isAbsolute(template)) {
3192
3205
  template = path8.resolve(evalFileDir, template);
@@ -3194,19 +3207,17 @@ function parseWorkspaceConfig(raw, evalFileDir) {
3194
3207
  const isolation = obj.isolation === "shared" || obj.isolation === "per_test" ? obj.isolation : void 0;
3195
3208
  const repos = Array.isArray(obj.repos) ? obj.repos.map(parseRepoConfig).filter(Boolean) : void 0;
3196
3209
  const hooks = parseWorkspaceHooksConfig(obj.hooks, evalFileDir);
3197
- const mode = obj.mode === "pooled" || obj.mode === "ephemeral" || obj.mode === "static" ? obj.mode : void 0;
3198
- const staticPath = typeof obj.static_path === "string" ? obj.static_path : void 0;
3199
- const pool = typeof obj.pool === "boolean" ? obj.pool : void 0;
3200
- if (!template && !isolation && !repos && !hooks && !mode && !staticPath && pool === void 0)
3201
- return void 0;
3210
+ const explicitMode = obj.mode === "pooled" || obj.mode === "temp" || obj.mode === "static" ? obj.mode : void 0;
3211
+ const workspacePath = typeof obj.path === "string" ? obj.path : void 0;
3212
+ const mode = explicitMode ?? (workspacePath ? "static" : void 0);
3213
+ if (!template && !isolation && !repos && !hooks && !mode && !workspacePath) return void 0;
3202
3214
  return {
3203
3215
  ...template !== void 0 && { template },
3204
3216
  ...isolation !== void 0 && { isolation },
3205
3217
  ...repos !== void 0 && { repos },
3206
3218
  ...hooks !== void 0 && { hooks },
3207
3219
  ...mode !== void 0 && { mode },
3208
- ...staticPath !== void 0 && { static_path: staticPath },
3209
- ...pool !== void 0 && { pool }
3220
+ ...workspacePath !== void 0 && { path: workspacePath }
3210
3221
  };
3211
3222
  }
3212
3223
  function mergeWorkspaceConfigs(suiteLevel, caseLevel) {
@@ -3220,21 +3231,22 @@ function mergeWorkspaceConfigs(suiteLevel, caseLevel) {
3220
3231
  ...caseHook ?? {}
3221
3232
  };
3222
3233
  };
3234
+ const mergedEnabled = caseLevel.hooks?.enabled ?? suiteLevel.hooks?.enabled;
3223
3235
  const mergedHooks = {
3236
+ ...mergedEnabled !== void 0 && { enabled: mergedEnabled },
3224
3237
  before_all: mergeHook(suiteLevel.hooks?.before_all, caseLevel.hooks?.before_all),
3225
3238
  before_each: mergeHook(suiteLevel.hooks?.before_each, caseLevel.hooks?.before_each),
3226
3239
  after_each: mergeHook(suiteLevel.hooks?.after_each, caseLevel.hooks?.after_each),
3227
3240
  after_all: mergeHook(suiteLevel.hooks?.after_all, caseLevel.hooks?.after_all)
3228
3241
  };
3229
- const hasHooks = Object.values(mergedHooks).some((hook) => hook !== void 0);
3242
+ const hasHooks = mergedEnabled !== void 0 || Object.values(mergedHooks).some((hook) => hook !== void 0 && typeof hook === "object");
3230
3243
  return {
3231
3244
  template: caseLevel.template ?? suiteLevel.template,
3232
3245
  isolation: caseLevel.isolation ?? suiteLevel.isolation,
3233
3246
  repos: caseLevel.repos ?? suiteLevel.repos,
3234
3247
  ...hasHooks && { hooks: mergedHooks },
3235
3248
  mode: caseLevel.mode ?? suiteLevel.mode,
3236
- static_path: caseLevel.static_path ?? suiteLevel.static_path,
3237
- pool: caseLevel.pool ?? suiteLevel.pool
3249
+ path: caseLevel.path ?? suiteLevel.path
3238
3250
  };
3239
3251
  }
3240
3252
  function asString6(value) {
@@ -6173,14 +6185,18 @@ var PiAgentSdkProvider = class {
6173
6185
  }
6174
6186
  });
6175
6187
  try {
6176
- const timeoutMs = this.config.timeoutMs ?? 12e4;
6177
- const timeoutPromise = new Promise((_, reject) => {
6178
- setTimeout(
6179
- () => reject(new Error(`Pi agent SDK timed out after ${timeoutMs}ms`)),
6180
- timeoutMs
6181
- );
6182
- });
6183
- await Promise.race([agent.prompt(request.question), timeoutPromise]);
6188
+ if (this.config.timeoutMs) {
6189
+ const timeoutMs = this.config.timeoutMs;
6190
+ const timeoutPromise = new Promise((_, reject) => {
6191
+ setTimeout(
6192
+ () => reject(new Error(`Pi agent SDK timed out after ${timeoutMs}ms`)),
6193
+ timeoutMs
6194
+ );
6195
+ });
6196
+ await Promise.race([agent.prompt(request.question), timeoutPromise]);
6197
+ } else {
6198
+ await agent.prompt(request.question);
6199
+ }
6184
6200
  await agent.waitForIdle();
6185
6201
  const agentMessages = agent.state.messages;
6186
6202
  for (const msg of agentMessages) {
@@ -12020,7 +12036,7 @@ function runEqualsAssertion(output, value) {
12020
12036
 
12021
12037
  // src/evaluation/orchestrator.ts
12022
12038
  import { createHash as createHash2, randomUUID as randomUUID7 } from "node:crypto";
12023
- import { mkdir as mkdir12, stat as stat7 } from "node:fs/promises";
12039
+ import { mkdir as mkdir12, readdir as readdir6, stat as stat7 } from "node:fs/promises";
12024
12040
  import path39 from "node:path";
12025
12041
  import micromatch4 from "micromatch";
12026
12042
 
@@ -13420,6 +13436,9 @@ function toScriptConfig(hook, hookName, context) {
13420
13436
  function hasHookCommand(hook) {
13421
13437
  return !!(hook?.command && hook.command.length > 0 || hook?.script && hook.script.length > 0);
13422
13438
  }
13439
+ function hooksEnabled(workspace) {
13440
+ return workspace?.hooks?.enabled !== false;
13441
+ }
13423
13442
  function getWorkspaceTemplate(target) {
13424
13443
  const config = target.config;
13425
13444
  if ("workspaceTemplate" in config && typeof config.workspaceTemplate === "string") {
@@ -13594,19 +13613,27 @@ async function runEvaluation(options) {
13594
13613
  }
13595
13614
  };
13596
13615
  const isPerTestIsolation = suiteWorkspace?.isolation === "per_test";
13597
- const configuredMode = suiteWorkspace?.mode ?? workspaceMode;
13598
- const configuredStaticPath = suiteWorkspace?.static_path ?? workspacePath ?? legacyWorkspacePath;
13599
- const useStaticWorkspace = configuredMode === "static" || !!configuredStaticPath && !configuredMode;
13616
+ const cliWorkspacePath = workspacePath ?? legacyWorkspacePath;
13617
+ const yamlWorkspacePath = suiteWorkspace?.path;
13618
+ if (cliWorkspacePath && workspaceMode && workspaceMode !== "static") {
13619
+ throw new Error("--workspace-path requires --workspace-mode static when both are provided");
13620
+ }
13621
+ const configuredMode = cliWorkspacePath ? "static" : workspaceMode ?? suiteWorkspace?.mode ?? (yamlWorkspacePath ? "static" : "pooled");
13622
+ const configuredStaticPath = cliWorkspacePath ?? yamlWorkspacePath;
13623
+ const useStaticWorkspace = configuredMode === "static";
13600
13624
  if (useStaticWorkspace && isPerTestIsolation) {
13601
13625
  throw new Error(
13602
13626
  "static workspace mode is incompatible with isolation: per_test. Use isolation: shared (default)."
13603
13627
  );
13604
13628
  }
13605
13629
  if (configuredMode === "static" && !configuredStaticPath) {
13606
- throw new Error("workspace.mode=static requires workspace.static_path or --workspace-path");
13630
+ throw new Error("workspace.mode=static requires workspace.path or --workspace-path");
13631
+ }
13632
+ if (configuredMode !== "static" && configuredStaticPath) {
13633
+ throw new Error("workspace.path requires workspace.mode=static");
13607
13634
  }
13608
13635
  const hasSharedWorkspace = !!(useStaticWorkspace || workspaceTemplate || suiteWorkspace?.hooks || suiteWorkspace?.repos?.length && !isPerTestIsolation);
13609
- const poolEnabled = configuredMode === "pooled" ? true : configuredMode === "ephemeral" || useStaticWorkspace ? false : suiteWorkspace?.pool ?? poolWorkspaces ?? true;
13636
+ const poolEnabled = configuredMode === "pooled";
13610
13637
  const usePool = poolEnabled !== false && !!suiteWorkspace?.repos?.length && !isPerTestIsolation && !useStaticWorkspace;
13611
13638
  const resolvedRetainOnSuccess = retainOnSuccess ?? (keepWorkspaces ? "keep" : "cleanup");
13612
13639
  const resolvedRetainOnFailure = retainOnFailure ?? (cleanupWorkspaces ? "cleanup" : "keep");
@@ -13630,9 +13657,28 @@ async function runEvaluation(options) {
13630
13657
  const availablePoolSlots = [];
13631
13658
  const poolSlotBaselines = /* @__PURE__ */ new Map();
13632
13659
  const poolMaxSlots = Math.min(configPoolMaxSlots ?? 10, 50);
13660
+ let staticMaterialised = false;
13633
13661
  if (useStaticWorkspace && configuredStaticPath) {
13662
+ const isYamlConfiguredPath = !cliWorkspacePath && !!yamlWorkspacePath;
13663
+ const dirExists = await stat7(configuredStaticPath).then(
13664
+ (s) => s.isDirectory(),
13665
+ () => false
13666
+ );
13667
+ const isEmpty = dirExists ? (await readdir6(configuredStaticPath)).length === 0 : false;
13668
+ if (isYamlConfiguredPath && (!dirExists || isEmpty)) {
13669
+ if (!dirExists) {
13670
+ await mkdir12(configuredStaticPath, { recursive: true });
13671
+ }
13672
+ if (workspaceTemplate) {
13673
+ await copyDirectoryRecursive(workspaceTemplate, configuredStaticPath);
13674
+ setupLog(`copied template into static workspace: ${configuredStaticPath}`);
13675
+ }
13676
+ staticMaterialised = true;
13677
+ setupLog(`materialised static workspace at: ${configuredStaticPath}`);
13678
+ } else {
13679
+ setupLog(`reusing existing static workspace: ${configuredStaticPath}`);
13680
+ }
13634
13681
  sharedWorkspacePath = configuredStaticPath;
13635
- setupLog(`using static workspace: ${configuredStaticPath}`);
13636
13682
  } else if (usePool && suiteWorkspace?.repos) {
13637
13683
  const slotsNeeded = workers;
13638
13684
  setupLog(`acquiring ${slotsNeeded} workspace pool slot(s) (pool capacity: ${poolMaxSlots})`);
@@ -13678,7 +13724,8 @@ async function runEvaluation(options) {
13678
13724
  } catch {
13679
13725
  }
13680
13726
  }
13681
- const repoManager = suiteWorkspace?.repos?.length && !usePool && !useStaticWorkspace ? new RepoManager(verbose) : void 0;
13727
+ const needsRepoMaterialisation = !!suiteWorkspace?.repos?.length && !usePool && (!useStaticWorkspace || staticMaterialised);
13728
+ const repoManager = needsRepoMaterialisation ? new RepoManager(verbose) : void 0;
13682
13729
  if (repoManager && sharedWorkspacePath && suiteWorkspace?.repos && !isPerTestIsolation) {
13683
13730
  setupLog(
13684
13731
  `materializing ${suiteWorkspace.repos.length} shared repo(s) into ${sharedWorkspacePath}`
@@ -13695,8 +13742,9 @@ async function runEvaluation(options) {
13695
13742
  throw new Error(`Failed to materialize repos: ${message}`);
13696
13743
  }
13697
13744
  }
13745
+ const suiteHooksEnabled = hooksEnabled(suiteWorkspace);
13698
13746
  const suiteBeforeAllHook = suiteWorkspace?.hooks?.before_all;
13699
- if (sharedWorkspacePath && hasHookCommand(suiteBeforeAllHook)) {
13747
+ if (sharedWorkspacePath && suiteHooksEnabled && hasHookCommand(suiteBeforeAllHook)) {
13700
13748
  const beforeAllHook = suiteBeforeAllHook;
13701
13749
  const beforeAllCommand = (beforeAllHook.command ?? beforeAllHook.script ?? []).join(" ");
13702
13750
  setupLog(
@@ -13723,7 +13771,7 @@ async function runEvaluation(options) {
13723
13771
  throw new Error(`before_all script failed: ${message}`);
13724
13772
  }
13725
13773
  }
13726
- if (availablePoolSlots.length > 0 && hasHookCommand(suiteBeforeAllHook)) {
13774
+ if (availablePoolSlots.length > 0 && suiteHooksEnabled && hasHookCommand(suiteBeforeAllHook)) {
13727
13775
  const beforeAllHook = suiteBeforeAllHook;
13728
13776
  for (const slot of availablePoolSlots) {
13729
13777
  setupLog(`running before_all on pool slot ${slot.index}`);
@@ -13965,7 +14013,7 @@ async function runEvaluation(options) {
13965
14013
  }
13966
14014
  const afterAllWorkspaces = poolSlots.length > 1 ? poolSlots.map((s) => s.path) : sharedWorkspacePath ? [sharedWorkspacePath] : [];
13967
14015
  const suiteAfterAllHook = suiteWorkspace?.hooks?.after_all;
13968
- if (afterAllWorkspaces.length > 0 && hasHookCommand(suiteAfterAllHook)) {
14016
+ if (afterAllWorkspaces.length > 0 && suiteHooksEnabled && hasHookCommand(suiteAfterAllHook)) {
13969
14017
  const afterAllHook = suiteAfterAllHook;
13970
14018
  for (const wsPath of afterAllWorkspaces) {
13971
14019
  const scriptContext = {
@@ -14213,6 +14261,7 @@ async function runEvalCase(options) {
14213
14261
  let afterEachOutput;
14214
14262
  const isSharedWorkspace = !!sharedWorkspacePath;
14215
14263
  let caseWorkspaceFile;
14264
+ const caseHooksEnabled = hooksEnabled(evalCase.workspace);
14216
14265
  if (!workspacePath) {
14217
14266
  const rawCaseTemplate = evalCase.workspace?.template ?? getWorkspaceTemplate(target);
14218
14267
  const resolvedCaseTemplate = await resolveWorkspaceTemplate(rawCaseTemplate);
@@ -14274,7 +14323,7 @@ async function runEvalCase(options) {
14274
14323
  }
14275
14324
  }
14276
14325
  const caseBeforeAllHook = evalCase.workspace?.hooks?.before_all;
14277
- if (workspacePath && hasHookCommand(caseBeforeAllHook)) {
14326
+ if (workspacePath && caseHooksEnabled && hasHookCommand(caseBeforeAllHook)) {
14278
14327
  const beforeAllHook = caseBeforeAllHook;
14279
14328
  const beforeAllCommand = (beforeAllHook.command ?? beforeAllHook.script ?? []).join(" ");
14280
14329
  if (setupDebug) {
@@ -14318,7 +14367,7 @@ async function runEvalCase(options) {
14318
14367
  }
14319
14368
  }
14320
14369
  const caseBeforeEachHook = evalCase.workspace?.hooks?.before_each;
14321
- if (workspacePath && hasHookCommand(caseBeforeEachHook)) {
14370
+ if (workspacePath && caseHooksEnabled && hasHookCommand(caseBeforeEachHook)) {
14322
14371
  const beforeEachHook = caseBeforeEachHook;
14323
14372
  const scriptContext = {
14324
14373
  workspacePath,
@@ -14447,7 +14496,7 @@ async function runEvalCase(options) {
14447
14496
  }
14448
14497
  }
14449
14498
  const providerError = extractProviderError(providerResponse);
14450
- if (repoManager && workspacePath && evalCase.workspace?.hooks?.after_each?.reset && evalCase.workspace.hooks.after_each.reset !== "none" && evalCase.workspace.repos) {
14499
+ if (caseHooksEnabled && repoManager && workspacePath && evalCase.workspace?.hooks?.after_each?.reset && evalCase.workspace.hooks.after_each.reset !== "none" && evalCase.workspace.repos) {
14451
14500
  try {
14452
14501
  await repoManager.reset(
14453
14502
  evalCase.workspace.repos,
@@ -14458,7 +14507,7 @@ async function runEvalCase(options) {
14458
14507
  }
14459
14508
  }
14460
14509
  const caseAfterEachHook = evalCase.workspace?.hooks?.after_each;
14461
- if (workspacePath && hasHookCommand(caseAfterEachHook)) {
14510
+ if (workspacePath && caseHooksEnabled && hasHookCommand(caseAfterEachHook)) {
14462
14511
  const afterEachHook = caseAfterEachHook;
14463
14512
  const scriptContext = {
14464
14513
  workspacePath,
@@ -15237,7 +15286,7 @@ async function evaluate(config) {
15237
15286
  repoRoot,
15238
15287
  target: resolvedTarget,
15239
15288
  maxRetries: config.maxRetries ?? 2,
15240
- agentTimeoutMs: config.agentTimeoutMs ?? 12e4,
15289
+ agentTimeoutMs: config.agentTimeoutMs,
15241
15290
  verbose: config.verbose,
15242
15291
  maxConcurrency: config.workers ?? 3,
15243
15292
  filter: config.filter,
@@ -15340,7 +15389,7 @@ var AgentVConfigSchema = z5.object({
15340
15389
  workers: z5.number().int().min(1).max(50).optional(),
15341
15390
  /** Maximum retries on failure (default: 2) */
15342
15391
  maxRetries: z5.number().int().min(0).optional(),
15343
- /** Agent timeout in milliseconds (default: 120000) */
15392
+ /** Agent timeout in milliseconds. No timeout if not set. */
15344
15393
  agentTimeoutMs: z5.number().int().min(0).optional(),
15345
15394
  /** Enable verbose logging */
15346
15395
  verbose: z5.boolean().optional(),