@agentv/core 0.7.3 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-L6RCDZ4Z.js +641 -0
- package/dist/chunk-L6RCDZ4Z.js.map +1 -0
- package/dist/evaluation/validation/index.cjs +11 -1
- package/dist/evaluation/validation/index.cjs.map +1 -1
- package/dist/evaluation/validation/index.js +2 -2
- package/dist/evaluation/validation/index.js.map +1 -1
- package/dist/index.cjs +53 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +40 -492
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-UQLHF3T7.js +0 -158
- package/dist/chunk-UQLHF3T7.js.map +0 -1
|
@@ -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/config-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.1\";\r\nconst SCHEMA_CONFIG_V2 = \"agentv-config-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 case SCHEMA_CONFIG_V2:\r\n return \"config\";\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 || schema === SCHEMA_CONFIG_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 case \"config\":\r\n return SCHEMA_CONFIG_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\nimport { KNOWN_PROVIDERS, PROVIDER_ALIASES, TARGETS_SCHEMA_V2 } from \"../providers/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\nconst CLI_PLACEHOLDERS = new Set([\"PROMPT\", \"GUIDELINES\", \"EVAL_ID\", \"ATTEMPT\", \"FILES\"]);\r\n\r\n// Known settings properties for each provider type\r\nconst COMMON_SETTINGS = new Set([\r\n \"provider_batching\",\r\n \"providerBatching\",\r\n]);\r\n\r\nconst AZURE_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"endpoint\",\r\n \"resource\",\r\n \"resourceName\",\r\n \"api_key\",\r\n \"apiKey\",\r\n \"deployment\",\r\n \"deploymentName\",\r\n \"model\",\r\n \"version\",\r\n \"api_version\",\r\n \"temperature\",\r\n \"max_output_tokens\",\r\n \"maxTokens\",\r\n]);\r\n\r\nconst ANTHROPIC_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"api_key\",\r\n \"apiKey\",\r\n \"model\",\r\n \"deployment\",\r\n \"variant\",\r\n \"temperature\",\r\n \"max_output_tokens\",\r\n \"maxTokens\",\r\n \"thinking_budget\",\r\n \"thinkingBudget\",\r\n]);\r\n\r\nconst GEMINI_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"api_key\",\r\n \"apiKey\",\r\n \"model\",\r\n \"deployment\",\r\n \"variant\",\r\n \"temperature\",\r\n \"max_output_tokens\",\r\n \"maxTokens\",\r\n]);\r\n\r\nconst CODEX_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"executable\",\r\n \"command\",\r\n \"binary\",\r\n \"args\",\r\n \"arguments\",\r\n \"cwd\",\r\n \"timeout_seconds\",\r\n \"timeoutSeconds\",\r\n \"log_dir\",\r\n \"logDir\",\r\n \"log_directory\",\r\n \"logDirectory\",\r\n \"log_format\",\r\n \"logFormat\",\r\n \"log_output_format\",\r\n \"logOutputFormat\",\r\n]);\r\n\r\nconst VSCODE_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"workspace_template\",\r\n \"workspaceTemplate\",\r\n \"vscode_cmd\",\r\n \"command\",\r\n \"wait\",\r\n \"dry_run\",\r\n \"dryRun\",\r\n \"subagent_root\",\r\n \"subagentRoot\",\r\n]);\r\n\r\nconst MOCK_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"response\",\r\n \"delayMs\",\r\n \"delayMinMs\",\r\n \"delayMaxMs\",\r\n]);\r\n\r\nconst CLI_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"command_template\",\r\n \"commandTemplate\",\r\n \"files_format\",\r\n \"filesFormat\",\r\n \"attachments_format\",\r\n \"attachmentsFormat\",\r\n \"cwd\",\r\n \"env\",\r\n \"timeout_seconds\",\r\n \"timeoutSeconds\",\r\n \"healthcheck\",\r\n]);\r\n\r\nfunction getKnownSettings(provider: string): Set<string> | null {\r\n const normalizedProvider = provider.toLowerCase();\r\n switch (normalizedProvider) {\r\n case \"azure\":\r\n case \"azure-openai\":\r\n return AZURE_SETTINGS;\r\n case \"anthropic\":\r\n return ANTHROPIC_SETTINGS;\r\n case \"gemini\":\r\n case \"google\":\r\n case \"google-gemini\":\r\n return GEMINI_SETTINGS;\r\n case \"codex\":\r\n case \"codex-cli\":\r\n return CODEX_SETTINGS;\r\n case \"vscode\":\r\n case \"vscode-insiders\":\r\n return VSCODE_SETTINGS;\r\n case \"mock\":\r\n return MOCK_SETTINGS;\r\n case \"cli\":\r\n return CLI_SETTINGS;\r\n default:\r\n return null; // Unknown provider, can't validate settings\r\n }\r\n}\r\n\r\nfunction validateUnknownSettings(\r\n settings: JsonObject,\r\n provider: string,\r\n absolutePath: string,\r\n location: string,\r\n errors: ValidationError[],\r\n): void {\r\n const knownSettings = getKnownSettings(provider);\r\n if (!knownSettings) {\r\n // Unknown provider, skip settings validation\r\n return;\r\n }\r\n\r\n for (const key of Object.keys(settings)) {\r\n if (!knownSettings.has(key)) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath: absolutePath,\r\n location: `${location}.${key}`,\r\n message: `Unknown setting '${key}' for ${provider} provider. This property will be ignored.`,\r\n });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Validate a targets file (agentv-targets-v2.1 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\nfunction validateCliSettings(\r\n settings: unknown,\r\n absolutePath: string,\r\n location: string,\r\n errors: ValidationError[],\r\n): void {\r\n if (!isObject(settings)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"CLI provider requires a 'settings' object\",\r\n });\r\n return;\r\n }\r\n\r\n const commandTemplate = settings[\"command_template\"] ?? settings[\"commandTemplate\"];\r\n if (typeof commandTemplate !== \"string\" || commandTemplate.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.commandTemplate`,\r\n message: \"CLI provider requires 'commandTemplate' as a non-empty string\",\r\n });\r\n } else {\r\n recordUnknownPlaceholders(commandTemplate, absolutePath, `${location}.commandTemplate`, errors);\r\n }\r\n\r\n const attachmentsFormat = settings[\"attachments_format\"] ?? settings[\"attachmentsFormat\"];\r\n if (attachmentsFormat !== undefined && typeof attachmentsFormat !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.attachmentsFormat`,\r\n message: \"'attachmentsFormat' must be a string when provided\",\r\n });\r\n }\r\n\r\n const filesFormat = settings[\"files_format\"] ?? settings[\"filesFormat\"];\r\n if (filesFormat !== undefined && typeof filesFormat !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.filesFormat`,\r\n message: \"'filesFormat' must be a string when provided\",\r\n });\r\n }\r\n\r\n const cwd = settings[\"cwd\"];\r\n if (cwd !== undefined && typeof cwd !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.cwd`,\r\n message: \"'cwd' must be a string when provided\",\r\n });\r\n }\r\n\r\n const timeoutSeconds = settings[\"timeout_seconds\"] ?? settings[\"timeoutSeconds\"];\r\n if (timeoutSeconds !== undefined) {\r\n const numericTimeout = Number(timeoutSeconds);\r\n if (!Number.isFinite(numericTimeout) || numericTimeout <= 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.timeoutSeconds`,\r\n message: \"'timeoutSeconds' must be a positive number when provided\",\r\n });\r\n }\r\n }\r\n\r\n const envOverrides = settings[\"env\"];\r\n if (envOverrides !== undefined) {\r\n if (!isObject(envOverrides)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.env`,\r\n message: \"'env' must be an object with string values\",\r\n });\r\n } else {\r\n for (const [key, value] of Object.entries(envOverrides)) {\r\n if (typeof value !== \"string\" || value.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.env.${key}`,\r\n message: `Environment override '${key}' must be a non-empty string`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n const healthcheck = settings[\"healthcheck\"];\r\n if (healthcheck !== undefined) {\r\n validateCliHealthcheck(healthcheck, absolutePath, `${location}.healthcheck`, errors);\r\n }\r\n}\r\n\r\nfunction validateCliHealthcheck(\r\n healthcheck: unknown,\r\n absolutePath: string,\r\n location: string,\r\n errors: ValidationError[],\r\n): void {\r\n if (!isObject(healthcheck)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"'healthcheck' must be an object when provided\",\r\n });\r\n return;\r\n }\r\n\r\n const type = healthcheck[\"type\"];\r\n if (type !== \"http\" && type !== \"command\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.type`,\r\n message: \"healthcheck.type must be either 'http' or 'command'\",\r\n });\r\n return;\r\n }\r\n\r\n const timeoutSeconds = healthcheck[\"timeout_seconds\"] ?? healthcheck[\"timeoutSeconds\"];\r\n if (timeoutSeconds !== undefined) {\r\n const numericTimeout = Number(timeoutSeconds);\r\n if (!Number.isFinite(numericTimeout) || numericTimeout <= 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.timeoutSeconds`,\r\n message: \"healthcheck.timeoutSeconds must be a positive number when provided\",\r\n });\r\n }\r\n }\r\n\r\n if (type === \"http\") {\r\n const url = healthcheck[\"url\"];\r\n if (typeof url !== \"string\" || url.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.url`,\r\n message: \"healthcheck.url must be a non-empty string for http checks\",\r\n });\r\n }\r\n return;\r\n }\r\n\r\n const commandTemplate = healthcheck[\"command_template\"] ?? healthcheck[\"commandTemplate\"];\r\n if (typeof commandTemplate !== \"string\" || commandTemplate.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.commandTemplate`,\r\n message: \"healthcheck.commandTemplate must be a non-empty string for command checks\",\r\n });\r\n } else {\r\n recordUnknownPlaceholders(commandTemplate, absolutePath, `${location}.commandTemplate`, errors);\r\n }\r\n\r\n const cwd = healthcheck[\"cwd\"];\r\n if (cwd !== undefined && typeof cwd !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.cwd`,\r\n message: \"healthcheck.cwd must be a string when provided\",\r\n });\r\n }\r\n}\r\n\r\nfunction recordUnknownPlaceholders(\r\n template: string,\r\n absolutePath: string,\r\n location: string,\r\n errors: ValidationError[],\r\n): void {\r\n const placeholders = extractPlaceholders(template);\r\n for (const placeholder of placeholders) {\r\n if (!CLI_PLACEHOLDERS.has(placeholder)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: `Unknown CLI placeholder '{${placeholder}}'. Supported placeholders: ${Array.from(CLI_PLACEHOLDERS).join(\", \")}`,\r\n });\r\n }\r\n }\r\n}\r\n\r\nfunction extractPlaceholders(template: string): string[] {\r\n const matches = template.matchAll(/\\{([A-Z_]+)\\}/g);\r\n const result: string[] = [];\r\n for (const match of matches) {\r\n const placeholder = match[1];\r\n if (placeholder) {\r\n result.push(placeholder);\r\n }\r\n }\r\n return result;\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 const providerValue = typeof provider === \"string\" ? provider.trim().toLowerCase() : undefined;\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 (providerValue !== \"cli\" && 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 if (providerValue === \"cli\") {\r\n validateCliSettings(settings, absolutePath, `${location}.settings`, errors);\r\n }\r\n\r\n // Check for unknown settings properties\r\n if (settings !== undefined && isObject(settings) && typeof provider === \"string\") {\r\n validateUnknownSettings(settings, provider, absolutePath, `${location}.settings`, errors);\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 { parse } from \"yaml\";\r\n\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\nconst SCHEMA_CONFIG_V2 = \"agentv-config-v2\";\r\n\r\n/**\r\n * Validate a config.yaml file for schema compliance and structural correctness.\r\n */\r\nexport async function validateConfigFile(filePath: string): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n\r\n try {\r\n const content = await readFile(filePath, \"utf8\");\r\n const parsed = parse(content) as unknown;\r\n\r\n // Check if parsed content is an object\r\n if (typeof parsed !== \"object\" || parsed === null) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n message: \"Config file must contain a valid YAML object\",\r\n });\r\n return { valid: false, filePath, fileType: \"config\", errors };\r\n }\r\n\r\n const config = parsed as Record<string, unknown>;\r\n\r\n // Validate $schema field\r\n const schema = config[\"$schema\"];\r\n if (schema !== SCHEMA_CONFIG_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_CONFIG_V2}'`\r\n : `Missing required field '$schema'. Please add '$schema: ${SCHEMA_CONFIG_V2}' at the top of the file.`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate guideline_patterns if present\r\n const guidelinePatterns = config[\"guideline_patterns\"];\r\n if (guidelinePatterns !== undefined) {\r\n if (!Array.isArray(guidelinePatterns)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: \"guideline_patterns\",\r\n message: \"Field 'guideline_patterns' must be an array\",\r\n });\r\n } else if (!guidelinePatterns.every((p) => typeof p === \"string\")) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: \"guideline_patterns\",\r\n message: \"All entries in 'guideline_patterns' must be strings\",\r\n });\r\n } else if (guidelinePatterns.length === 0) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath,\r\n location: \"guideline_patterns\",\r\n message: \"Field 'guideline_patterns' is empty. Consider removing it or adding patterns.\",\r\n });\r\n }\r\n }\r\n\r\n // Check for unexpected fields\r\n const allowedFields = new Set([\"$schema\", \"guideline_patterns\"]);\r\n const unexpectedFields = Object.keys(config).filter((key) => !allowedFields.has(key));\r\n \r\n if (unexpectedFields.length > 0) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath,\r\n message: `Unexpected fields: ${unexpectedFields.join(\", \")}`,\r\n });\r\n }\r\n\r\n return {\r\n valid: errors.filter((e) => e.severity === \"error\").length === 0,\r\n filePath,\r\n fileType: \"config\",\r\n errors,\r\n };\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n message: `Failed to parse config file: ${(error as Error).message}`,\r\n });\r\n return { valid: false, filePath, fileType: \"config\", 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 type { ValidationError } from \"./types.js\";\r\nimport { buildSearchRoots, findGitRoot, resolveFileReference } from \"../file-utils.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","absolutePath","errors","readFile","parse","SCHEMA_CONFIG_V2","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/config-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.1\";\r\nconst SCHEMA_CONFIG_V2 = \"agentv-config-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 case SCHEMA_CONFIG_V2:\r\n return \"config\";\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 || schema === SCHEMA_CONFIG_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 case \"config\":\r\n return SCHEMA_CONFIG_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\nimport { KNOWN_PROVIDERS, PROVIDER_ALIASES, TARGETS_SCHEMA_V2 } from \"../providers/types.js\";\r\nimport { CLI_PLACEHOLDERS } from \"../providers/targets.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// Known settings properties for each provider type\r\nconst COMMON_SETTINGS = new Set([\r\n \"provider_batching\",\r\n \"providerBatching\",\r\n]);\r\n\r\nconst AZURE_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"endpoint\",\r\n \"resource\",\r\n \"resourceName\",\r\n \"api_key\",\r\n \"apiKey\",\r\n \"deployment\",\r\n \"deploymentName\",\r\n \"model\",\r\n \"version\",\r\n \"api_version\",\r\n \"temperature\",\r\n \"max_output_tokens\",\r\n \"maxTokens\",\r\n]);\r\n\r\nconst ANTHROPIC_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"api_key\",\r\n \"apiKey\",\r\n \"model\",\r\n \"deployment\",\r\n \"variant\",\r\n \"temperature\",\r\n \"max_output_tokens\",\r\n \"maxTokens\",\r\n \"thinking_budget\",\r\n \"thinkingBudget\",\r\n]);\r\n\r\nconst GEMINI_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"api_key\",\r\n \"apiKey\",\r\n \"model\",\r\n \"deployment\",\r\n \"variant\",\r\n \"temperature\",\r\n \"max_output_tokens\",\r\n \"maxTokens\",\r\n]);\r\n\r\nconst CODEX_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"executable\",\r\n \"command\",\r\n \"binary\",\r\n \"args\",\r\n \"arguments\",\r\n \"cwd\",\r\n \"timeout_seconds\",\r\n \"timeoutSeconds\",\r\n \"log_dir\",\r\n \"logDir\",\r\n \"log_directory\",\r\n \"logDirectory\",\r\n \"log_format\",\r\n \"logFormat\",\r\n \"log_output_format\",\r\n \"logOutputFormat\",\r\n]);\r\n\r\nconst VSCODE_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"workspace_template\",\r\n \"workspaceTemplate\",\r\n \"vscode_cmd\",\r\n \"command\",\r\n \"wait\",\r\n \"dry_run\",\r\n \"dryRun\",\r\n \"subagent_root\",\r\n \"subagentRoot\",\r\n]);\r\n\r\nconst MOCK_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"response\",\r\n \"delayMs\",\r\n \"delayMinMs\",\r\n \"delayMaxMs\",\r\n]);\r\n\r\nconst CLI_SETTINGS = new Set([\r\n ...COMMON_SETTINGS,\r\n \"command_template\",\r\n \"commandTemplate\",\r\n \"files_format\",\r\n \"filesFormat\",\r\n \"attachments_format\",\r\n \"attachmentsFormat\",\r\n \"cwd\",\r\n \"env\",\r\n \"timeout_seconds\",\r\n \"timeoutSeconds\",\r\n \"healthcheck\",\r\n]);\r\n\r\nfunction getKnownSettings(provider: string): Set<string> | null {\r\n const normalizedProvider = provider.toLowerCase();\r\n switch (normalizedProvider) {\r\n case \"azure\":\r\n case \"azure-openai\":\r\n return AZURE_SETTINGS;\r\n case \"anthropic\":\r\n return ANTHROPIC_SETTINGS;\r\n case \"gemini\":\r\n case \"google\":\r\n case \"google-gemini\":\r\n return GEMINI_SETTINGS;\r\n case \"codex\":\r\n case \"codex-cli\":\r\n return CODEX_SETTINGS;\r\n case \"vscode\":\r\n case \"vscode-insiders\":\r\n return VSCODE_SETTINGS;\r\n case \"mock\":\r\n return MOCK_SETTINGS;\r\n case \"cli\":\r\n return CLI_SETTINGS;\r\n default:\r\n return null; // Unknown provider, can't validate settings\r\n }\r\n}\r\n\r\nfunction validateUnknownSettings(\r\n settings: JsonObject,\r\n provider: string,\r\n absolutePath: string,\r\n location: string,\r\n errors: ValidationError[],\r\n): void {\r\n const knownSettings = getKnownSettings(provider);\r\n if (!knownSettings) {\r\n // Unknown provider, skip settings validation\r\n return;\r\n }\r\n\r\n for (const key of Object.keys(settings)) {\r\n if (!knownSettings.has(key)) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath: absolutePath,\r\n location: `${location}.${key}`,\r\n message: `Unknown setting '${key}' for ${provider} provider. This property will be ignored.`,\r\n });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Validate a targets file (agentv-targets-v2.1 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\nfunction validateCliSettings(\r\n settings: unknown,\r\n absolutePath: string,\r\n location: string,\r\n errors: ValidationError[],\r\n): void {\r\n if (!isObject(settings)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"CLI provider requires a 'settings' object\",\r\n });\r\n return;\r\n }\r\n\r\n const commandTemplate = settings[\"command_template\"] ?? settings[\"commandTemplate\"];\r\n if (typeof commandTemplate !== \"string\" || commandTemplate.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.commandTemplate`,\r\n message: \"CLI provider requires 'commandTemplate' as a non-empty string\",\r\n });\r\n } else {\r\n recordUnknownPlaceholders(commandTemplate, absolutePath, `${location}.commandTemplate`, errors);\r\n }\r\n\r\n const attachmentsFormat = settings[\"attachments_format\"] ?? settings[\"attachmentsFormat\"];\r\n if (attachmentsFormat !== undefined && typeof attachmentsFormat !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.attachmentsFormat`,\r\n message: \"'attachmentsFormat' must be a string when provided\",\r\n });\r\n }\r\n\r\n const filesFormat = settings[\"files_format\"] ?? settings[\"filesFormat\"];\r\n if (filesFormat !== undefined && typeof filesFormat !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.filesFormat`,\r\n message: \"'filesFormat' must be a string when provided\",\r\n });\r\n }\r\n\r\n const cwd = settings[\"cwd\"];\r\n if (cwd !== undefined && typeof cwd !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.cwd`,\r\n message: \"'cwd' must be a string when provided\",\r\n });\r\n }\r\n\r\n const timeoutSeconds = settings[\"timeout_seconds\"] ?? settings[\"timeoutSeconds\"];\r\n if (timeoutSeconds !== undefined) {\r\n const numericTimeout = Number(timeoutSeconds);\r\n if (!Number.isFinite(numericTimeout) || numericTimeout <= 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.timeoutSeconds`,\r\n message: \"'timeoutSeconds' must be a positive number when provided\",\r\n });\r\n }\r\n }\r\n\r\n const envOverrides = settings[\"env\"];\r\n if (envOverrides !== undefined) {\r\n if (!isObject(envOverrides)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.env`,\r\n message: \"'env' must be an object with string values\",\r\n });\r\n } else {\r\n for (const [key, value] of Object.entries(envOverrides)) {\r\n if (typeof value !== \"string\" || value.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.env.${key}`,\r\n message: `Environment override '${key}' must be a non-empty string`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n const healthcheck = settings[\"healthcheck\"];\r\n if (healthcheck !== undefined) {\r\n validateCliHealthcheck(healthcheck, absolutePath, `${location}.healthcheck`, errors);\r\n }\r\n}\r\n\r\nfunction validateCliHealthcheck(\r\n healthcheck: unknown,\r\n absolutePath: string,\r\n location: string,\r\n errors: ValidationError[],\r\n): void {\r\n if (!isObject(healthcheck)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: \"'healthcheck' must be an object when provided\",\r\n });\r\n return;\r\n }\r\n\r\n const type = healthcheck[\"type\"];\r\n if (type !== \"http\" && type !== \"command\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.type`,\r\n message: \"healthcheck.type must be either 'http' or 'command'\",\r\n });\r\n return;\r\n }\r\n\r\n const timeoutSeconds = healthcheck[\"timeout_seconds\"] ?? healthcheck[\"timeoutSeconds\"];\r\n if (timeoutSeconds !== undefined) {\r\n const numericTimeout = Number(timeoutSeconds);\r\n if (!Number.isFinite(numericTimeout) || numericTimeout <= 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.timeoutSeconds`,\r\n message: \"healthcheck.timeoutSeconds must be a positive number when provided\",\r\n });\r\n }\r\n }\r\n\r\n if (type === \"http\") {\r\n const url = healthcheck[\"url\"];\r\n if (typeof url !== \"string\" || url.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.url`,\r\n message: \"healthcheck.url must be a non-empty string for http checks\",\r\n });\r\n }\r\n return;\r\n }\r\n\r\n const commandTemplate = healthcheck[\"command_template\"] ?? healthcheck[\"commandTemplate\"];\r\n if (typeof commandTemplate !== \"string\" || commandTemplate.trim().length === 0) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.commandTemplate`,\r\n message: \"healthcheck.commandTemplate must be a non-empty string for command checks\",\r\n });\r\n } else {\r\n recordUnknownPlaceholders(commandTemplate, absolutePath, `${location}.commandTemplate`, errors);\r\n }\r\n\r\n const cwd = healthcheck[\"cwd\"];\r\n if (cwd !== undefined && typeof cwd !== \"string\") {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location: `${location}.cwd`,\r\n message: \"healthcheck.cwd must be a string when provided\",\r\n });\r\n }\r\n}\r\n\r\nfunction recordUnknownPlaceholders(\r\n template: string,\r\n absolutePath: string,\r\n location: string,\r\n errors: ValidationError[],\r\n): void {\r\n const placeholders = extractPlaceholders(template);\r\n for (const placeholder of placeholders) {\r\n if (!CLI_PLACEHOLDERS.has(placeholder)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath: absolutePath,\r\n location,\r\n message: `Unknown CLI placeholder '{${placeholder}}'. Supported placeholders: ${Array.from(CLI_PLACEHOLDERS).join(\", \")}`,\r\n });\r\n }\r\n }\r\n}\r\n\r\nfunction extractPlaceholders(template: string): string[] {\r\n const matches = template.matchAll(/\\{([A-Z_]+)\\}/g);\r\n const result: string[] = [];\r\n for (const match of matches) {\r\n const placeholder = match[1];\r\n if (placeholder) {\r\n result.push(placeholder);\r\n }\r\n }\r\n return result;\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 const providerValue = typeof provider === \"string\" ? provider.trim().toLowerCase() : undefined;\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 (providerValue !== \"cli\" && 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 if (providerValue === \"cli\") {\r\n validateCliSettings(settings, absolutePath, `${location}.settings`, errors);\r\n }\r\n\r\n // Check for unknown settings properties\r\n if (settings !== undefined && isObject(settings) && typeof provider === \"string\") {\r\n validateUnknownSettings(settings, provider, absolutePath, `${location}.settings`, errors);\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 { parse } from \"yaml\";\r\n\r\nimport type { ValidationError, ValidationResult } from \"./types.js\";\r\n\r\nconst SCHEMA_CONFIG_V2 = \"agentv-config-v2\";\r\n\r\n/**\r\n * Validate a config.yaml file for schema compliance and structural correctness.\r\n */\r\nexport async function validateConfigFile(filePath: string): Promise<ValidationResult> {\r\n const errors: ValidationError[] = [];\r\n\r\n try {\r\n const content = await readFile(filePath, \"utf8\");\r\n const parsed = parse(content) as unknown;\r\n\r\n // Check if parsed content is an object\r\n if (typeof parsed !== \"object\" || parsed === null) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n message: \"Config file must contain a valid YAML object\",\r\n });\r\n return { valid: false, filePath, fileType: \"config\", errors };\r\n }\r\n\r\n const config = parsed as Record<string, unknown>;\r\n\r\n // Validate $schema field\r\n const schema = config[\"$schema\"];\r\n if (schema !== SCHEMA_CONFIG_V2) {\r\n const message =\r\n typeof schema === \"string\"\r\n ? `Invalid $schema value '${schema}'. Expected '${SCHEMA_CONFIG_V2}'`\r\n : `Missing required field '$schema'. Please add '$schema: ${SCHEMA_CONFIG_V2}' at the top of the file.`;\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: \"$schema\",\r\n message,\r\n });\r\n }\r\n\r\n // Validate guideline_patterns if present\r\n const guidelinePatterns = config[\"guideline_patterns\"];\r\n if (guidelinePatterns !== undefined) {\r\n if (!Array.isArray(guidelinePatterns)) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: \"guideline_patterns\",\r\n message: \"Field 'guideline_patterns' must be an array\",\r\n });\r\n } else if (!guidelinePatterns.every((p) => typeof p === \"string\")) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n location: \"guideline_patterns\",\r\n message: \"All entries in 'guideline_patterns' must be strings\",\r\n });\r\n } else if (guidelinePatterns.length === 0) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath,\r\n location: \"guideline_patterns\",\r\n message: \"Field 'guideline_patterns' is empty. Consider removing it or adding patterns.\",\r\n });\r\n }\r\n }\r\n\r\n // Check for unexpected fields\r\n const allowedFields = new Set([\"$schema\", \"guideline_patterns\"]);\r\n const unexpectedFields = Object.keys(config).filter((key) => !allowedFields.has(key));\r\n \r\n if (unexpectedFields.length > 0) {\r\n errors.push({\r\n severity: \"warning\",\r\n filePath,\r\n message: `Unexpected fields: ${unexpectedFields.join(\", \")}`,\r\n });\r\n }\r\n\r\n return {\r\n valid: errors.filter((e) => e.severity === \"error\").length === 0,\r\n filePath,\r\n fileType: \"config\",\r\n errors,\r\n };\r\n } catch (error) {\r\n errors.push({\r\n severity: \"error\",\r\n filePath,\r\n message: `Failed to parse config file: ${(error as Error).message}`,\r\n });\r\n return { valid: false, filePath, fileType: \"config\", 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 type { ValidationError } from \"./types.js\";\r\nimport { buildSearchRoots, findGitRoot, resolveFileReference } from \"../file-utils.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","absolutePath","errors","readFile","parse","SCHEMA_CONFIG_V2","readFile","path","parse","isObject","path","readFile","parse"]}
|
package/dist/index.cjs
CHANGED
|
@@ -942,6 +942,8 @@ var GeminiProvider = class {
|
|
|
942
942
|
|
|
943
943
|
// src/evaluation/providers/cli.ts
|
|
944
944
|
var import_node_child_process = require("child_process");
|
|
945
|
+
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
946
|
+
var import_node_os = __toESM(require("os"), 1);
|
|
945
947
|
var import_node_path3 = __toESM(require("path"), 1);
|
|
946
948
|
var import_node_util = require("util");
|
|
947
949
|
var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
|
|
@@ -957,6 +959,7 @@ async function defaultCommandRunner(command, options) {
|
|
|
957
959
|
};
|
|
958
960
|
try {
|
|
959
961
|
const { stdout, stderr } = await execAsync(command, execOptions);
|
|
962
|
+
console.error(`[CLI DEBUG] SUCCESS - stdout: ${stdout.length} bytes, stderr: ${stderr.length} bytes`);
|
|
960
963
|
return {
|
|
961
964
|
stdout,
|
|
962
965
|
stderr,
|
|
@@ -967,6 +970,8 @@ async function defaultCommandRunner(command, options) {
|
|
|
967
970
|
};
|
|
968
971
|
} catch (error) {
|
|
969
972
|
const execError = error;
|
|
973
|
+
console.error(`[CLI DEBUG] ERROR - code: ${execError.code}, message: ${execError.message}`);
|
|
974
|
+
console.error(`[CLI DEBUG] stdout: ${execError.stdout?.length ?? 0} bytes, stderr: ${execError.stderr?.length ?? 0} bytes`);
|
|
970
975
|
return {
|
|
971
976
|
stdout: execError.stdout ?? "",
|
|
972
977
|
stderr: execError.stderr ?? "",
|
|
@@ -996,7 +1001,8 @@ var CliProvider = class {
|
|
|
996
1001
|
throw new Error("CLI provider request was aborted before execution");
|
|
997
1002
|
}
|
|
998
1003
|
await this.ensureHealthy(request.signal);
|
|
999
|
-
const
|
|
1004
|
+
const outputFilePath = generateOutputFilePath(request.evalCaseId);
|
|
1005
|
+
const templateValues = buildTemplateValues(request, this.config, outputFilePath);
|
|
1000
1006
|
const renderedCommand = renderTemplate(this.config.commandTemplate, templateValues);
|
|
1001
1007
|
const env = this.config.env ? { ...process.env, ...this.config.env } : process.env;
|
|
1002
1008
|
const result = await this.runCommand(renderedCommand, {
|
|
@@ -1019,16 +1025,30 @@ var CliProvider = class {
|
|
|
1019
1025
|
const message = detail ? `${detail} (exit code ${codeText})` : `CLI exited with code ${codeText}`;
|
|
1020
1026
|
throw new Error(message);
|
|
1021
1027
|
}
|
|
1028
|
+
const responseText = await this.readAndCleanupOutputFile(outputFilePath);
|
|
1022
1029
|
return {
|
|
1023
|
-
text:
|
|
1030
|
+
text: responseText,
|
|
1024
1031
|
raw: {
|
|
1025
1032
|
command: renderedCommand,
|
|
1026
1033
|
stderr: result.stderr,
|
|
1027
1034
|
exitCode: result.exitCode ?? 0,
|
|
1028
|
-
cwd: this.config.cwd
|
|
1035
|
+
cwd: this.config.cwd,
|
|
1036
|
+
outputFile: outputFilePath
|
|
1029
1037
|
}
|
|
1030
1038
|
};
|
|
1031
1039
|
}
|
|
1040
|
+
async readAndCleanupOutputFile(filePath) {
|
|
1041
|
+
try {
|
|
1042
|
+
const content = await import_promises3.default.readFile(filePath, "utf-8");
|
|
1043
|
+
return content;
|
|
1044
|
+
} catch (error) {
|
|
1045
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
1046
|
+
throw new Error(`Failed to read output file '${filePath}': ${errorMsg}`);
|
|
1047
|
+
} finally {
|
|
1048
|
+
await import_promises3.default.unlink(filePath).catch(() => {
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1032
1052
|
async ensureHealthy(signal) {
|
|
1033
1053
|
if (!this.config.healthcheck) {
|
|
1034
1054
|
return;
|
|
@@ -1069,10 +1089,11 @@ var CliProvider = class {
|
|
|
1069
1089
|
question: "",
|
|
1070
1090
|
guidelines: "",
|
|
1071
1091
|
inputFiles: [],
|
|
1072
|
-
evalCaseId: "",
|
|
1092
|
+
evalCaseId: "healthcheck",
|
|
1073
1093
|
attempt: 0
|
|
1074
1094
|
},
|
|
1075
|
-
this.config
|
|
1095
|
+
this.config,
|
|
1096
|
+
generateOutputFilePath("healthcheck")
|
|
1076
1097
|
)
|
|
1077
1098
|
);
|
|
1078
1099
|
const env = this.config.env ? { ...process.env, ...this.config.env } : process.env;
|
|
@@ -1090,14 +1111,15 @@ var CliProvider = class {
|
|
|
1090
1111
|
}
|
|
1091
1112
|
}
|
|
1092
1113
|
};
|
|
1093
|
-
function buildTemplateValues(request, config) {
|
|
1114
|
+
function buildTemplateValues(request, config, outputFilePath) {
|
|
1094
1115
|
const inputFiles = normalizeInputFiles(request.inputFiles);
|
|
1095
1116
|
return {
|
|
1096
1117
|
PROMPT: shellEscape(request.question ?? ""),
|
|
1097
1118
|
GUIDELINES: shellEscape(request.guidelines ?? ""),
|
|
1098
1119
|
EVAL_ID: shellEscape(request.evalCaseId ?? ""),
|
|
1099
1120
|
ATTEMPT: shellEscape(String(request.attempt ?? 0)),
|
|
1100
|
-
FILES: formatFileList(inputFiles, config.filesFormat)
|
|
1121
|
+
FILES: formatFileList(inputFiles, config.filesFormat),
|
|
1122
|
+
OUTPUT_FILE: shellEscape(outputFilePath)
|
|
1101
1123
|
};
|
|
1102
1124
|
}
|
|
1103
1125
|
function normalizeInputFiles(inputFiles) {
|
|
@@ -1135,11 +1157,17 @@ function shellEscape(value) {
|
|
|
1135
1157
|
return "''";
|
|
1136
1158
|
}
|
|
1137
1159
|
if (process.platform === "win32") {
|
|
1138
|
-
const escaped = value.replace(/
|
|
1139
|
-
return `
|
|
1160
|
+
const escaped = value.replace(/'/g, "''");
|
|
1161
|
+
return `'${escaped}'`;
|
|
1140
1162
|
}
|
|
1141
1163
|
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
1142
1164
|
}
|
|
1165
|
+
function generateOutputFilePath(evalCaseId) {
|
|
1166
|
+
const safeEvalId = evalCaseId || "unknown";
|
|
1167
|
+
const timestamp = Date.now();
|
|
1168
|
+
const random = Math.random().toString(36).substring(2, 9);
|
|
1169
|
+
return import_node_path3.default.join(import_node_os.default.tmpdir(), `agentv-${safeEvalId}-${timestamp}-${random}.json`);
|
|
1170
|
+
}
|
|
1143
1171
|
function formatTimeoutSuffix(timeoutMs) {
|
|
1144
1172
|
if (!timeoutMs || timeoutMs <= 0) {
|
|
1145
1173
|
return "";
|
|
@@ -1152,8 +1180,8 @@ function formatTimeoutSuffix(timeoutMs) {
|
|
|
1152
1180
|
var import_node_child_process2 = require("child_process");
|
|
1153
1181
|
var import_node_crypto = require("crypto");
|
|
1154
1182
|
var import_node_fs3 = require("fs");
|
|
1155
|
-
var
|
|
1156
|
-
var
|
|
1183
|
+
var import_promises4 = require("fs/promises");
|
|
1184
|
+
var import_node_os2 = require("os");
|
|
1157
1185
|
var import_node_path5 = __toESM(require("path"), 1);
|
|
1158
1186
|
var import_node_util2 = require("util");
|
|
1159
1187
|
|
|
@@ -1342,7 +1370,7 @@ var CodexProvider = class {
|
|
|
1342
1370
|
try {
|
|
1343
1371
|
const promptContent = buildPromptDocument(request, inputFiles);
|
|
1344
1372
|
const promptFile = import_node_path5.default.join(workspaceRoot, PROMPT_FILENAME);
|
|
1345
|
-
await (0,
|
|
1373
|
+
await (0, import_promises4.writeFile)(promptFile, promptContent, "utf8");
|
|
1346
1374
|
const args = this.buildCodexArgs();
|
|
1347
1375
|
const cwd = this.resolveCwd(workspaceRoot);
|
|
1348
1376
|
const result = await this.executeCodex(args, cwd, promptContent, request.signal, logger);
|
|
@@ -1425,11 +1453,11 @@ var CodexProvider = class {
|
|
|
1425
1453
|
}
|
|
1426
1454
|
}
|
|
1427
1455
|
async createWorkspace() {
|
|
1428
|
-
return await (0,
|
|
1456
|
+
return await (0, import_promises4.mkdtemp)(import_node_path5.default.join((0, import_node_os2.tmpdir)(), WORKSPACE_PREFIX));
|
|
1429
1457
|
}
|
|
1430
1458
|
async cleanupWorkspace(workspaceRoot) {
|
|
1431
1459
|
try {
|
|
1432
|
-
await (0,
|
|
1460
|
+
await (0, import_promises4.rm)(workspaceRoot, { recursive: true, force: true });
|
|
1433
1461
|
} catch {
|
|
1434
1462
|
}
|
|
1435
1463
|
}
|
|
@@ -1449,7 +1477,7 @@ var CodexProvider = class {
|
|
|
1449
1477
|
return void 0;
|
|
1450
1478
|
}
|
|
1451
1479
|
try {
|
|
1452
|
-
await (0,
|
|
1480
|
+
await (0, import_promises4.mkdir)(logDir, { recursive: true });
|
|
1453
1481
|
} catch (error) {
|
|
1454
1482
|
const message = error instanceof Error ? error.message : String(error);
|
|
1455
1483
|
console.warn(`Skipping Codex stream logging (could not create ${logDir}): ${message}`);
|
|
@@ -1672,7 +1700,7 @@ async function locateExecutable(candidate) {
|
|
|
1672
1700
|
if (includesPathSeparator) {
|
|
1673
1701
|
const resolved = import_node_path5.default.isAbsolute(candidate) ? candidate : import_node_path5.default.resolve(candidate);
|
|
1674
1702
|
const executablePath = await ensureWindowsExecutableVariant(resolved);
|
|
1675
|
-
await (0,
|
|
1703
|
+
await (0, import_promises4.access)(executablePath, import_node_fs3.constants.F_OK);
|
|
1676
1704
|
return executablePath;
|
|
1677
1705
|
}
|
|
1678
1706
|
const locator = process.platform === "win32" ? "where" : "which";
|
|
@@ -1682,7 +1710,7 @@ async function locateExecutable(candidate) {
|
|
|
1682
1710
|
const preferred = selectExecutableCandidate(lines);
|
|
1683
1711
|
if (preferred) {
|
|
1684
1712
|
const executablePath = await ensureWindowsExecutableVariant(preferred);
|
|
1685
|
-
await (0,
|
|
1713
|
+
await (0, import_promises4.access)(executablePath, import_node_fs3.constants.F_OK);
|
|
1686
1714
|
return executablePath;
|
|
1687
1715
|
}
|
|
1688
1716
|
} catch {
|
|
@@ -1716,7 +1744,7 @@ async function ensureWindowsExecutableVariant(candidate) {
|
|
|
1716
1744
|
for (const ext of extensions) {
|
|
1717
1745
|
const withExtension = `${candidate}${ext}`;
|
|
1718
1746
|
try {
|
|
1719
|
-
await (0,
|
|
1747
|
+
await (0, import_promises4.access)(withExtension, import_node_fs3.constants.F_OK);
|
|
1720
1748
|
return withExtension;
|
|
1721
1749
|
} catch {
|
|
1722
1750
|
}
|
|
@@ -2018,7 +2046,7 @@ var MockProvider = class {
|
|
|
2018
2046
|
|
|
2019
2047
|
// src/evaluation/providers/targets.ts
|
|
2020
2048
|
var import_zod = require("zod");
|
|
2021
|
-
var CLI_PLACEHOLDERS = /* @__PURE__ */ new Set(["PROMPT", "GUIDELINES", "EVAL_ID", "ATTEMPT", "FILES"]);
|
|
2049
|
+
var CLI_PLACEHOLDERS = /* @__PURE__ */ new Set(["PROMPT", "GUIDELINES", "EVAL_ID", "ATTEMPT", "FILES", "OUTPUT_FILE"]);
|
|
2022
2050
|
var BASE_TARGET_SCHEMA = import_zod.z.object({
|
|
2023
2051
|
name: import_zod.z.string().min(1, "target name is required"),
|
|
2024
2052
|
provider: import_zod.z.string().min(1, "provider is required"),
|
|
@@ -2745,7 +2773,7 @@ total unlocked subagents available: ${result.created.length + result.skippedExis
|
|
|
2745
2773
|
|
|
2746
2774
|
// src/evaluation/providers/targets-file.ts
|
|
2747
2775
|
var import_node_fs4 = require("fs");
|
|
2748
|
-
var
|
|
2776
|
+
var import_promises5 = require("fs/promises");
|
|
2749
2777
|
var import_node_path7 = __toESM(require("path"), 1);
|
|
2750
2778
|
var import_yaml2 = require("yaml");
|
|
2751
2779
|
|
|
@@ -2815,7 +2843,7 @@ function assertTargetDefinition(value, index, filePath) {
|
|
|
2815
2843
|
}
|
|
2816
2844
|
async function fileExists3(filePath) {
|
|
2817
2845
|
try {
|
|
2818
|
-
await (0,
|
|
2846
|
+
await (0, import_promises5.access)(filePath, import_node_fs4.constants.F_OK);
|
|
2819
2847
|
return true;
|
|
2820
2848
|
} catch {
|
|
2821
2849
|
return false;
|
|
@@ -2826,7 +2854,7 @@ async function readTargetDefinitions(filePath) {
|
|
|
2826
2854
|
if (!await fileExists3(absolutePath)) {
|
|
2827
2855
|
throw new Error(`targets.yaml not found at ${absolutePath}`);
|
|
2828
2856
|
}
|
|
2829
|
-
const raw = await (0,
|
|
2857
|
+
const raw = await (0, import_promises5.readFile)(absolutePath, "utf8");
|
|
2830
2858
|
const parsed = (0, import_yaml2.parse)(raw);
|
|
2831
2859
|
if (!isRecord(parsed)) {
|
|
2832
2860
|
throw new Error(`targets.yaml at ${absolutePath} must be a YAML object with '$schema' and 'targets' fields`);
|
|
@@ -3171,7 +3199,7 @@ function substituteVariables(template, variables) {
|
|
|
3171
3199
|
|
|
3172
3200
|
// src/evaluation/orchestrator.ts
|
|
3173
3201
|
var import_node_crypto3 = require("crypto");
|
|
3174
|
-
var
|
|
3202
|
+
var import_promises6 = require("fs/promises");
|
|
3175
3203
|
var import_node_path8 = __toESM(require("path"), 1);
|
|
3176
3204
|
|
|
3177
3205
|
// ../../node_modules/.pnpm/yocto-queue@1.2.1/node_modules/yocto-queue/index.js
|
|
@@ -3931,14 +3959,14 @@ async function dumpPrompt(directory, evalCase, promptInputs) {
|
|
|
3931
3959
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3932
3960
|
const filename = `${timestamp}_${sanitizeFilename(evalCase.id)}.json`;
|
|
3933
3961
|
const filePath = import_node_path8.default.resolve(directory, filename);
|
|
3934
|
-
await (0,
|
|
3962
|
+
await (0, import_promises6.mkdir)(import_node_path8.default.dirname(filePath), { recursive: true });
|
|
3935
3963
|
const payload = {
|
|
3936
3964
|
eval_id: evalCase.id,
|
|
3937
3965
|
question: promptInputs.question,
|
|
3938
3966
|
guidelines: promptInputs.guidelines,
|
|
3939
3967
|
guideline_paths: evalCase.guideline_paths
|
|
3940
3968
|
};
|
|
3941
|
-
await (0,
|
|
3969
|
+
await (0, import_promises6.writeFile)(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
3942
3970
|
}
|
|
3943
3971
|
function sanitizeFilename(value) {
|
|
3944
3972
|
if (!value) {
|