@agentv/core 0.2.3 → 0.2.6

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.
@@ -78,9 +78,37 @@ async function resolveFileReference(rawValue, searchRoots) {
78
78
  return { displayPath, attempted };
79
79
  }
80
80
 
81
+ // src/evaluation/providers/types.ts
82
+ var KNOWN_PROVIDERS = [
83
+ "azure",
84
+ "anthropic",
85
+ "gemini",
86
+ "mock",
87
+ "vscode",
88
+ "vscode-insiders"
89
+ ];
90
+ var PROVIDER_ALIASES = [
91
+ "azure-openai",
92
+ // alias for "azure"
93
+ "google",
94
+ // alias for "gemini"
95
+ "google-gemini",
96
+ // alias for "gemini"
97
+ "openai",
98
+ // legacy/future support
99
+ "bedrock",
100
+ // legacy/future support
101
+ "vertex"
102
+ // legacy/future support
103
+ ];
104
+ var TARGETS_SCHEMA_V2 = "agentv-targets-v2";
105
+
81
106
  export {
82
107
  findGitRoot,
83
108
  buildSearchRoots,
84
- resolveFileReference
109
+ resolveFileReference,
110
+ KNOWN_PROVIDERS,
111
+ PROVIDER_ALIASES,
112
+ TARGETS_SCHEMA_V2
85
113
  };
86
- //# sourceMappingURL=chunk-5REK5RSI.js.map
114
+ //# sourceMappingURL=chunk-QVS4OL44.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/evaluation/file-utils.ts","../src/evaluation/providers/types.ts"],"sourcesContent":["import { constants } from \"node:fs\";\r\nimport { access } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\n\r\nexport async function fileExists(filePath: string): Promise<boolean> {\r\n try {\r\n await access(filePath, constants.F_OK);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Find git repository root by walking up the directory tree.\r\n */\r\nexport async function findGitRoot(startPath: string): Promise<string | null> {\r\n let currentDir = path.dirname(path.resolve(startPath));\r\n const root = path.parse(currentDir).root;\r\n\r\n while (currentDir !== root) {\r\n const gitPath = path.join(currentDir, \".git\");\r\n if (await fileExists(gitPath)) {\r\n return currentDir;\r\n }\r\n\r\n const parentDir = path.dirname(currentDir);\r\n if (parentDir === currentDir) {\r\n break;\r\n }\r\n currentDir = parentDir;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Build search roots for file resolution, matching yaml-parser behavior.\r\n * Searches from eval file directory up to repo root.\r\n */\r\nexport function buildSearchRoots(evalPath: string, repoRoot: string): readonly string[] {\r\n const uniqueRoots: string[] = [];\r\n const addRoot = (root: string): void => {\r\n const normalized = path.resolve(root);\r\n if (!uniqueRoots.includes(normalized)) {\r\n uniqueRoots.push(normalized);\r\n }\r\n };\r\n\r\n let currentDir = path.dirname(evalPath);\r\n let reachedBoundary = false;\r\n while (!reachedBoundary) {\r\n addRoot(currentDir);\r\n const parentDir = path.dirname(currentDir);\r\n if (currentDir === repoRoot || parentDir === currentDir) {\r\n reachedBoundary = true;\r\n } else {\r\n currentDir = parentDir;\r\n }\r\n }\r\n\r\n addRoot(repoRoot);\r\n addRoot(process.cwd());\r\n return uniqueRoots;\r\n}\r\n\r\n/**\r\n * Trim leading path separators for display.\r\n */\r\nfunction trimLeadingSeparators(value: string): string {\r\n const trimmed = value.replace(/^[/\\\\]+/, \"\");\r\n return trimmed.length > 0 ? trimmed : value;\r\n}\r\n\r\n/**\r\n * Resolve a file reference using search roots, matching yaml-parser behavior.\r\n */\r\nexport async function resolveFileReference(\r\n rawValue: string,\r\n searchRoots: readonly string[],\r\n): Promise<{\r\n readonly displayPath: string;\r\n readonly resolvedPath?: string;\r\n readonly attempted: readonly string[];\r\n}> {\r\n const displayPath = trimLeadingSeparators(rawValue);\r\n const potentialPaths: string[] = [];\r\n\r\n if (path.isAbsolute(rawValue)) {\r\n potentialPaths.push(path.normalize(rawValue));\r\n }\r\n\r\n for (const base of searchRoots) {\r\n potentialPaths.push(path.resolve(base, displayPath));\r\n }\r\n\r\n const attempted: string[] = [];\r\n const seen = new Set<string>();\r\n for (const candidate of potentialPaths) {\r\n const absoluteCandidate = path.resolve(candidate);\r\n if (seen.has(absoluteCandidate)) {\r\n continue;\r\n }\r\n seen.add(absoluteCandidate);\r\n attempted.push(absoluteCandidate);\r\n if (await fileExists(absoluteCandidate)) {\r\n return { displayPath, resolvedPath: absoluteCandidate, attempted };\r\n }\r\n }\r\n\r\n return { displayPath, attempted };\r\n}\r\n","import type { AxChatRequest } from \"@ax-llm/ax\";\r\n\r\nimport type { JsonObject } from \"../types.js\";\r\n\r\ntype ChatPrompt = AxChatRequest[\"chatPrompt\"];\r\n\r\nexport type ProviderKind =\r\n | \"azure\"\r\n | \"anthropic\"\r\n | \"gemini\"\r\n | \"mock\"\r\n | \"vscode\"\r\n | \"vscode-insiders\";\r\n\r\n/**\r\n * List of all supported provider kinds.\r\n * This is the source of truth for provider validation.\r\n */\r\nexport const KNOWN_PROVIDERS: readonly ProviderKind[] = [\r\n \"azure\",\r\n \"anthropic\",\r\n \"gemini\",\r\n \"mock\",\r\n \"vscode\",\r\n \"vscode-insiders\",\r\n] as const;\r\n\r\n/**\r\n * Provider aliases that are accepted in target definitions.\r\n * These map to the canonical ProviderKind values.\r\n */\r\nexport const PROVIDER_ALIASES: readonly string[] = [\r\n \"azure-openai\", // alias for \"azure\"\r\n \"google\", // alias for \"gemini\"\r\n \"google-gemini\", // alias for \"gemini\"\r\n \"openai\", // legacy/future support\r\n \"bedrock\", // legacy/future support\r\n \"vertex\", // legacy/future support\r\n] as const;\r\n\r\n/**\r\n * Schema identifier for targets.yaml files (version 2).\r\n */\r\nexport const TARGETS_SCHEMA_V2 = \"agentv-targets-v2\";\r\n\r\nexport interface ProviderRequest {\r\n readonly prompt: string;\r\n readonly guidelines?: string;\r\n readonly chatPrompt?: ChatPrompt;\r\n readonly attachments?: readonly string[];\r\n readonly testCaseId?: string;\r\n readonly attempt?: number;\r\n readonly maxOutputTokens?: number;\r\n readonly temperature?: number;\r\n readonly metadata?: JsonObject;\r\n readonly signal?: AbortSignal;\r\n}\r\n\r\nexport interface ProviderResponse {\r\n readonly text: string;\r\n readonly reasoning?: string;\r\n readonly raw?: unknown;\r\n readonly usage?: JsonObject;\r\n}\r\n\r\nexport interface Provider {\r\n readonly id: string;\r\n readonly kind: ProviderKind;\r\n readonly targetName: string;\r\n invoke(request: ProviderRequest): Promise<ProviderResponse>;\r\n}\r\n\r\nexport type EnvLookup = Readonly<Record<string, string | undefined>>;\r\n\r\nexport interface TargetDefinition {\r\n readonly name: string;\r\n readonly provider: ProviderKind | string;\r\n readonly settings?: Record<string, unknown> | undefined;\r\n readonly judge_target?: string | undefined;\r\n readonly workers?: number | undefined;\r\n}\r\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,OAAO,UAAU;AAEjB,eAAsB,WAAW,UAAoC;AACnE,MAAI;AACF,UAAM,OAAO,UAAU,UAAU,IAAI;AACrC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,YAAY,WAA2C;AAC3E,MAAI,aAAa,KAAK,QAAQ,KAAK,QAAQ,SAAS,CAAC;AACrD,QAAM,OAAO,KAAK,MAAM,UAAU,EAAE;AAEpC,SAAO,eAAe,MAAM;AAC1B,UAAM,UAAU,KAAK,KAAK,YAAY,MAAM;AAC5C,QAAI,MAAM,WAAW,OAAO,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,KAAK,QAAQ,UAAU;AACzC,QAAI,cAAc,YAAY;AAC5B;AAAA,IACF;AACA,iBAAa;AAAA,EACf;AAEA,SAAO;AACT;AAMO,SAAS,iBAAiB,UAAkB,UAAqC;AACtF,QAAM,cAAwB,CAAC;AAC/B,QAAM,UAAU,CAAC,SAAuB;AACtC,UAAM,aAAa,KAAK,QAAQ,IAAI;AACpC,QAAI,CAAC,YAAY,SAAS,UAAU,GAAG;AACrC,kBAAY,KAAK,UAAU;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,QAAQ,QAAQ;AACtC,MAAI,kBAAkB;AACtB,SAAO,CAAC,iBAAiB;AACvB,YAAQ,UAAU;AAClB,UAAM,YAAY,KAAK,QAAQ,UAAU;AACzC,QAAI,eAAe,YAAY,cAAc,YAAY;AACvD,wBAAkB;AAAA,IACpB,OAAO;AACL,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,UAAQ,QAAQ;AAChB,UAAQ,QAAQ,IAAI,CAAC;AACrB,SAAO;AACT;AAKA,SAAS,sBAAsB,OAAuB;AACpD,QAAM,UAAU,MAAM,QAAQ,WAAW,EAAE;AAC3C,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAKA,eAAsB,qBACpB,UACA,aAKC;AACD,QAAM,cAAc,sBAAsB,QAAQ;AAClD,QAAM,iBAA2B,CAAC;AAElC,MAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,mBAAe,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,EAC9C;AAEA,aAAW,QAAQ,aAAa;AAC9B,mBAAe,KAAK,KAAK,QAAQ,MAAM,WAAW,CAAC;AAAA,EACrD;AAEA,QAAM,YAAsB,CAAC;AAC7B,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,aAAa,gBAAgB;AACtC,UAAM,oBAAoB,KAAK,QAAQ,SAAS;AAChD,QAAI,KAAK,IAAI,iBAAiB,GAAG;AAC/B;AAAA,IACF;AACA,SAAK,IAAI,iBAAiB;AAC1B,cAAU,KAAK,iBAAiB;AAChC,QAAI,MAAM,WAAW,iBAAiB,GAAG;AACvC,aAAO,EAAE,aAAa,cAAc,mBAAmB,UAAU;AAAA,IACnE;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,UAAU;AAClC;;;AC7FO,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,IAAM,mBAAsC;AAAA,EACjD;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAKO,IAAM,oBAAoB;","names":[]}
@@ -283,7 +283,33 @@ function validateMessages(messages, location, filePath, errors) {
283
283
  var import_promises3 = require("fs/promises");
284
284
  var import_node_path2 = __toESM(require("path"), 1);
285
285
  var import_yaml3 = require("yaml");
286
- var SCHEMA_TARGETS_V22 = "agentv-targets-v2";
286
+
287
+ // src/evaluation/providers/types.ts
288
+ var KNOWN_PROVIDERS = [
289
+ "azure",
290
+ "anthropic",
291
+ "gemini",
292
+ "mock",
293
+ "vscode",
294
+ "vscode-insiders"
295
+ ];
296
+ var PROVIDER_ALIASES = [
297
+ "azure-openai",
298
+ // alias for "azure"
299
+ "google",
300
+ // alias for "gemini"
301
+ "google-gemini",
302
+ // alias for "gemini"
303
+ "openai",
304
+ // legacy/future support
305
+ "bedrock",
306
+ // legacy/future support
307
+ "vertex"
308
+ // legacy/future support
309
+ ];
310
+ var TARGETS_SCHEMA_V2 = "agentv-targets-v2";
311
+
312
+ // src/evaluation/validation/targets-validator.ts
287
313
  function isObject2(value) {
288
314
  return typeof value === "object" && value !== null && !Array.isArray(value);
289
315
  }
@@ -321,8 +347,8 @@ async function validateTargetsFile(filePath) {
321
347
  };
322
348
  }
323
349
  const schema = parsed["$schema"];
324
- if (schema !== SCHEMA_TARGETS_V22) {
325
- const message = typeof schema === "string" ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_TARGETS_V22}'` : `Missing required field '$schema'. Expected '${SCHEMA_TARGETS_V22}'`;
350
+ if (schema !== TARGETS_SCHEMA_V2) {
351
+ const message = typeof schema === "string" ? `Invalid $schema value '${schema}'. Expected '${TARGETS_SCHEMA_V2}'` : `Missing required field '$schema'. Expected '${TARGETS_SCHEMA_V2}'`;
326
352
  errors.push({
327
353
  severity: "error",
328
354
  filePath: absolutePath,
@@ -345,7 +371,7 @@ async function validateTargetsFile(filePath) {
345
371
  errors
346
372
  };
347
373
  }
348
- const knownProviders = ["azure", "openai", "anthropic", "bedrock", "vertex"];
374
+ const knownProviders = [...KNOWN_PROVIDERS, ...PROVIDER_ALIASES];
349
375
  for (let i = 0; i < targets.length; i++) {
350
376
  const target = targets[i];
351
377
  const location = `targets[${i}]`;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/evaluation/validation/index.ts","../../../src/evaluation/validation/file-type.ts","../../../src/evaluation/validation/eval-validator.ts","../../../src/evaluation/validation/targets-validator.ts","../../../src/evaluation/validation/file-reference-validator.ts","../../../src/evaluation/file-utils.ts"],"sourcesContent":["/**\r\n * Validation module for AgentV eval and targets files.\r\n */\r\n\r\nexport { detectFileType, isValidSchema, getExpectedSchema } from \"./file-type.js\";\r\nexport { validateEvalFile } from \"./eval-validator.js\";\r\nexport { validateTargetsFile } from \"./targets-validator.js\";\r\nexport { validateFileReferences } from \"./file-reference-validator.js\";\r\nexport type {\r\n FileType,\r\n ValidationSeverity,\r\n ValidationError,\r\n ValidationResult,\r\n ValidationSummary,\r\n} from \"./types.js\";\r\n","import { readFile } from \"node:fs/promises\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { FileType } from \"./types.js\";\r\n\r\nconst SCHEMA_EVAL_V2 = \"agentv-eval-v2\";\r\nconst SCHEMA_TARGETS_V2 = \"agentv-targets-v2\";\r\n\r\n/**\r\n * Detect file type by reading $schema field from YAML file.\r\n * Returns \"unknown\" if file cannot be read or $schema is missing/invalid.\r\n */\r\nexport async function detectFileType(filePath: string): Promise<FileType> {\r\n try {\r\n const content = await readFile(filePath, \"utf8\");\r\n const parsed = parse(content) as unknown;\r\n\r\n if (typeof parsed !== \"object\" || parsed === null) {\r\n return \"unknown\";\r\n }\r\n\r\n const record = parsed as Record<string, unknown>;\r\n const schema = record[\"$schema\"];\r\n\r\n if (typeof schema !== \"string\") {\r\n return \"unknown\";\r\n }\r\n\r\n switch (schema) {\r\n case SCHEMA_EVAL_V2:\r\n return \"eval\";\r\n case SCHEMA_TARGETS_V2:\r\n return \"targets\";\r\n default:\r\n return \"unknown\";\r\n }\r\n } catch {\r\n return \"unknown\";\r\n }\r\n}\r\n\r\n/**\r\n * Check if a schema value is a valid AgentV schema identifier.\r\n */\r\nexport function isValidSchema(schema: unknown): boolean {\r\n return schema === SCHEMA_EVAL_V2 || schema === SCHEMA_TARGETS_V2;\r\n}\r\n\r\n/**\r\n * Get the expected schema for a file type.\r\n */\r\nexport function getExpectedSchema(fileType: FileType): string | undefined {\r\n switch (fileType) {\r\n case \"eval\":\r\n return SCHEMA_EVAL_V2;\r\n case \"targets\":\r\n return SCHEMA_TARGETS_V2;\r\n default:\r\n return undefined;\r\n }\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\nconst SCHEMA_EVAL_V2 = \"agentv-eval-v2\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate an eval file (agentv-eval-v2 schema).\r\n */\r\nexport async function validateEvalFile(\r\n filePath: string,\r\n): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(filePath);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: `Failed to parse YAML: ${(error as Error).message}`,\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"File must contain a YAML object\",\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate $schema field\r\n const schema = parsed[\"$schema\"];\r\n if (schema !== SCHEMA_EVAL_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_EVAL_V2}'`\r\n : `Missing required field '$schema'. Expected '${SCHEMA_EVAL_V2}'`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate evalcases array\r\n const evalcases = parsed[\"evalcases\"];\r\n if (!Array.isArray(evalcases)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"evalcases\",\r\n message: \"Missing or invalid 'evalcases' field (must be an array)\",\r\n });\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate each eval case\r\n for (let i = 0; i < evalcases.length; i++) {\r\n const evalCase = evalcases[i];\r\n const location = `evalcases[${i}]`;\r\n\r\n if (!isObject(evalCase)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"Eval case must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Required fields: id, outcome, input_messages, expected_messages\r\n const id = evalCase[\"id\"];\r\n if (typeof id !== \"string\" || id.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.id`,\r\n message: \"Missing or invalid 'id' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n const outcome = evalCase[\"outcome\"];\r\n if (typeof outcome !== \"string\" || outcome.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.outcome`,\r\n message: \"Missing or invalid 'outcome' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n const inputMessages = evalCase[\"input_messages\"];\r\n if (!Array.isArray(inputMessages)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.input_messages`,\r\n message: \"Missing or invalid 'input_messages' field (must be an array)\",\r\n });\r\n } else {\r\n validateMessages(inputMessages, `${location}.input_messages`, absolutePath, errors);\r\n }\r\n\r\n const expectedMessages = evalCase[\"expected_messages\"];\r\n if (!Array.isArray(expectedMessages)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.expected_messages`,\r\n message: \"Missing or invalid 'expected_messages' field (must be an array)\",\r\n });\r\n } else {\r\n validateMessages(expectedMessages, `${location}.expected_messages`, absolutePath, errors);\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n}\r\n\r\nfunction validateMessages(\r\n messages: JsonArray,\r\n location: string,\r\n filePath: string,\r\n errors: ValidationError[],\r\n): void {\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n const msgLocation = `${location}[${i}]`;\r\n\r\n if (!isObject(message)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: msgLocation,\r\n message: \"Message must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Validate role field\r\n const role = message[\"role\"];\r\n const validRoles = [\"system\", \"user\", \"assistant\"];\r\n if (!validRoles.includes(role as string)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${msgLocation}.role`,\r\n message: `Invalid role '${role}'. Must be one of: ${validRoles.join(\", \")}`,\r\n });\r\n }\r\n\r\n // Validate content field (can be string or array)\r\n const content = message[\"content\"];\r\n if (typeof content === \"string\") {\r\n // String content is valid\r\n } else if (Array.isArray(content)) {\r\n // Array content - validate each element\r\n for (let j = 0; j < content.length; j++) {\r\n const contentItem = content[j];\r\n const contentLocation = `${msgLocation}.content[${j}]`;\r\n\r\n if (typeof contentItem === \"string\") {\r\n // String in array is valid\r\n } else if (isObject(contentItem)) {\r\n const type = contentItem[\"type\"];\r\n if (typeof type !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${contentLocation}.type`,\r\n message: \"Content object must have a 'type' field\",\r\n });\r\n }\r\n\r\n // For 'file' type, we'll validate existence later in file-reference-validator\r\n // For 'text' type, require 'value' field\r\n if (type === \"text\") {\r\n const value = contentItem[\"value\"];\r\n if (typeof value !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${contentLocation}.value`,\r\n message: \"Content with type 'text' must have a 'value' field\",\r\n });\r\n }\r\n }\r\n } else {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: contentLocation,\r\n message: \"Content array items must be strings or objects\",\r\n });\r\n }\r\n }\r\n } else {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${msgLocation}.content`,\r\n message: \"Missing or invalid 'content' field (must be a string or array)\",\r\n });\r\n }\r\n }\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\nconst SCHEMA_TARGETS_V2 = \"agentv-targets-v2\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate a targets file (agentv-targets-v2 schema).\r\n */\r\nexport async function validateTargetsFile(\r\n filePath: string,\r\n): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(filePath);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: `Failed to parse YAML: ${(error as Error).message}`,\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"File must contain a YAML object\",\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate $schema field\r\n const schema = parsed[\"$schema\"];\r\n if (schema !== SCHEMA_TARGETS_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_TARGETS_V2}'`\r\n : `Missing required field '$schema'. Expected '${SCHEMA_TARGETS_V2}'`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate targets array\r\n const targets = parsed[\"targets\"];\r\n if (!Array.isArray(targets)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"targets\",\r\n message: \"Missing or invalid 'targets' field (must be an array)\",\r\n });\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate each target definition\r\n const knownProviders = [\"azure\", \"openai\", \"anthropic\", \"bedrock\", \"vertex\"];\r\n \r\n for (let i = 0; i < targets.length; i++) {\r\n const target = targets[i];\r\n const location = `targets[${i}]`;\r\n\r\n if (!isObject(target)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"Target must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Required field: name\r\n const name = target[\"name\"];\r\n if (typeof name !== \"string\" || name.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.name`,\r\n message: \"Missing or invalid 'name' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n // Required field: provider\r\n const provider = target[\"provider\"];\r\n if (typeof provider !== \"string\" || provider.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.provider`,\r\n message: \"Missing or invalid 'provider' field (must be a non-empty string)\",\r\n });\r\n } else if (!knownProviders.includes(provider)) {\r\n // Warning for unknown providers (non-fatal)\r\n errors.push({\r\n severity: \"warning\",\r\n filePath: absolutePath,\r\n location: `${location}.provider`,\r\n message: `Unknown provider '${provider}'. Known providers: ${knownProviders.join(\", \")}`,\r\n });\r\n }\r\n\r\n // Optional field: settings (must be object if present)\r\n const settings = target[\"settings\"];\r\n if (settings !== undefined && !isObject(settings)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.settings`,\r\n message: \"Invalid 'settings' field (must be an object)\",\r\n });\r\n }\r\n\r\n // Optional field: judge_target (must be string if present)\r\n const judgeTarget = target[\"judge_target\"];\r\n if (judgeTarget !== undefined && typeof judgeTarget !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.judge_target`,\r\n message: \"Invalid 'judge_target' field (must be a string)\",\r\n });\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.filter((e) => e.severity === \"error\").length === 0,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport { buildSearchRoots, findGitRoot, resolveFileReference } from \"../file-utils.js\";\r\nimport type { ValidationError } from \"./types.js\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate that file references in eval file content exist.\r\n * Checks content blocks with type: \"file\" and validates the referenced file exists.\r\n * Also checks that referenced files are not empty.\r\n */\r\nexport async function validateFileReferences(\r\n evalFilePath: string,\r\n): Promise<readonly ValidationError[]> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(evalFilePath);\r\n\r\n // Find git root and build search roots (same as yaml-parser does at runtime)\r\n const gitRoot = await findGitRoot(absolutePath);\r\n if (!gitRoot) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"Cannot validate file references: git repository root not found\",\r\n });\r\n return errors;\r\n }\r\n\r\n const searchRoots = buildSearchRoots(absolutePath, gitRoot);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch {\r\n // Parse errors are already caught by eval-validator\r\n return errors;\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n return errors;\r\n }\r\n\r\n const evalcases = parsed[\"evalcases\"];\r\n if (!Array.isArray(evalcases)) {\r\n return errors;\r\n }\r\n\r\n for (let i = 0; i < evalcases.length; i++) {\r\n const evalCase = evalcases[i];\r\n if (!isObject(evalCase)) {\r\n continue;\r\n }\r\n\r\n // Check input_messages\r\n const inputMessages = evalCase[\"input_messages\"];\r\n if (Array.isArray(inputMessages)) {\r\n await validateMessagesFileRefs(inputMessages, `evalcases[${i}].input_messages`, searchRoots, absolutePath, errors);\r\n }\r\n\r\n // Check expected_messages\r\n const expectedMessages = evalCase[\"expected_messages\"];\r\n if (Array.isArray(expectedMessages)) {\r\n await validateMessagesFileRefs(expectedMessages, `evalcases[${i}].expected_messages`, searchRoots, absolutePath, errors);\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\nasync function validateMessagesFileRefs(\r\n messages: JsonArray,\r\n location: string,\r\n searchRoots: readonly string[],\r\n filePath: string,\r\n errors: ValidationError[],\r\n): Promise<void> {\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n if (!isObject(message)) {\r\n continue;\r\n }\r\n\r\n const content = message[\"content\"];\r\n if (typeof content === \"string\") {\r\n continue;\r\n }\r\n\r\n if (!Array.isArray(content)) {\r\n continue;\r\n }\r\n\r\n for (let j = 0; j < content.length; j++) {\r\n const contentItem = content[j];\r\n if (!isObject(contentItem)) {\r\n continue;\r\n }\r\n\r\n const type = contentItem[\"type\"];\r\n if (type !== \"file\") {\r\n continue;\r\n }\r\n\r\n const value = contentItem[\"value\"];\r\n if (typeof value !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}].value`,\r\n message: \"File reference must have a 'value' field with the file path\",\r\n });\r\n continue;\r\n }\r\n\r\n // Use the same file resolution logic as yaml-parser at runtime\r\n const { resolvedPath } = await resolveFileReference(value, searchRoots);\r\n\r\n if (!resolvedPath) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Referenced file not found: ${value}`,\r\n });\r\n } else {\r\n // Check that file is not empty\r\n try {\r\n const fileContent = await readFile(resolvedPath, \"utf8\");\r\n if (fileContent.trim().length === 0) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Referenced file is empty: ${value}`,\r\n });\r\n }\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Cannot read referenced file: ${value} (${(error as Error).message})`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { constants } from \"node:fs\";\r\nimport { access } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\n\r\nexport async function fileExists(filePath: string): Promise<boolean> {\r\n try {\r\n await access(filePath, constants.F_OK);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Find git repository root by walking up the directory tree.\r\n */\r\nexport async function findGitRoot(startPath: string): Promise<string | null> {\r\n let currentDir = path.dirname(path.resolve(startPath));\r\n const root = path.parse(currentDir).root;\r\n\r\n while (currentDir !== root) {\r\n const gitPath = path.join(currentDir, \".git\");\r\n if (await fileExists(gitPath)) {\r\n return currentDir;\r\n }\r\n\r\n const parentDir = path.dirname(currentDir);\r\n if (parentDir === currentDir) {\r\n break;\r\n }\r\n currentDir = parentDir;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Build search roots for file resolution, matching yaml-parser behavior.\r\n * Searches from eval file directory up to repo root.\r\n */\r\nexport function buildSearchRoots(evalPath: string, repoRoot: string): readonly string[] {\r\n const uniqueRoots: string[] = [];\r\n const addRoot = (root: string): void => {\r\n const normalized = path.resolve(root);\r\n if (!uniqueRoots.includes(normalized)) {\r\n uniqueRoots.push(normalized);\r\n }\r\n };\r\n\r\n let currentDir = path.dirname(evalPath);\r\n let reachedBoundary = false;\r\n while (!reachedBoundary) {\r\n addRoot(currentDir);\r\n const parentDir = path.dirname(currentDir);\r\n if (currentDir === repoRoot || parentDir === currentDir) {\r\n reachedBoundary = true;\r\n } else {\r\n currentDir = parentDir;\r\n }\r\n }\r\n\r\n addRoot(repoRoot);\r\n addRoot(process.cwd());\r\n return uniqueRoots;\r\n}\r\n\r\n/**\r\n * Trim leading path separators for display.\r\n */\r\nfunction trimLeadingSeparators(value: string): string {\r\n const trimmed = value.replace(/^[/\\\\]+/, \"\");\r\n return trimmed.length > 0 ? trimmed : value;\r\n}\r\n\r\n/**\r\n * Resolve a file reference using search roots, matching yaml-parser behavior.\r\n */\r\nexport async function resolveFileReference(\r\n rawValue: string,\r\n searchRoots: readonly string[],\r\n): Promise<{\r\n readonly displayPath: string;\r\n readonly resolvedPath?: string;\r\n readonly attempted: readonly string[];\r\n}> {\r\n const displayPath = trimLeadingSeparators(rawValue);\r\n const potentialPaths: string[] = [];\r\n\r\n if (path.isAbsolute(rawValue)) {\r\n potentialPaths.push(path.normalize(rawValue));\r\n }\r\n\r\n for (const base of searchRoots) {\r\n potentialPaths.push(path.resolve(base, displayPath));\r\n }\r\n\r\n const attempted: string[] = [];\r\n const seen = new Set<string>();\r\n for (const candidate of potentialPaths) {\r\n const absoluteCandidate = path.resolve(candidate);\r\n if (seen.has(absoluteCandidate)) {\r\n continue;\r\n }\r\n seen.add(absoluteCandidate);\r\n attempted.push(absoluteCandidate);\r\n if (await fileExists(absoluteCandidate)) {\r\n return { displayPath, resolvedPath: absoluteCandidate, attempted };\r\n }\r\n }\r\n\r\n return { displayPath, attempted };\r\n}\r\n"],"mappings":"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","names":["import_promises","import_yaml","SCHEMA_EVAL_V2","path","import_promises","import_node_path","import_yaml","SCHEMA_TARGETS_V2","isObject","path","import_promises","import_node_path","import_yaml","import_promises","import_node_path","path","isObject","path"]}
1
+ {"version":3,"sources":["../../../src/evaluation/validation/index.ts","../../../src/evaluation/validation/file-type.ts","../../../src/evaluation/validation/eval-validator.ts","../../../src/evaluation/validation/targets-validator.ts","../../../src/evaluation/providers/types.ts","../../../src/evaluation/validation/file-reference-validator.ts","../../../src/evaluation/file-utils.ts"],"sourcesContent":["/**\r\n * Validation module for AgentV eval and targets files.\r\n */\r\n\r\nexport { detectFileType, isValidSchema, getExpectedSchema } from \"./file-type.js\";\r\nexport { validateEvalFile } from \"./eval-validator.js\";\r\nexport { validateTargetsFile } from \"./targets-validator.js\";\r\nexport { validateFileReferences } from \"./file-reference-validator.js\";\r\nexport type {\r\n FileType,\r\n ValidationSeverity,\r\n ValidationError,\r\n ValidationResult,\r\n ValidationSummary,\r\n} from \"./types.js\";\r\n","import { readFile } from \"node:fs/promises\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { FileType } from \"./types.js\";\r\n\r\nconst SCHEMA_EVAL_V2 = \"agentv-eval-v2\";\r\nconst SCHEMA_TARGETS_V2 = \"agentv-targets-v2\";\r\n\r\n/**\r\n * Detect file type by reading $schema field from YAML file.\r\n * Returns \"unknown\" if file cannot be read or $schema is missing/invalid.\r\n */\r\nexport async function detectFileType(filePath: string): Promise<FileType> {\r\n try {\r\n const content = await readFile(filePath, \"utf8\");\r\n const parsed = parse(content) as unknown;\r\n\r\n if (typeof parsed !== \"object\" || parsed === null) {\r\n return \"unknown\";\r\n }\r\n\r\n const record = parsed as Record<string, unknown>;\r\n const schema = record[\"$schema\"];\r\n\r\n if (typeof schema !== \"string\") {\r\n return \"unknown\";\r\n }\r\n\r\n switch (schema) {\r\n case SCHEMA_EVAL_V2:\r\n return \"eval\";\r\n case SCHEMA_TARGETS_V2:\r\n return \"targets\";\r\n default:\r\n return \"unknown\";\r\n }\r\n } catch {\r\n return \"unknown\";\r\n }\r\n}\r\n\r\n/**\r\n * Check if a schema value is a valid AgentV schema identifier.\r\n */\r\nexport function isValidSchema(schema: unknown): boolean {\r\n return schema === SCHEMA_EVAL_V2 || schema === SCHEMA_TARGETS_V2;\r\n}\r\n\r\n/**\r\n * Get the expected schema for a file type.\r\n */\r\nexport function getExpectedSchema(fileType: FileType): string | undefined {\r\n switch (fileType) {\r\n case \"eval\":\r\n return SCHEMA_EVAL_V2;\r\n case \"targets\":\r\n return SCHEMA_TARGETS_V2;\r\n default:\r\n return undefined;\r\n }\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\nconst SCHEMA_EVAL_V2 = \"agentv-eval-v2\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate an eval file (agentv-eval-v2 schema).\r\n */\r\nexport async function validateEvalFile(\r\n filePath: string,\r\n): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(filePath);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: `Failed to parse YAML: ${(error as Error).message}`,\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"File must contain a YAML object\",\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate $schema field\r\n const schema = parsed[\"$schema\"];\r\n if (schema !== SCHEMA_EVAL_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_EVAL_V2}'`\r\n : `Missing required field '$schema'. Expected '${SCHEMA_EVAL_V2}'`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate evalcases array\r\n const evalcases = parsed[\"evalcases\"];\r\n if (!Array.isArray(evalcases)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"evalcases\",\r\n message: \"Missing or invalid 'evalcases' field (must be an array)\",\r\n });\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate each eval case\r\n for (let i = 0; i < evalcases.length; i++) {\r\n const evalCase = evalcases[i];\r\n const location = `evalcases[${i}]`;\r\n\r\n if (!isObject(evalCase)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"Eval case must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Required fields: id, outcome, input_messages, expected_messages\r\n const id = evalCase[\"id\"];\r\n if (typeof id !== \"string\" || id.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.id`,\r\n message: \"Missing or invalid 'id' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n const outcome = evalCase[\"outcome\"];\r\n if (typeof outcome !== \"string\" || outcome.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.outcome`,\r\n message: \"Missing or invalid 'outcome' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n const inputMessages = evalCase[\"input_messages\"];\r\n if (!Array.isArray(inputMessages)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.input_messages`,\r\n message: \"Missing or invalid 'input_messages' field (must be an array)\",\r\n });\r\n } else {\r\n validateMessages(inputMessages, `${location}.input_messages`, absolutePath, errors);\r\n }\r\n\r\n const expectedMessages = evalCase[\"expected_messages\"];\r\n if (!Array.isArray(expectedMessages)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.expected_messages`,\r\n message: \"Missing or invalid 'expected_messages' field (must be an array)\",\r\n });\r\n } else {\r\n validateMessages(expectedMessages, `${location}.expected_messages`, absolutePath, errors);\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n}\r\n\r\nfunction validateMessages(\r\n messages: JsonArray,\r\n location: string,\r\n filePath: string,\r\n errors: ValidationError[],\r\n): void {\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n const msgLocation = `${location}[${i}]`;\r\n\r\n if (!isObject(message)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: msgLocation,\r\n message: \"Message must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Validate role field\r\n const role = message[\"role\"];\r\n const validRoles = [\"system\", \"user\", \"assistant\"];\r\n if (!validRoles.includes(role as string)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${msgLocation}.role`,\r\n message: `Invalid role '${role}'. Must be one of: ${validRoles.join(\", \")}`,\r\n });\r\n }\r\n\r\n // Validate content field (can be string or array)\r\n const content = message[\"content\"];\r\n if (typeof content === \"string\") {\r\n // String content is valid\r\n } else if (Array.isArray(content)) {\r\n // Array content - validate each element\r\n for (let j = 0; j < content.length; j++) {\r\n const contentItem = content[j];\r\n const contentLocation = `${msgLocation}.content[${j}]`;\r\n\r\n if (typeof contentItem === \"string\") {\r\n // String in array is valid\r\n } else if (isObject(contentItem)) {\r\n const type = contentItem[\"type\"];\r\n if (typeof type !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${contentLocation}.type`,\r\n message: \"Content object must have a 'type' field\",\r\n });\r\n }\r\n\r\n // For 'file' type, we'll validate existence later in file-reference-validator\r\n // For 'text' type, require 'value' field\r\n if (type === \"text\") {\r\n const value = contentItem[\"value\"];\r\n if (typeof value !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${contentLocation}.value`,\r\n message: \"Content with type 'text' must have a 'value' field\",\r\n });\r\n }\r\n }\r\n } else {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: contentLocation,\r\n message: \"Content array items must be strings or objects\",\r\n });\r\n }\r\n }\r\n } else {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${msgLocation}.content`,\r\n message: \"Missing or invalid 'content' field (must be a string or array)\",\r\n });\r\n }\r\n }\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport { KNOWN_PROVIDERS, PROVIDER_ALIASES, TARGETS_SCHEMA_V2 } from \"../providers/types.js\";\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate a targets file (agentv-targets-v2 schema).\r\n */\r\nexport async function validateTargetsFile(\r\n filePath: string,\r\n): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(filePath);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: `Failed to parse YAML: ${(error as Error).message}`,\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"File must contain a YAML object\",\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate $schema field\r\n const schema = parsed[\"$schema\"];\r\n if (schema !== TARGETS_SCHEMA_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${TARGETS_SCHEMA_V2}'`\r\n : `Missing required field '$schema'. Expected '${TARGETS_SCHEMA_V2}'`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate targets array\r\n const targets = parsed[\"targets\"];\r\n if (!Array.isArray(targets)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"targets\",\r\n message: \"Missing or invalid 'targets' field (must be an array)\",\r\n });\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate each target definition\r\n const knownProviders = [...KNOWN_PROVIDERS, ...PROVIDER_ALIASES];\r\n \r\n for (let i = 0; i < targets.length; i++) {\r\n const target = targets[i];\r\n const location = `targets[${i}]`;\r\n\r\n if (!isObject(target)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"Target must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Required field: name\r\n const name = target[\"name\"];\r\n if (typeof name !== \"string\" || name.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.name`,\r\n message: \"Missing or invalid 'name' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n // Required field: provider\r\n const provider = target[\"provider\"];\r\n if (typeof provider !== \"string\" || provider.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.provider`,\r\n message: \"Missing or invalid 'provider' field (must be a non-empty string)\",\r\n });\r\n } else if (!knownProviders.includes(provider)) {\r\n // Warning for unknown providers (non-fatal)\r\n errors.push({\r\n severity: \"warning\",\r\n filePath: absolutePath,\r\n location: `${location}.provider`,\r\n message: `Unknown provider '${provider}'. Known providers: ${knownProviders.join(\", \")}`,\r\n });\r\n }\r\n\r\n // Optional field: settings (must be object if present)\r\n const settings = target[\"settings\"];\r\n if (settings !== undefined && !isObject(settings)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.settings`,\r\n message: \"Invalid 'settings' field (must be an object)\",\r\n });\r\n }\r\n\r\n // Optional field: judge_target (must be string if present)\r\n const judgeTarget = target[\"judge_target\"];\r\n if (judgeTarget !== undefined && typeof judgeTarget !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.judge_target`,\r\n message: \"Invalid 'judge_target' field (must be a string)\",\r\n });\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.filter((e) => e.severity === \"error\").length === 0,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n}\r\n","import type { AxChatRequest } from \"@ax-llm/ax\";\r\n\r\nimport type { JsonObject } from \"../types.js\";\r\n\r\ntype ChatPrompt = AxChatRequest[\"chatPrompt\"];\r\n\r\nexport type ProviderKind =\r\n | \"azure\"\r\n | \"anthropic\"\r\n | \"gemini\"\r\n | \"mock\"\r\n | \"vscode\"\r\n | \"vscode-insiders\";\r\n\r\n/**\r\n * List of all supported provider kinds.\r\n * This is the source of truth for provider validation.\r\n */\r\nexport const KNOWN_PROVIDERS: readonly ProviderKind[] = [\r\n \"azure\",\r\n \"anthropic\",\r\n \"gemini\",\r\n \"mock\",\r\n \"vscode\",\r\n \"vscode-insiders\",\r\n] as const;\r\n\r\n/**\r\n * Provider aliases that are accepted in target definitions.\r\n * These map to the canonical ProviderKind values.\r\n */\r\nexport const PROVIDER_ALIASES: readonly string[] = [\r\n \"azure-openai\", // alias for \"azure\"\r\n \"google\", // alias for \"gemini\"\r\n \"google-gemini\", // alias for \"gemini\"\r\n \"openai\", // legacy/future support\r\n \"bedrock\", // legacy/future support\r\n \"vertex\", // legacy/future support\r\n] as const;\r\n\r\n/**\r\n * Schema identifier for targets.yaml files (version 2).\r\n */\r\nexport const TARGETS_SCHEMA_V2 = \"agentv-targets-v2\";\r\n\r\nexport interface ProviderRequest {\r\n readonly prompt: string;\r\n readonly guidelines?: string;\r\n readonly chatPrompt?: ChatPrompt;\r\n readonly attachments?: readonly string[];\r\n readonly testCaseId?: string;\r\n readonly attempt?: number;\r\n readonly maxOutputTokens?: number;\r\n readonly temperature?: number;\r\n readonly metadata?: JsonObject;\r\n readonly signal?: AbortSignal;\r\n}\r\n\r\nexport interface ProviderResponse {\r\n readonly text: string;\r\n readonly reasoning?: string;\r\n readonly raw?: unknown;\r\n readonly usage?: JsonObject;\r\n}\r\n\r\nexport interface Provider {\r\n readonly id: string;\r\n readonly kind: ProviderKind;\r\n readonly targetName: string;\r\n invoke(request: ProviderRequest): Promise<ProviderResponse>;\r\n}\r\n\r\nexport type EnvLookup = Readonly<Record<string, string | undefined>>;\r\n\r\nexport interface TargetDefinition {\r\n readonly name: string;\r\n readonly provider: ProviderKind | string;\r\n readonly settings?: Record<string, unknown> | undefined;\r\n readonly judge_target?: string | undefined;\r\n readonly workers?: number | undefined;\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport { buildSearchRoots, findGitRoot, resolveFileReference } from \"../file-utils.js\";\r\nimport type { ValidationError } from \"./types.js\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate that file references in eval file content exist.\r\n * Checks content blocks with type: \"file\" and validates the referenced file exists.\r\n * Also checks that referenced files are not empty.\r\n */\r\nexport async function validateFileReferences(\r\n evalFilePath: string,\r\n): Promise<readonly ValidationError[]> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(evalFilePath);\r\n\r\n // Find git root and build search roots (same as yaml-parser does at runtime)\r\n const gitRoot = await findGitRoot(absolutePath);\r\n if (!gitRoot) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"Cannot validate file references: git repository root not found\",\r\n });\r\n return errors;\r\n }\r\n\r\n const searchRoots = buildSearchRoots(absolutePath, gitRoot);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch {\r\n // Parse errors are already caught by eval-validator\r\n return errors;\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n return errors;\r\n }\r\n\r\n const evalcases = parsed[\"evalcases\"];\r\n if (!Array.isArray(evalcases)) {\r\n return errors;\r\n }\r\n\r\n for (let i = 0; i < evalcases.length; i++) {\r\n const evalCase = evalcases[i];\r\n if (!isObject(evalCase)) {\r\n continue;\r\n }\r\n\r\n // Check input_messages\r\n const inputMessages = evalCase[\"input_messages\"];\r\n if (Array.isArray(inputMessages)) {\r\n await validateMessagesFileRefs(inputMessages, `evalcases[${i}].input_messages`, searchRoots, absolutePath, errors);\r\n }\r\n\r\n // Check expected_messages\r\n const expectedMessages = evalCase[\"expected_messages\"];\r\n if (Array.isArray(expectedMessages)) {\r\n await validateMessagesFileRefs(expectedMessages, `evalcases[${i}].expected_messages`, searchRoots, absolutePath, errors);\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\nasync function validateMessagesFileRefs(\r\n messages: JsonArray,\r\n location: string,\r\n searchRoots: readonly string[],\r\n filePath: string,\r\n errors: ValidationError[],\r\n): Promise<void> {\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n if (!isObject(message)) {\r\n continue;\r\n }\r\n\r\n const content = message[\"content\"];\r\n if (typeof content === \"string\") {\r\n continue;\r\n }\r\n\r\n if (!Array.isArray(content)) {\r\n continue;\r\n }\r\n\r\n for (let j = 0; j < content.length; j++) {\r\n const contentItem = content[j];\r\n if (!isObject(contentItem)) {\r\n continue;\r\n }\r\n\r\n const type = contentItem[\"type\"];\r\n if (type !== \"file\") {\r\n continue;\r\n }\r\n\r\n const value = contentItem[\"value\"];\r\n if (typeof value !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}].value`,\r\n message: \"File reference must have a 'value' field with the file path\",\r\n });\r\n continue;\r\n }\r\n\r\n // Use the same file resolution logic as yaml-parser at runtime\r\n const { resolvedPath } = await resolveFileReference(value, searchRoots);\r\n\r\n if (!resolvedPath) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Referenced file not found: ${value}`,\r\n });\r\n } else {\r\n // Check that file is not empty\r\n try {\r\n const fileContent = await readFile(resolvedPath, \"utf8\");\r\n if (fileContent.trim().length === 0) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Referenced file is empty: ${value}`,\r\n });\r\n }\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Cannot read referenced file: ${value} (${(error as Error).message})`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { constants } from \"node:fs\";\r\nimport { access } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\n\r\nexport async function fileExists(filePath: string): Promise<boolean> {\r\n try {\r\n await access(filePath, constants.F_OK);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Find git repository root by walking up the directory tree.\r\n */\r\nexport async function findGitRoot(startPath: string): Promise<string | null> {\r\n let currentDir = path.dirname(path.resolve(startPath));\r\n const root = path.parse(currentDir).root;\r\n\r\n while (currentDir !== root) {\r\n const gitPath = path.join(currentDir, \".git\");\r\n if (await fileExists(gitPath)) {\r\n return currentDir;\r\n }\r\n\r\n const parentDir = path.dirname(currentDir);\r\n if (parentDir === currentDir) {\r\n break;\r\n }\r\n currentDir = parentDir;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Build search roots for file resolution, matching yaml-parser behavior.\r\n * Searches from eval file directory up to repo root.\r\n */\r\nexport function buildSearchRoots(evalPath: string, repoRoot: string): readonly string[] {\r\n const uniqueRoots: string[] = [];\r\n const addRoot = (root: string): void => {\r\n const normalized = path.resolve(root);\r\n if (!uniqueRoots.includes(normalized)) {\r\n uniqueRoots.push(normalized);\r\n }\r\n };\r\n\r\n let currentDir = path.dirname(evalPath);\r\n let reachedBoundary = false;\r\n while (!reachedBoundary) {\r\n addRoot(currentDir);\r\n const parentDir = path.dirname(currentDir);\r\n if (currentDir === repoRoot || parentDir === currentDir) {\r\n reachedBoundary = true;\r\n } else {\r\n currentDir = parentDir;\r\n }\r\n }\r\n\r\n addRoot(repoRoot);\r\n addRoot(process.cwd());\r\n return uniqueRoots;\r\n}\r\n\r\n/**\r\n * Trim leading path separators for display.\r\n */\r\nfunction trimLeadingSeparators(value: string): string {\r\n const trimmed = value.replace(/^[/\\\\]+/, \"\");\r\n return trimmed.length > 0 ? trimmed : value;\r\n}\r\n\r\n/**\r\n * Resolve a file reference using search roots, matching yaml-parser behavior.\r\n */\r\nexport async function resolveFileReference(\r\n rawValue: string,\r\n searchRoots: readonly string[],\r\n): Promise<{\r\n readonly displayPath: string;\r\n readonly resolvedPath?: string;\r\n readonly attempted: readonly string[];\r\n}> {\r\n const displayPath = trimLeadingSeparators(rawValue);\r\n const potentialPaths: string[] = [];\r\n\r\n if (path.isAbsolute(rawValue)) {\r\n potentialPaths.push(path.normalize(rawValue));\r\n }\r\n\r\n for (const base of searchRoots) {\r\n potentialPaths.push(path.resolve(base, displayPath));\r\n }\r\n\r\n const attempted: string[] = [];\r\n const seen = new Set<string>();\r\n for (const candidate of potentialPaths) {\r\n const absoluteCandidate = path.resolve(candidate);\r\n if (seen.has(absoluteCandidate)) {\r\n continue;\r\n }\r\n seen.add(absoluteCandidate);\r\n attempted.push(absoluteCandidate);\r\n if (await fileExists(absoluteCandidate)) {\r\n return { displayPath, resolvedPath: absoluteCandidate, attempted };\r\n }\r\n }\r\n\r\n return { displayPath, attempted };\r\n}\r\n"],"mappings":"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","names":["import_promises","import_yaml","SCHEMA_EVAL_V2","path","import_promises","import_node_path","import_yaml","isObject","path","import_promises","import_node_path","import_yaml","import_promises","import_node_path","path","isObject","path"]}
@@ -1,8 +1,11 @@
1
1
  import {
2
+ KNOWN_PROVIDERS,
3
+ PROVIDER_ALIASES,
4
+ TARGETS_SCHEMA_V2,
2
5
  buildSearchRoots,
3
6
  findGitRoot,
4
7
  resolveFileReference
5
- } from "../../chunk-5REK5RSI.js";
8
+ } from "../../chunk-QVS4OL44.js";
6
9
 
7
10
  // src/evaluation/validation/file-type.ts
8
11
  import { readFile } from "node:fs/promises";
@@ -248,7 +251,6 @@ function validateMessages(messages, location, filePath, errors) {
248
251
  import { readFile as readFile3 } from "node:fs/promises";
249
252
  import path2 from "node:path";
250
253
  import { parse as parse3 } from "yaml";
251
- var SCHEMA_TARGETS_V22 = "agentv-targets-v2";
252
254
  function isObject2(value) {
253
255
  return typeof value === "object" && value !== null && !Array.isArray(value);
254
256
  }
@@ -286,8 +288,8 @@ async function validateTargetsFile(filePath) {
286
288
  };
287
289
  }
288
290
  const schema = parsed["$schema"];
289
- if (schema !== SCHEMA_TARGETS_V22) {
290
- const message = typeof schema === "string" ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_TARGETS_V22}'` : `Missing required field '$schema'. Expected '${SCHEMA_TARGETS_V22}'`;
291
+ if (schema !== TARGETS_SCHEMA_V2) {
292
+ const message = typeof schema === "string" ? `Invalid $schema value '${schema}'. Expected '${TARGETS_SCHEMA_V2}'` : `Missing required field '$schema'. Expected '${TARGETS_SCHEMA_V2}'`;
291
293
  errors.push({
292
294
  severity: "error",
293
295
  filePath: absolutePath,
@@ -310,7 +312,7 @@ async function validateTargetsFile(filePath) {
310
312
  errors
311
313
  };
312
314
  }
313
- const knownProviders = ["azure", "openai", "anthropic", "bedrock", "vertex"];
315
+ const knownProviders = [...KNOWN_PROVIDERS, ...PROVIDER_ALIASES];
314
316
  for (let i = 0; i < targets.length; i++) {
315
317
  const target = targets[i];
316
318
  const location = `targets[${i}]`;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/evaluation/validation/file-type.ts","../../../src/evaluation/validation/eval-validator.ts","../../../src/evaluation/validation/targets-validator.ts","../../../src/evaluation/validation/file-reference-validator.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { FileType } from \"./types.js\";\r\n\r\nconst SCHEMA_EVAL_V2 = \"agentv-eval-v2\";\r\nconst SCHEMA_TARGETS_V2 = \"agentv-targets-v2\";\r\n\r\n/**\r\n * Detect file type by reading $schema field from YAML file.\r\n * Returns \"unknown\" if file cannot be read or $schema is missing/invalid.\r\n */\r\nexport async function detectFileType(filePath: string): Promise<FileType> {\r\n try {\r\n const content = await readFile(filePath, \"utf8\");\r\n const parsed = parse(content) as unknown;\r\n\r\n if (typeof parsed !== \"object\" || parsed === null) {\r\n return \"unknown\";\r\n }\r\n\r\n const record = parsed as Record<string, unknown>;\r\n const schema = record[\"$schema\"];\r\n\r\n if (typeof schema !== \"string\") {\r\n return \"unknown\";\r\n }\r\n\r\n switch (schema) {\r\n case SCHEMA_EVAL_V2:\r\n return \"eval\";\r\n case SCHEMA_TARGETS_V2:\r\n return \"targets\";\r\n default:\r\n return \"unknown\";\r\n }\r\n } catch {\r\n return \"unknown\";\r\n }\r\n}\r\n\r\n/**\r\n * Check if a schema value is a valid AgentV schema identifier.\r\n */\r\nexport function isValidSchema(schema: unknown): boolean {\r\n return schema === SCHEMA_EVAL_V2 || schema === SCHEMA_TARGETS_V2;\r\n}\r\n\r\n/**\r\n * Get the expected schema for a file type.\r\n */\r\nexport function getExpectedSchema(fileType: FileType): string | undefined {\r\n switch (fileType) {\r\n case \"eval\":\r\n return SCHEMA_EVAL_V2;\r\n case \"targets\":\r\n return SCHEMA_TARGETS_V2;\r\n default:\r\n return undefined;\r\n }\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\nconst SCHEMA_EVAL_V2 = \"agentv-eval-v2\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate an eval file (agentv-eval-v2 schema).\r\n */\r\nexport async function validateEvalFile(\r\n filePath: string,\r\n): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(filePath);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: `Failed to parse YAML: ${(error as Error).message}`,\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"File must contain a YAML object\",\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate $schema field\r\n const schema = parsed[\"$schema\"];\r\n if (schema !== SCHEMA_EVAL_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_EVAL_V2}'`\r\n : `Missing required field '$schema'. Expected '${SCHEMA_EVAL_V2}'`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate evalcases array\r\n const evalcases = parsed[\"evalcases\"];\r\n if (!Array.isArray(evalcases)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"evalcases\",\r\n message: \"Missing or invalid 'evalcases' field (must be an array)\",\r\n });\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate each eval case\r\n for (let i = 0; i < evalcases.length; i++) {\r\n const evalCase = evalcases[i];\r\n const location = `evalcases[${i}]`;\r\n\r\n if (!isObject(evalCase)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"Eval case must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Required fields: id, outcome, input_messages, expected_messages\r\n const id = evalCase[\"id\"];\r\n if (typeof id !== \"string\" || id.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.id`,\r\n message: \"Missing or invalid 'id' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n const outcome = evalCase[\"outcome\"];\r\n if (typeof outcome !== \"string\" || outcome.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.outcome`,\r\n message: \"Missing or invalid 'outcome' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n const inputMessages = evalCase[\"input_messages\"];\r\n if (!Array.isArray(inputMessages)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.input_messages`,\r\n message: \"Missing or invalid 'input_messages' field (must be an array)\",\r\n });\r\n } else {\r\n validateMessages(inputMessages, `${location}.input_messages`, absolutePath, errors);\r\n }\r\n\r\n const expectedMessages = evalCase[\"expected_messages\"];\r\n if (!Array.isArray(expectedMessages)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.expected_messages`,\r\n message: \"Missing or invalid 'expected_messages' field (must be an array)\",\r\n });\r\n } else {\r\n validateMessages(expectedMessages, `${location}.expected_messages`, absolutePath, errors);\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n}\r\n\r\nfunction validateMessages(\r\n messages: JsonArray,\r\n location: string,\r\n filePath: string,\r\n errors: ValidationError[],\r\n): void {\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n const msgLocation = `${location}[${i}]`;\r\n\r\n if (!isObject(message)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: msgLocation,\r\n message: \"Message must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Validate role field\r\n const role = message[\"role\"];\r\n const validRoles = [\"system\", \"user\", \"assistant\"];\r\n if (!validRoles.includes(role as string)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${msgLocation}.role`,\r\n message: `Invalid role '${role}'. Must be one of: ${validRoles.join(\", \")}`,\r\n });\r\n }\r\n\r\n // Validate content field (can be string or array)\r\n const content = message[\"content\"];\r\n if (typeof content === \"string\") {\r\n // String content is valid\r\n } else if (Array.isArray(content)) {\r\n // Array content - validate each element\r\n for (let j = 0; j < content.length; j++) {\r\n const contentItem = content[j];\r\n const contentLocation = `${msgLocation}.content[${j}]`;\r\n\r\n if (typeof contentItem === \"string\") {\r\n // String in array is valid\r\n } else if (isObject(contentItem)) {\r\n const type = contentItem[\"type\"];\r\n if (typeof type !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${contentLocation}.type`,\r\n message: \"Content object must have a 'type' field\",\r\n });\r\n }\r\n\r\n // For 'file' type, we'll validate existence later in file-reference-validator\r\n // For 'text' type, require 'value' field\r\n if (type === \"text\") {\r\n const value = contentItem[\"value\"];\r\n if (typeof value !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${contentLocation}.value`,\r\n message: \"Content with type 'text' must have a 'value' field\",\r\n });\r\n }\r\n }\r\n } else {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: contentLocation,\r\n message: \"Content array items must be strings or objects\",\r\n });\r\n }\r\n }\r\n } else {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${msgLocation}.content`,\r\n message: \"Missing or invalid 'content' field (must be a string or array)\",\r\n });\r\n }\r\n }\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\nconst SCHEMA_TARGETS_V2 = \"agentv-targets-v2\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate a targets file (agentv-targets-v2 schema).\r\n */\r\nexport async function validateTargetsFile(\r\n filePath: string,\r\n): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(filePath);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: `Failed to parse YAML: ${(error as Error).message}`,\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"File must contain a YAML object\",\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate $schema field\r\n const schema = parsed[\"$schema\"];\r\n if (schema !== SCHEMA_TARGETS_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_TARGETS_V2}'`\r\n : `Missing required field '$schema'. Expected '${SCHEMA_TARGETS_V2}'`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate targets array\r\n const targets = parsed[\"targets\"];\r\n if (!Array.isArray(targets)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"targets\",\r\n message: \"Missing or invalid 'targets' field (must be an array)\",\r\n });\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate each target definition\r\n const knownProviders = [\"azure\", \"openai\", \"anthropic\", \"bedrock\", \"vertex\"];\r\n \r\n for (let i = 0; i < targets.length; i++) {\r\n const target = targets[i];\r\n const location = `targets[${i}]`;\r\n\r\n if (!isObject(target)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"Target must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Required field: name\r\n const name = target[\"name\"];\r\n if (typeof name !== \"string\" || name.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.name`,\r\n message: \"Missing or invalid 'name' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n // Required field: provider\r\n const provider = target[\"provider\"];\r\n if (typeof provider !== \"string\" || provider.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.provider`,\r\n message: \"Missing or invalid 'provider' field (must be a non-empty string)\",\r\n });\r\n } else if (!knownProviders.includes(provider)) {\r\n // Warning for unknown providers (non-fatal)\r\n errors.push({\r\n severity: \"warning\",\r\n filePath: absolutePath,\r\n location: `${location}.provider`,\r\n message: `Unknown provider '${provider}'. Known providers: ${knownProviders.join(\", \")}`,\r\n });\r\n }\r\n\r\n // Optional field: settings (must be object if present)\r\n const settings = target[\"settings\"];\r\n if (settings !== undefined && !isObject(settings)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.settings`,\r\n message: \"Invalid 'settings' field (must be an object)\",\r\n });\r\n }\r\n\r\n // Optional field: judge_target (must be string if present)\r\n const judgeTarget = target[\"judge_target\"];\r\n if (judgeTarget !== undefined && typeof judgeTarget !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.judge_target`,\r\n message: \"Invalid 'judge_target' field (must be a string)\",\r\n });\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.filter((e) => e.severity === \"error\").length === 0,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport { buildSearchRoots, findGitRoot, resolveFileReference } from \"../file-utils.js\";\r\nimport type { ValidationError } from \"./types.js\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate that file references in eval file content exist.\r\n * Checks content blocks with type: \"file\" and validates the referenced file exists.\r\n * Also checks that referenced files are not empty.\r\n */\r\nexport async function validateFileReferences(\r\n evalFilePath: string,\r\n): Promise<readonly ValidationError[]> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(evalFilePath);\r\n\r\n // Find git root and build search roots (same as yaml-parser does at runtime)\r\n const gitRoot = await findGitRoot(absolutePath);\r\n if (!gitRoot) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"Cannot validate file references: git repository root not found\",\r\n });\r\n return errors;\r\n }\r\n\r\n const searchRoots = buildSearchRoots(absolutePath, gitRoot);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch {\r\n // Parse errors are already caught by eval-validator\r\n return errors;\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n return errors;\r\n }\r\n\r\n const evalcases = parsed[\"evalcases\"];\r\n if (!Array.isArray(evalcases)) {\r\n return errors;\r\n }\r\n\r\n for (let i = 0; i < evalcases.length; i++) {\r\n const evalCase = evalcases[i];\r\n if (!isObject(evalCase)) {\r\n continue;\r\n }\r\n\r\n // Check input_messages\r\n const inputMessages = evalCase[\"input_messages\"];\r\n if (Array.isArray(inputMessages)) {\r\n await validateMessagesFileRefs(inputMessages, `evalcases[${i}].input_messages`, searchRoots, absolutePath, errors);\r\n }\r\n\r\n // Check expected_messages\r\n const expectedMessages = evalCase[\"expected_messages\"];\r\n if (Array.isArray(expectedMessages)) {\r\n await validateMessagesFileRefs(expectedMessages, `evalcases[${i}].expected_messages`, searchRoots, absolutePath, errors);\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\nasync function validateMessagesFileRefs(\r\n messages: JsonArray,\r\n location: string,\r\n searchRoots: readonly string[],\r\n filePath: string,\r\n errors: ValidationError[],\r\n): Promise<void> {\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n if (!isObject(message)) {\r\n continue;\r\n }\r\n\r\n const content = message[\"content\"];\r\n if (typeof content === \"string\") {\r\n continue;\r\n }\r\n\r\n if (!Array.isArray(content)) {\r\n continue;\r\n }\r\n\r\n for (let j = 0; j < content.length; j++) {\r\n const contentItem = content[j];\r\n if (!isObject(contentItem)) {\r\n continue;\r\n }\r\n\r\n const type = contentItem[\"type\"];\r\n if (type !== \"file\") {\r\n continue;\r\n }\r\n\r\n const value = contentItem[\"value\"];\r\n if (typeof value !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}].value`,\r\n message: \"File reference must have a 'value' field with the file path\",\r\n });\r\n continue;\r\n }\r\n\r\n // Use the same file resolution logic as yaml-parser at runtime\r\n const { resolvedPath } = await resolveFileReference(value, searchRoots);\r\n\r\n if (!resolvedPath) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Referenced file not found: ${value}`,\r\n });\r\n } else {\r\n // Check that file is not empty\r\n try {\r\n const fileContent = await readFile(resolvedPath, \"utf8\");\r\n if (fileContent.trim().length === 0) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Referenced file is empty: ${value}`,\r\n });\r\n }\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Cannot read referenced file: ${value} (${(error as Error).message})`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["readFile","parse","SCHEMA_EVAL_V2","readFile","path","parse","SCHEMA_TARGETS_V2","isObject","readFile","path","parse","isObject","path","readFile","parse"]}
1
+ {"version":3,"sources":["../../../src/evaluation/validation/file-type.ts","../../../src/evaluation/validation/eval-validator.ts","../../../src/evaluation/validation/targets-validator.ts","../../../src/evaluation/validation/file-reference-validator.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { FileType } from \"./types.js\";\r\n\r\nconst SCHEMA_EVAL_V2 = \"agentv-eval-v2\";\r\nconst SCHEMA_TARGETS_V2 = \"agentv-targets-v2\";\r\n\r\n/**\r\n * Detect file type by reading $schema field from YAML file.\r\n * Returns \"unknown\" if file cannot be read or $schema is missing/invalid.\r\n */\r\nexport async function detectFileType(filePath: string): Promise<FileType> {\r\n try {\r\n const content = await readFile(filePath, \"utf8\");\r\n const parsed = parse(content) as unknown;\r\n\r\n if (typeof parsed !== \"object\" || parsed === null) {\r\n return \"unknown\";\r\n }\r\n\r\n const record = parsed as Record<string, unknown>;\r\n const schema = record[\"$schema\"];\r\n\r\n if (typeof schema !== \"string\") {\r\n return \"unknown\";\r\n }\r\n\r\n switch (schema) {\r\n case SCHEMA_EVAL_V2:\r\n return \"eval\";\r\n case SCHEMA_TARGETS_V2:\r\n return \"targets\";\r\n default:\r\n return \"unknown\";\r\n }\r\n } catch {\r\n return \"unknown\";\r\n }\r\n}\r\n\r\n/**\r\n * Check if a schema value is a valid AgentV schema identifier.\r\n */\r\nexport function isValidSchema(schema: unknown): boolean {\r\n return schema === SCHEMA_EVAL_V2 || schema === SCHEMA_TARGETS_V2;\r\n}\r\n\r\n/**\r\n * Get the expected schema for a file type.\r\n */\r\nexport function getExpectedSchema(fileType: FileType): string | undefined {\r\n switch (fileType) {\r\n case \"eval\":\r\n return SCHEMA_EVAL_V2;\r\n case \"targets\":\r\n return SCHEMA_TARGETS_V2;\r\n default:\r\n return undefined;\r\n }\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\nconst SCHEMA_EVAL_V2 = \"agentv-eval-v2\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate an eval file (agentv-eval-v2 schema).\r\n */\r\nexport async function validateEvalFile(\r\n filePath: string,\r\n): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(filePath);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: `Failed to parse YAML: ${(error as Error).message}`,\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"File must contain a YAML object\",\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate $schema field\r\n const schema = parsed[\"$schema\"];\r\n if (schema !== SCHEMA_EVAL_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_EVAL_V2}'`\r\n : `Missing required field '$schema'. Expected '${SCHEMA_EVAL_V2}'`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate evalcases array\r\n const evalcases = parsed[\"evalcases\"];\r\n if (!Array.isArray(evalcases)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"evalcases\",\r\n message: \"Missing or invalid 'evalcases' field (must be an array)\",\r\n });\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate each eval case\r\n for (let i = 0; i < evalcases.length; i++) {\r\n const evalCase = evalcases[i];\r\n const location = `evalcases[${i}]`;\r\n\r\n if (!isObject(evalCase)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"Eval case must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Required fields: id, outcome, input_messages, expected_messages\r\n const id = evalCase[\"id\"];\r\n if (typeof id !== \"string\" || id.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.id`,\r\n message: \"Missing or invalid 'id' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n const outcome = evalCase[\"outcome\"];\r\n if (typeof outcome !== \"string\" || outcome.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.outcome`,\r\n message: \"Missing or invalid 'outcome' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n const inputMessages = evalCase[\"input_messages\"];\r\n if (!Array.isArray(inputMessages)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.input_messages`,\r\n message: \"Missing or invalid 'input_messages' field (must be an array)\",\r\n });\r\n } else {\r\n validateMessages(inputMessages, `${location}.input_messages`, absolutePath, errors);\r\n }\r\n\r\n const expectedMessages = evalCase[\"expected_messages\"];\r\n if (!Array.isArray(expectedMessages)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.expected_messages`,\r\n message: \"Missing or invalid 'expected_messages' field (must be an array)\",\r\n });\r\n } else {\r\n validateMessages(expectedMessages, `${location}.expected_messages`, absolutePath, errors);\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"eval\",\r\n errors,\r\n };\r\n}\r\n\r\nfunction validateMessages(\r\n messages: JsonArray,\r\n location: string,\r\n filePath: string,\r\n errors: ValidationError[],\r\n): void {\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n const msgLocation = `${location}[${i}]`;\r\n\r\n if (!isObject(message)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: msgLocation,\r\n message: \"Message must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Validate role field\r\n const role = message[\"role\"];\r\n const validRoles = [\"system\", \"user\", \"assistant\"];\r\n if (!validRoles.includes(role as string)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${msgLocation}.role`,\r\n message: `Invalid role '${role}'. Must be one of: ${validRoles.join(\", \")}`,\r\n });\r\n }\r\n\r\n // Validate content field (can be string or array)\r\n const content = message[\"content\"];\r\n if (typeof content === \"string\") {\r\n // String content is valid\r\n } else if (Array.isArray(content)) {\r\n // Array content - validate each element\r\n for (let j = 0; j < content.length; j++) {\r\n const contentItem = content[j];\r\n const contentLocation = `${msgLocation}.content[${j}]`;\r\n\r\n if (typeof contentItem === \"string\") {\r\n // String in array is valid\r\n } else if (isObject(contentItem)) {\r\n const type = contentItem[\"type\"];\r\n if (typeof type !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${contentLocation}.type`,\r\n message: \"Content object must have a 'type' field\",\r\n });\r\n }\r\n\r\n // For 'file' type, we'll validate existence later in file-reference-validator\r\n // For 'text' type, require 'value' field\r\n if (type === \"text\") {\r\n const value = contentItem[\"value\"];\r\n if (typeof value !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${contentLocation}.value`,\r\n message: \"Content with type 'text' must have a 'value' field\",\r\n });\r\n }\r\n }\r\n } else {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: contentLocation,\r\n message: \"Content array items must be strings or objects\",\r\n });\r\n }\r\n }\r\n } else {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${msgLocation}.content`,\r\n message: \"Missing or invalid 'content' field (must be a string or array)\",\r\n });\r\n }\r\n }\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport { KNOWN_PROVIDERS, PROVIDER_ALIASES, TARGETS_SCHEMA_V2 } from \"../providers/types.js\";\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate a targets file (agentv-targets-v2 schema).\r\n */\r\nexport async function validateTargetsFile(\r\n filePath: string,\r\n): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(filePath);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: `Failed to parse YAML: ${(error as Error).message}`,\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"File must contain a YAML object\",\r\n });\r\n return {\r\n valid: false,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate $schema field\r\n const schema = parsed[\"$schema\"];\r\n if (schema !== TARGETS_SCHEMA_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${TARGETS_SCHEMA_V2}'`\r\n : `Missing required field '$schema'. Expected '${TARGETS_SCHEMA_V2}'`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate targets array\r\n const targets = parsed[\"targets\"];\r\n if (!Array.isArray(targets)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: \"targets\",\r\n message: \"Missing or invalid 'targets' field (must be an array)\",\r\n });\r\n return {\r\n valid: errors.length === 0,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n }\r\n\r\n // Validate each target definition\r\n const knownProviders = [...KNOWN_PROVIDERS, ...PROVIDER_ALIASES];\r\n \r\n for (let i = 0; i < targets.length; i++) {\r\n const target = targets[i];\r\n const location = `targets[${i}]`;\r\n\r\n if (!isObject(target)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"Target must be an object\",\r\n });\r\n continue;\r\n }\r\n\r\n // Required field: name\r\n const name = target[\"name\"];\r\n if (typeof name !== \"string\" || name.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.name`,\r\n message: \"Missing or invalid 'name' field (must be a non-empty string)\",\r\n });\r\n }\r\n\r\n // Required field: provider\r\n const provider = target[\"provider\"];\r\n if (typeof provider !== \"string\" || provider.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.provider`,\r\n message: \"Missing or invalid 'provider' field (must be a non-empty string)\",\r\n });\r\n } else if (!knownProviders.includes(provider)) {\r\n // Warning for unknown providers (non-fatal)\r\n errors.push({\r\n severity: \"warning\",\r\n filePath: absolutePath,\r\n location: `${location}.provider`,\r\n message: `Unknown provider '${provider}'. Known providers: ${knownProviders.join(\", \")}`,\r\n });\r\n }\r\n\r\n // Optional field: settings (must be object if present)\r\n const settings = target[\"settings\"];\r\n if (settings !== undefined && !isObject(settings)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.settings`,\r\n message: \"Invalid 'settings' field (must be an object)\",\r\n });\r\n }\r\n\r\n // Optional field: judge_target (must be string if present)\r\n const judgeTarget = target[\"judge_target\"];\r\n if (judgeTarget !== undefined && typeof judgeTarget !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.judge_target`,\r\n message: \"Invalid 'judge_target' field (must be a string)\",\r\n });\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.filter((e) => e.severity === \"error\").length === 0,\r\n filePath: absolutePath,\r\n fileType: \"targets\",\r\n errors,\r\n };\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { parse } from \"yaml\";\r\n\r\nimport { buildSearchRoots, findGitRoot, resolveFileReference } from \"../file-utils.js\";\r\nimport type { ValidationError } from \"./types.js\";\r\n\r\ntype JsonValue = string | number | boolean | null | JsonObject | JsonArray;\r\ntype JsonObject = { readonly [key: string]: JsonValue };\r\ntype JsonArray = readonly JsonValue[];\r\n\r\nfunction isObject(value: unknown): value is JsonObject {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Validate that file references in eval file content exist.\r\n * Checks content blocks with type: \"file\" and validates the referenced file exists.\r\n * Also checks that referenced files are not empty.\r\n */\r\nexport async function validateFileReferences(\r\n evalFilePath: string,\r\n): Promise<readonly ValidationError[]> {\r\n const errors: ValidationError[] = [];\r\n const absolutePath = path.resolve(evalFilePath);\r\n\r\n // Find git root and build search roots (same as yaml-parser does at runtime)\r\n const gitRoot = await findGitRoot(absolutePath);\r\n if (!gitRoot) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n message: \"Cannot validate file references: git repository root not found\",\r\n });\r\n return errors;\r\n }\r\n\r\n const searchRoots = buildSearchRoots(absolutePath, gitRoot);\r\n\r\n let parsed: unknown;\r\n try {\r\n const content = await readFile(absolutePath, \"utf8\");\r\n parsed = parse(content);\r\n } catch {\r\n // Parse errors are already caught by eval-validator\r\n return errors;\r\n }\r\n\r\n if (!isObject(parsed)) {\r\n return errors;\r\n }\r\n\r\n const evalcases = parsed[\"evalcases\"];\r\n if (!Array.isArray(evalcases)) {\r\n return errors;\r\n }\r\n\r\n for (let i = 0; i < evalcases.length; i++) {\r\n const evalCase = evalcases[i];\r\n if (!isObject(evalCase)) {\r\n continue;\r\n }\r\n\r\n // Check input_messages\r\n const inputMessages = evalCase[\"input_messages\"];\r\n if (Array.isArray(inputMessages)) {\r\n await validateMessagesFileRefs(inputMessages, `evalcases[${i}].input_messages`, searchRoots, absolutePath, errors);\r\n }\r\n\r\n // Check expected_messages\r\n const expectedMessages = evalCase[\"expected_messages\"];\r\n if (Array.isArray(expectedMessages)) {\r\n await validateMessagesFileRefs(expectedMessages, `evalcases[${i}].expected_messages`, searchRoots, absolutePath, errors);\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\nasync function validateMessagesFileRefs(\r\n messages: JsonArray,\r\n location: string,\r\n searchRoots: readonly string[],\r\n filePath: string,\r\n errors: ValidationError[],\r\n): Promise<void> {\r\n for (let i = 0; i < messages.length; i++) {\r\n const message = messages[i];\r\n if (!isObject(message)) {\r\n continue;\r\n }\r\n\r\n const content = message[\"content\"];\r\n if (typeof content === \"string\") {\r\n continue;\r\n }\r\n\r\n if (!Array.isArray(content)) {\r\n continue;\r\n }\r\n\r\n for (let j = 0; j < content.length; j++) {\r\n const contentItem = content[j];\r\n if (!isObject(contentItem)) {\r\n continue;\r\n }\r\n\r\n const type = contentItem[\"type\"];\r\n if (type !== \"file\") {\r\n continue;\r\n }\r\n\r\n const value = contentItem[\"value\"];\r\n if (typeof value !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}].value`,\r\n message: \"File reference must have a 'value' field with the file path\",\r\n });\r\n continue;\r\n }\r\n\r\n // Use the same file resolution logic as yaml-parser at runtime\r\n const { resolvedPath } = await resolveFileReference(value, searchRoots);\r\n\r\n if (!resolvedPath) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Referenced file not found: ${value}`,\r\n });\r\n } else {\r\n // Check that file is not empty\r\n try {\r\n const fileContent = await readFile(resolvedPath, \"utf8\");\r\n if (fileContent.trim().length === 0) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Referenced file is empty: ${value}`,\r\n });\r\n }\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: `${location}[${i}].content[${j}]`,\r\n message: `Cannot read referenced file: ${value} (${(error as Error).message})`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["readFile","parse","SCHEMA_EVAL_V2","readFile","path","parse","isObject","path","readFile","parse","readFile","path","parse","isObject","path","readFile","parse"]}