@agentv/core 0.7.5 → 0.10.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.
@@ -44,7 +44,7 @@ module.exports = __toCommonJS(validation_exports);
44
44
  var import_promises = require("fs/promises");
45
45
  var import_yaml = require("yaml");
46
46
  var SCHEMA_EVAL_V2 = "agentv-eval-v2";
47
- var SCHEMA_TARGETS_V2 = "agentv-targets-v2.1";
47
+ var SCHEMA_TARGETS_V2 = "agentv-targets-v2.2";
48
48
  var SCHEMA_CONFIG_V2 = "agentv-config-v2";
49
49
  async function detectFileType(filePath) {
50
50
  try {
@@ -196,14 +196,14 @@ async function validateEvalFile(filePath) {
196
196
  validateMessages(inputMessages, `${location}.input_messages`, absolutePath, errors);
197
197
  }
198
198
  const expectedMessages = evalCase["expected_messages"];
199
- if (!Array.isArray(expectedMessages)) {
199
+ if (expectedMessages !== void 0 && !Array.isArray(expectedMessages)) {
200
200
  errors.push({
201
201
  severity: "error",
202
202
  filePath: absolutePath,
203
203
  location: `${location}.expected_messages`,
204
- message: "Missing or invalid 'expected_messages' field (must be an array)"
204
+ message: "Invalid 'expected_messages' field (must be an array if provided)"
205
205
  });
206
- } else {
206
+ } else if (Array.isArray(expectedMessages)) {
207
207
  validateMessages(expectedMessages, `${location}.expected_messages`, absolutePath, errors);
208
208
  }
209
209
  }
@@ -239,11 +239,13 @@ function validateMessages(messages, location, filePath, errors) {
239
239
  }
240
240
  const content = message["content"];
241
241
  if (typeof content === "string") {
242
+ validateContentForRoleMarkers(content, `${msgLocation}.content`, filePath, errors);
242
243
  } else if (Array.isArray(content)) {
243
244
  for (let j = 0; j < content.length; j++) {
244
245
  const contentItem = content[j];
245
246
  const contentLocation = `${msgLocation}.content[${j}]`;
246
247
  if (typeof contentItem === "string") {
248
+ validateContentForRoleMarkers(contentItem, contentLocation, filePath, errors);
247
249
  } else if (isObject(contentItem)) {
248
250
  const type = contentItem["type"];
249
251
  if (typeof type !== "string") {
@@ -263,6 +265,8 @@ function validateMessages(messages, location, filePath, errors) {
263
265
  location: `${contentLocation}.value`,
264
266
  message: "Content with type 'text' must have a 'value' field"
265
267
  });
268
+ } else {
269
+ validateContentForRoleMarkers(value, `${contentLocation}.value`, filePath, errors);
266
270
  }
267
271
  }
268
272
  } else {
@@ -284,12 +288,35 @@ function validateMessages(messages, location, filePath, errors) {
284
288
  }
285
289
  }
286
290
  }
291
+ function validateContentForRoleMarkers(content, location, filePath, errors) {
292
+ const markers = ["@[System]:", "@[User]:", "@[Assistant]:", "@[Tool]:"];
293
+ for (const marker of markers) {
294
+ if (content.toLowerCase().includes(marker.toLowerCase())) {
295
+ errors.push({
296
+ severity: "warning",
297
+ filePath,
298
+ location,
299
+ message: `Content contains potential role marker '${marker}'. This may confuse agentic providers or cause prompt injection.`
300
+ });
301
+ }
302
+ }
303
+ }
287
304
 
288
305
  // src/evaluation/validation/targets-validator.ts
289
306
  var import_promises3 = require("fs/promises");
290
307
  var import_node_path2 = __toESM(require("path"), 1);
291
308
  var import_yaml3 = require("yaml");
292
309
 
310
+ // src/evaluation/providers/targets.ts
311
+ var import_zod = require("zod");
312
+ var CLI_PLACEHOLDERS = /* @__PURE__ */ new Set(["PROMPT", "GUIDELINES", "EVAL_ID", "ATTEMPT", "FILES", "OUTPUT_FILE"]);
313
+ var BASE_TARGET_SCHEMA = import_zod.z.object({
314
+ name: import_zod.z.string().min(1, "target name is required"),
315
+ provider: import_zod.z.string().min(1, "provider is required"),
316
+ judge_target: import_zod.z.string().optional(),
317
+ workers: import_zod.z.number().int().min(1).optional()
318
+ }).passthrough();
319
+
293
320
  // src/evaluation/providers/types.ts
294
321
  var KNOWN_PROVIDERS = [
295
322
  "azure",
@@ -317,18 +344,7 @@ var PROVIDER_ALIASES = [
317
344
  "vertex"
318
345
  // legacy/future support
319
346
  ];
320
- var TARGETS_SCHEMA_V2 = "agentv-targets-v2.1";
321
-
322
- // src/evaluation/providers/targets.ts
323
- var import_zod = require("zod");
324
- var CLI_PLACEHOLDERS = /* @__PURE__ */ new Set(["PROMPT", "GUIDELINES", "EVAL_ID", "ATTEMPT", "FILES", "OUTPUT_FILE"]);
325
- var BASE_TARGET_SCHEMA = import_zod.z.object({
326
- name: import_zod.z.string().min(1, "target name is required"),
327
- provider: import_zod.z.string().min(1, "provider is required"),
328
- settings: import_zod.z.record(import_zod.z.unknown()).optional(),
329
- judge_target: import_zod.z.string().optional(),
330
- workers: import_zod.z.number().int().min(1).optional()
331
- });
347
+ var TARGETS_SCHEMA_V2 = "agentv-targets-v2.2";
332
348
 
333
349
  // src/evaluation/validation/targets-validator.ts
334
350
  function isObject2(value) {
@@ -338,8 +354,21 @@ var COMMON_SETTINGS = /* @__PURE__ */ new Set([
338
354
  "provider_batching",
339
355
  "providerBatching"
340
356
  ]);
357
+ var RETRY_SETTINGS = /* @__PURE__ */ new Set([
358
+ "max_retries",
359
+ "maxRetries",
360
+ "retry_initial_delay_ms",
361
+ "retryInitialDelayMs",
362
+ "retry_max_delay_ms",
363
+ "retryMaxDelayMs",
364
+ "retry_backoff_factor",
365
+ "retryBackoffFactor",
366
+ "retry_status_codes",
367
+ "retryStatusCodes"
368
+ ]);
341
369
  var AZURE_SETTINGS = /* @__PURE__ */ new Set([
342
370
  ...COMMON_SETTINGS,
371
+ ...RETRY_SETTINGS,
343
372
  "endpoint",
344
373
  "resource",
345
374
  "resourceName",
@@ -356,6 +385,7 @@ var AZURE_SETTINGS = /* @__PURE__ */ new Set([
356
385
  ]);
357
386
  var ANTHROPIC_SETTINGS = /* @__PURE__ */ new Set([
358
387
  ...COMMON_SETTINGS,
388
+ ...RETRY_SETTINGS,
359
389
  "api_key",
360
390
  "apiKey",
361
391
  "model",
@@ -369,6 +399,7 @@ var ANTHROPIC_SETTINGS = /* @__PURE__ */ new Set([
369
399
  ]);
370
400
  var GEMINI_SETTINGS = /* @__PURE__ */ new Set([
371
401
  ...COMMON_SETTINGS,
402
+ ...RETRY_SETTINGS,
372
403
  "api_key",
373
404
  "apiKey",
374
405
  "model",
@@ -456,13 +487,14 @@ function getKnownSettings(provider) {
456
487
  return null;
457
488
  }
458
489
  }
459
- function validateUnknownSettings(settings, provider, absolutePath, location, errors) {
490
+ function validateUnknownSettings(target, provider, absolutePath, location, errors) {
460
491
  const knownSettings = getKnownSettings(provider);
461
492
  if (!knownSettings) {
462
493
  return;
463
494
  }
464
- for (const key of Object.keys(settings)) {
465
- if (!knownSettings.has(key)) {
495
+ const baseFields = /* @__PURE__ */ new Set(["name", "provider", "judge_target", "workers", "$schema", "targets"]);
496
+ for (const key of Object.keys(target)) {
497
+ if (!baseFields.has(key) && !knownSettings.has(key)) {
466
498
  errors.push({
467
499
  severity: "warning",
468
500
  filePath: absolutePath,
@@ -492,17 +524,8 @@ async function validateTargetsFile(filePath) {
492
524
  errors
493
525
  };
494
526
  }
495
- function validateCliSettings(settings, absolutePath2, location, errors2) {
496
- if (!isObject2(settings)) {
497
- errors2.push({
498
- severity: "error",
499
- filePath: absolutePath2,
500
- location,
501
- message: "CLI provider requires a 'settings' object"
502
- });
503
- return;
504
- }
505
- const commandTemplate = settings["command_template"] ?? settings["commandTemplate"];
527
+ function validateCliSettings(target, absolutePath2, location, errors2) {
528
+ const commandTemplate = target["command_template"] ?? target["commandTemplate"];
506
529
  if (typeof commandTemplate !== "string" || commandTemplate.trim().length === 0) {
507
530
  errors2.push({
508
531
  severity: "error",
@@ -513,7 +536,7 @@ async function validateTargetsFile(filePath) {
513
536
  } else {
514
537
  recordUnknownPlaceholders(commandTemplate, absolutePath2, `${location}.commandTemplate`, errors2);
515
538
  }
516
- const attachmentsFormat = settings["attachments_format"] ?? settings["attachmentsFormat"];
539
+ const attachmentsFormat = target["attachments_format"] ?? target["attachmentsFormat"];
517
540
  if (attachmentsFormat !== void 0 && typeof attachmentsFormat !== "string") {
518
541
  errors2.push({
519
542
  severity: "error",
@@ -522,7 +545,7 @@ async function validateTargetsFile(filePath) {
522
545
  message: "'attachmentsFormat' must be a string when provided"
523
546
  });
524
547
  }
525
- const filesFormat = settings["files_format"] ?? settings["filesFormat"];
548
+ const filesFormat = target["files_format"] ?? target["filesFormat"];
526
549
  if (filesFormat !== void 0 && typeof filesFormat !== "string") {
527
550
  errors2.push({
528
551
  severity: "error",
@@ -531,7 +554,7 @@ async function validateTargetsFile(filePath) {
531
554
  message: "'filesFormat' must be a string when provided"
532
555
  });
533
556
  }
534
- const cwd = settings["cwd"];
557
+ const cwd = target["cwd"];
535
558
  if (cwd !== void 0 && typeof cwd !== "string") {
536
559
  errors2.push({
537
560
  severity: "error",
@@ -540,7 +563,7 @@ async function validateTargetsFile(filePath) {
540
563
  message: "'cwd' must be a string when provided"
541
564
  });
542
565
  }
543
- const timeoutSeconds = settings["timeout_seconds"] ?? settings["timeoutSeconds"];
566
+ const timeoutSeconds = target["timeout_seconds"] ?? target["timeoutSeconds"];
544
567
  if (timeoutSeconds !== void 0) {
545
568
  const numericTimeout = Number(timeoutSeconds);
546
569
  if (!Number.isFinite(numericTimeout) || numericTimeout <= 0) {
@@ -552,29 +575,7 @@ async function validateTargetsFile(filePath) {
552
575
  });
553
576
  }
554
577
  }
555
- const envOverrides = settings["env"];
556
- if (envOverrides !== void 0) {
557
- if (!isObject2(envOverrides)) {
558
- errors2.push({
559
- severity: "error",
560
- filePath: absolutePath2,
561
- location: `${location}.env`,
562
- message: "'env' must be an object with string values"
563
- });
564
- } else {
565
- for (const [key, value] of Object.entries(envOverrides)) {
566
- if (typeof value !== "string" || value.trim().length === 0) {
567
- errors2.push({
568
- severity: "error",
569
- filePath: absolutePath2,
570
- location: `${location}.env.${key}`,
571
- message: `Environment override '${key}' must be a non-empty string`
572
- });
573
- }
574
- }
575
- }
576
- }
577
- const healthcheck = settings["healthcheck"];
578
+ const healthcheck = target["healthcheck"];
578
579
  if (healthcheck !== void 0) {
579
580
  validateCliHealthcheck(healthcheck, absolutePath2, `${location}.healthcheck`, errors2);
580
581
  }
@@ -745,20 +746,11 @@ async function validateTargetsFile(filePath) {
745
746
  message: `Unknown provider '${provider}'. Known providers: ${knownProviders.join(", ")}`
746
747
  });
747
748
  }
748
- const settings = target["settings"];
749
- if (providerValue !== "cli" && settings !== void 0 && !isObject2(settings)) {
750
- errors.push({
751
- severity: "error",
752
- filePath: absolutePath,
753
- location: `${location}.settings`,
754
- message: "Invalid 'settings' field (must be an object)"
755
- });
756
- }
757
749
  if (providerValue === "cli") {
758
- validateCliSettings(settings, absolutePath, `${location}.settings`, errors);
750
+ validateCliSettings(target, absolutePath, location, errors);
759
751
  }
760
- if (settings !== void 0 && isObject2(settings) && typeof provider === "string") {
761
- validateUnknownSettings(settings, provider, absolutePath, `${location}.settings`, errors);
752
+ if (typeof provider === "string") {
753
+ validateUnknownSettings(target, provider, absolutePath, location, errors);
762
754
  }
763
755
  const judgeTarget = target["judge_target"];
764
756
  if (judgeTarget !== void 0 && typeof judgeTarget !== "string") {