@vitest-evals/github-reporter 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli-options.ts","../src/report.ts","../src/utils.ts","../src/annotations.ts","../src/collect.ts","../src/summary.ts","../src/github.ts","../src/merge.ts","../src/cli.ts"],"sourcesContent":["export type CliOptions = {\n resultPatterns: string[];\n summaryPath?: string;\n summaryEnabled: boolean;\n annotations: boolean;\n checkRun: boolean;\n failOnFailures: boolean;\n failOnCheckError: boolean;\n maxAnnotations?: number;\n maxFailures?: number;\n checkRunId?: number;\n checkName?: string;\n token?: string;\n repository?: string;\n sha?: string;\n workspace?: string;\n help: boolean;\n};\n\ntype MutableCliOptions = Omit<CliOptions, \"resultPatterns\"> & {\n resultPatterns: string[];\n};\n\n/** Parses GitHub reporter CLI arguments, with explicit arguments taking precedence over environment defaults. */\nexport function parseCliArgs(\n args: string[],\n env: NodeJS.ProcessEnv = process.env,\n): CliOptions {\n const options: MutableCliOptions = {\n summaryPath: env.GITHUB_STEP_SUMMARY,\n summaryEnabled: true,\n annotations: env.GITHUB_ACTIONS === \"true\",\n checkRun: false,\n failOnFailures: false,\n failOnCheckError: false,\n resultPatterns: [],\n help: false,\n };\n\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n switch (arg) {\n case \"--json\":\n options.resultPatterns.push(readValue(args, ++index, arg));\n break;\n case \"--summary\":\n options.summaryPath = readValue(args, ++index, arg);\n options.summaryEnabled = true;\n break;\n case \"--no-summary\":\n options.summaryEnabled = false;\n break;\n case \"--annotations\":\n options.annotations = true;\n break;\n case \"--no-annotations\":\n options.annotations = false;\n break;\n case \"--check-run\":\n options.checkRun = true;\n break;\n case \"--fail-on-failures\":\n options.failOnFailures = true;\n break;\n case \"--fail-on-check-error\":\n options.failOnCheckError = true;\n break;\n case \"--max-annotations\":\n options.maxAnnotations = readInteger(args, ++index, arg);\n break;\n case \"--max-failures\":\n options.maxFailures = readInteger(args, ++index, arg);\n break;\n case \"--check-run-id\":\n options.checkRunId = readInteger(args, ++index, arg);\n options.checkRun = true;\n break;\n case \"--check-name\":\n options.checkName = readValue(args, ++index, arg);\n break;\n case \"--token\":\n options.token = readValue(args, ++index, arg);\n break;\n case \"--repo\":\n options.repository = readValue(args, ++index, arg);\n break;\n case \"--sha\":\n options.sha = readValue(args, ++index, arg);\n break;\n case \"--workspace\":\n options.workspace = readValue(args, ++index, arg);\n break;\n case \"--help\":\n case \"-h\":\n options.help = true;\n return withDefaultJsonPath(options, env);\n default:\n if (!arg.startsWith(\"-\")) {\n options.resultPatterns.push(arg);\n break;\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n }\n\n return withDefaultJsonPath(options, env);\n}\n\nfunction withDefaultJsonPath(\n options: MutableCliOptions,\n env: NodeJS.ProcessEnv,\n): CliOptions {\n return {\n ...options,\n resultPatterns:\n options.resultPatterns.length > 0\n ? options.resultPatterns\n : [env.VITEST_EVALS_JSON_REPORT || \"vitest-results.json\"],\n };\n}\n\nfunction readValue(args: string[], index: number, flag: string) {\n const value = args[index];\n if (!value) {\n throw new Error(`Missing value for ${flag}`);\n }\n return value;\n}\n\nfunction readInteger(args: string[], index: number, flag: string) {\n const rawValue = readValue(args, index, flag);\n if (!/^\\d+$/.test(rawValue)) {\n throw new Error(`Invalid integer for ${flag}`);\n }\n return Number(rawValue);\n}\n","import { appendFile } from \"node:fs/promises\";\nimport {\n readVitestJsonReportFile,\n resolveResultFiles,\n} from \"@vitest-evals/core/node\";\nimport { renderWorkflowCommands } from \"./annotations\";\nimport { collectEvalReport } from \"./collect\";\nimport { publishCheckRun, type PublishCheckRunResult } from \"./github\";\nimport { mergeEvalReports } from \"./merge\";\nimport { renderJobSummary, type SummaryOptions } from \"./summary\";\nimport type { EvalReport } from \"./types\";\n\n/** Options for reading eval JSON files and publishing GitHub report surfaces. */\nexport type PublishEvalReportOptions = SummaryOptions & {\n resultPatterns: string[];\n cwd?: string;\n workspace?: string;\n summaryEnabled?: boolean;\n summaryPath?: string;\n annotations?: boolean;\n checkRun?: boolean;\n failOnCheckError?: boolean;\n maxAnnotations?: number;\n checkRunId?: number;\n checkName?: string;\n token?: string;\n repository?: string;\n sha?: string;\n warn?: (message: string) => void;\n};\n\n/** Result from publishing eval reports, including merged report data. */\nexport type PublishEvalReportResult = {\n report: EvalReport;\n resultFiles: string[];\n checkRun?: PublishCheckRunResult;\n};\n\n/** Reads, merges, and publishes eval reports to GitHub Actions surfaces. */\nexport async function publishEvalReport(\n options: PublishEvalReportOptions,\n): Promise<PublishEvalReportResult> {\n const resultFiles = await resolveResultFiles(options.resultPatterns, {\n cwd: options.cwd,\n });\n if (resultFiles.length === 0) {\n throw new Error(\n `No eval result files matched: ${options.resultPatterns.join(\", \")}`,\n );\n }\n\n const reports = await Promise.all(\n resultFiles.map(async (resultFile) => {\n const json = await readVitestJsonReportFile(resultFile);\n return collectEvalReport(json, {\n workspace: options.workspace,\n });\n }),\n );\n const report = mergeEvalReports(reports);\n const summary = renderJobSummary(report, {\n maxFailures: options.maxFailures,\n maxOutputChars: options.maxOutputChars,\n maxReasonChars: options.maxReasonChars,\n maxToolCalls: options.maxToolCalls,\n });\n\n if (options.summaryEnabled !== false) {\n if (options.summaryPath) {\n await appendFile(options.summaryPath, `${summary}\\n`);\n } else {\n console.log(summary);\n }\n }\n\n if (options.annotations) {\n for (const command of renderWorkflowCommands(report, {\n maxAnnotations: options.maxAnnotations,\n })) {\n console.log(command);\n }\n }\n\n let checkRun: PublishCheckRunResult | undefined;\n if (options.checkRun) {\n try {\n checkRun = await publishCheckRun(report, {\n checkRunId: options.checkRunId,\n maxAnnotations: options.maxAnnotations,\n maxFailures: options.maxFailures,\n maxOutputChars: options.maxOutputChars,\n maxReasonChars: options.maxReasonChars,\n maxToolCalls: options.maxToolCalls,\n name: options.checkName,\n repository: options.repository,\n sha: options.sha,\n token: options.token,\n });\n\n if (checkRun.status === \"skipped\") {\n options.warn?.(`GitHub Check Run skipped: ${checkRun.reason}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (options.failOnCheckError) {\n throw error;\n }\n options.warn?.(message);\n }\n }\n\n return {\n report,\n resultFiles,\n checkRun,\n };\n}\n","import { posix } from \"node:path\";\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function compactLine(value: string, maxLength: number) {\n const line = value\n .split(/\\r?\\n/)\n .map((part) => part.trim())\n .find((part) => part.length > 0);\n if (!line) {\n return \"\";\n }\n return truncate(line, maxLength);\n}\n\nexport function truncate(value: string, maxLength: number) {\n if (maxLength <= 0) {\n return \"\";\n }\n if (value.length <= maxLength) {\n return value;\n }\n return `${value.slice(0, Math.max(0, maxLength - 15)).trimEnd()}... [truncated]`;\n}\n\nexport function stringifyValue(value: unknown, maxLength: number) {\n if (value === undefined) {\n return \"\";\n }\n if (typeof value === \"string\") {\n return truncate(value, maxLength);\n }\n try {\n return truncate(JSON.stringify(value, null, 2), maxLength);\n } catch {\n return truncate(String(value), maxLength);\n }\n}\n\nexport function formatNumber(value: number) {\n return new Intl.NumberFormat(\"en-US\", {\n maximumFractionDigits: 0,\n }).format(value);\n}\n\nexport function formatScore(value: number | null | undefined) {\n if (value == null || !Number.isFinite(value)) {\n return \"n/a\";\n }\n return value.toFixed(2);\n}\n\nexport function formatDuration(ms: number | undefined) {\n if (ms === undefined || !Number.isFinite(ms)) {\n return \"n/a\";\n }\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n const seconds = ms / 1000;\n if (seconds < 60) {\n return `${seconds.toFixed(seconds < 10 ? 1 : 0)}s`;\n }\n const totalSeconds = Math.round(seconds);\n const minutes = Math.floor(totalSeconds / 60);\n const remainingSeconds = totalSeconds % 60;\n return `${minutes}m ${remainingSeconds}s`;\n}\n\nexport function formatLocation(\n file: string,\n location?: { line: number; column: number },\n) {\n if (!location) {\n return file;\n }\n return `${file}:${location.line}`;\n}\n\nexport function normalizePathForGitHub(path: string, workspace?: string) {\n const normalized = path.replace(/\\\\/g, \"/\");\n if (!workspace) {\n return normalized;\n }\n\n const workspacePath = workspace.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n if (\n normalized !== workspacePath &&\n !normalized.startsWith(`${workspacePath}/`)\n ) {\n return normalized;\n }\n\n return posix.relative(workspacePath, normalized);\n}\n\nexport function escapeFence(value: string) {\n return value.replace(/```/g, \"'''\");\n}\n\nexport function escapeHtml(value: string) {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nexport function escapeCommandData(value: string) {\n return value.replace(/%/g, \"%25\").replace(/\\r/g, \"%0D\").replace(/\\n/g, \"%0A\");\n}\n\nexport function escapeCommandProperty(value: string) {\n return escapeCommandData(value).replace(/:/g, \"%3A\").replace(/,/g, \"%2C\");\n}\n","import type { EvalCase, EvalReport, ToolCallSummary } from \"./types\";\nimport {\n compactLine,\n escapeCommandData,\n escapeCommandProperty,\n formatScore,\n stringifyValue,\n truncate,\n} from \"./utils\";\n\n/** Options for limiting rendered GitHub annotations. */\nexport type AnnotationOptions = {\n maxAnnotations?: number;\n};\n\n/** GitHub Check Run annotation payload. */\nexport type CheckAnnotation = {\n path: string;\n start_line: number;\n end_line: number;\n annotation_level: \"failure\" | \"warning\" | \"notice\";\n message: string;\n title?: string;\n raw_details?: string;\n};\n\nconst DEFAULT_MAX_WORKFLOW_ANNOTATIONS = 10;\nconst DEFAULT_MAX_CHECK_ANNOTATIONS = 50;\nconst MAX_CHECK_FIELD_LENGTH = 64_000;\n\ntype AnnotatedEvalCase = EvalCase & {\n location: { line: number; column: number };\n};\n\n/** Renders GitHub workflow-command annotations for failed eval cases. */\nexport function renderWorkflowCommands(\n report: EvalReport,\n options: AnnotationOptions = {},\n) {\n const maxAnnotations =\n options.maxAnnotations ?? DEFAULT_MAX_WORKFLOW_ANNOTATIONS;\n\n return report.failures\n .filter(hasAnnotationLocation)\n .slice(0, maxAnnotations)\n .map((testCase) =>\n formatWorkflowCommand({\n command: \"error\",\n properties: {\n file: testCase.displayFile,\n line: String(testCase.location.line),\n col: String(testCase.location.column),\n title: \"vitest-evals\",\n },\n message: formatWorkflowMessage(testCase),\n }),\n );\n}\n\n/** Builds Check Run annotations for failed eval cases. */\nexport function buildCheckAnnotations(\n report: EvalReport,\n options: AnnotationOptions = {},\n): CheckAnnotation[] {\n const maxAnnotations = Math.min(\n options.maxAnnotations ?? DEFAULT_MAX_CHECK_ANNOTATIONS,\n DEFAULT_MAX_CHECK_ANNOTATIONS,\n );\n\n return report.failures\n .filter(hasAnnotationLocation)\n .slice(0, maxAnnotations)\n .map((testCase) => ({\n path: testCase.displayFile,\n start_line: testCase.location.line,\n end_line: testCase.location.line,\n annotation_level: \"failure\",\n title: truncate(\n `${testCase.primaryFailure?.judgeName ?? \"vitest-evals\"} - ${testCase.displayName}`,\n 255,\n ),\n message: truncate(\n formatWorkflowMessage(testCase),\n MAX_CHECK_FIELD_LENGTH,\n ),\n raw_details: truncate(formatRawDetails(testCase), MAX_CHECK_FIELD_LENGTH),\n }));\n}\n\nfunction hasAnnotationLocation(\n testCase: EvalCase,\n): testCase is AnnotatedEvalCase {\n return Boolean(testCase.location);\n}\n\nfunction formatWorkflowMessage(testCase: EvalCase) {\n const failure = testCase.primaryFailure;\n const parts = [\n testCase.displayName,\n `score ${formatScore(failure?.score ?? testCase.eval?.avgScore)}`,\n ];\n\n if (failure?.judgeName) {\n parts.push(failure.judgeName);\n }\n\n const reason = compactLine(failure?.reason ?? \"\", 320);\n if (reason) {\n parts.push(reason);\n }\n\n return parts.join(\" - \");\n}\n\nfunction formatRawDetails(testCase: AnnotatedEvalCase) {\n const lines = [\n `Test: ${testCase.displayName}`,\n `Location: ${testCase.displayFile}:${testCase.location.line}`,\n `Harness: ${testCase.harness?.name ?? \"n/a\"}`,\n `Score: ${formatScore(testCase.primaryFailure?.score ?? testCase.eval?.avgScore)}`,\n `Judge: ${testCase.primaryFailure?.judgeName ?? \"n/a\"}`,\n \"\",\n \"Reason:\",\n testCase.primaryFailure?.reason ?? \"n/a\",\n ];\n\n const finalOutput = testCase.eval?.output ?? testCase.harness?.output;\n if (finalOutput !== undefined) {\n lines.push(\"\", \"Final:\", stringifyValue(finalOutput, 8000));\n }\n\n if (testCase.toolCalls.length) {\n lines.push(\"\", \"Tools:\");\n for (const toolCall of testCase.toolCalls) {\n lines.push(`- ${toolCall.name}: ${formatToolCallStatus(toolCall)}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction formatToolCallStatus(toolCall: ToolCallSummary) {\n if (toolCall.status === \"pending\") {\n return \"pending\";\n }\n\n if (toolCall.status === \"error\") {\n return `error: ${toolCall.error ?? \"unknown error\"}`;\n }\n\n return \"ok\";\n}\n\nfunction formatWorkflowCommand({\n command,\n properties,\n message,\n}: {\n command: \"error\" | \"warning\" | \"notice\";\n properties: Record<string, string>;\n message: string;\n}) {\n const renderedProperties = Object.entries(properties)\n .map(([key, value]) => `${key}=${escapeCommandProperty(value)}`)\n .join(\",\");\n return `::${command} ${renderedProperties}::${escapeCommandData(message)}`;\n}\n","import {\n collectReportWorkspace,\n type HarnessRun,\n type ReportCase,\n type TranscriptToolCallEvent,\n type TranscriptToolResultEvent,\n type ToolCall,\n} from \"@vitest-evals/core\";\nimport type {\n CollectOptions,\n EvalCase,\n EvalFailure,\n EvalReport,\n EvalScore,\n ToolCallSummary,\n UsageSummary,\n VitestJsonReport,\n} from \"./types\";\nimport { compactLine, stringifyValue } from \"./utils\";\n\n/** Converts a Vitest JSON report into the compact eval report model. */\nexport function collectEvalReport(\n input: VitestJsonReport,\n options: CollectOptions = {},\n): EvalReport {\n const workspace = collectReportWorkspace(\n {\n report: input,\n },\n {\n workspace: options.workspace,\n },\n );\n const cases = workspace.cases.map(collectEvalCase);\n const failures = cases.filter((testCase) => testCase.status === \"failed\");\n const evalScores = cases\n .map((testCase) => testCase.eval?.avgScore)\n .filter((score): score is number => isFiniteNumber(score));\n const usage = sumUsage(cases);\n const durationMs = workspace.runs[0]?.durationMs;\n\n return {\n status: input.success && failures.length === 0 ? \"passed\" : \"failed\",\n startedAt: input.startTime,\n durationMs,\n totals: {\n total: input.numTotalTests,\n passed: input.numPassedTests,\n failed: input.numFailedTests,\n skipped: input.numPendingTests + input.numTodoTests,\n evalTotal: cases.length,\n evalPassed: cases.filter((testCase) => testCase.status === \"passed\")\n .length,\n evalFailed: failures.length,\n },\n score:\n evalScores.length > 0\n ? {\n average:\n evalScores.reduce((total, score) => total + score, 0) /\n evalScores.length,\n minimum: Math.min(...evalScores),\n }\n : undefined,\n usage,\n cases,\n failures,\n };\n}\n\nfunction collectEvalCase(reportCase: ReportCase): EvalCase {\n const scores = (reportCase.eval?.scores ?? []).map(normalizeScore);\n const harnessRun = reportCase.harness?.run;\n const toolCalls = collectToolCalls(reportCase);\n const evalCase: EvalCase = {\n id: reportCase.id,\n file: reportCase.file,\n displayFile: reportCase.displayFile,\n title: reportCase.title,\n displayName: reportCase.displayName,\n status: reportCase.status,\n durationMs: numberField(reportCase.durationMs),\n location: reportCase.location,\n failureMessages: reportCase.failureMessages,\n toolCalls,\n eval: reportCase.eval\n ? {\n avgScore: numberField(reportCase.eval.avgScore),\n thresholdFailed: reportCase.eval.thresholdFailed,\n output: reportCase.eval.output,\n scores,\n }\n : undefined,\n harness: reportCase.harness\n ? {\n name: reportCase.harness.name,\n output: harnessRun?.output,\n usage: harnessRun?.usage,\n timingMs: harnessRun?.timings?.totalMs,\n toolCalls,\n errors: harnessRun?.errors ?? [],\n }\n : undefined,\n };\n\n evalCase.primaryFailure = getPrimaryFailure(evalCase);\n return evalCase;\n}\n\nfunction normalizeScore(score: EvalScore): EvalScore {\n return {\n ...score,\n score: numberField(score.score) ?? null,\n };\n}\n\nfunction numberField(value: unknown) {\n return isFiniteNumber(value) ? value : undefined;\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction collectToolCalls(reportCase: ReportCase) {\n const harnessCalls = collectSessionToolCalls(\n reportCase.harness?.run?.session,\n );\n return harnessCalls.length > 0\n ? harnessCalls\n : (reportCase.eval?.toolCalls ?? []).map(toToolCallSummary);\n}\n\nfunction collectSessionToolCalls(session: HarnessRun[\"session\"] | undefined) {\n if (!session) {\n return [];\n }\n\n const resultsById = new Map<string, TranscriptToolResultEvent>();\n for (const event of session.events) {\n if (event.type === \"tool_result\" && !resultsById.has(event.toolCallId)) {\n resultsById.set(event.toolCallId, event);\n }\n }\n\n return session.events.flatMap((event) =>\n event.type === \"tool_call\"\n ? [toSessionToolCallSummary(event, resultsById.get(event.id))]\n : [],\n );\n}\n\nfunction toToolCallSummary(call: ToolCall): ToolCallSummary {\n return {\n name: call.name,\n status: call.status,\n error: call.status === \"error\" ? getToolCallError(call.error) : undefined,\n };\n}\n\nfunction toSessionToolCallSummary(\n call: TranscriptToolCallEvent,\n result: TranscriptToolResultEvent | undefined,\n): ToolCallSummary {\n if (!result) {\n return {\n name: call.name,\n status: \"pending\",\n ...(call.durationMs !== undefined ? { durationMs: call.durationMs } : {}),\n };\n }\n\n const durationMs = result.durationMs ?? call.durationMs;\n return {\n name: call.name,\n status: result.error ? \"error\" : \"ok\",\n ...(durationMs !== undefined ? { durationMs } : {}),\n ...(result.error ? { error: getToolCallError(result.error) } : {}),\n };\n}\n\nfunction getToolCallError(value: unknown) {\n const error = value as { message?: unknown };\n if (\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof error.message === \"string\"\n ) {\n return error.message;\n }\n if (value !== undefined) {\n return stringifyValue(value, 240);\n }\n return undefined;\n}\n\nfunction getPrimaryFailure(testCase: EvalCase): EvalFailure | undefined {\n const failingScores = [...(testCase.eval?.scores ?? [])]\n .filter(\n (score) =>\n (score.score ?? 0) < 1 ||\n score.metadata?.rationale !== undefined ||\n score.metadata?.output !== undefined,\n )\n .sort((left, right) => (left.score ?? 0) - (right.score ?? 0));\n const primary = failingScores[0];\n const score =\n typeof primary?.score === \"number\"\n ? primary.score\n : testCase.eval?.avgScore;\n const reason =\n stringifyReason(primary?.metadata?.rationale) ??\n compactLine(testCase.failureMessages.join(\"\\n\"), 500);\n\n if (!primary && !reason && score === undefined) {\n return undefined;\n }\n\n return {\n judgeName: primary?.name,\n score,\n reason: reason || undefined,\n };\n}\n\nfunction stringifyReason(value: unknown) {\n if (value === undefined) {\n return undefined;\n }\n return typeof value === \"string\" ? value : stringifyValue(value, 4000);\n}\n\nfunction sumUsage(cases: EvalCase[]) {\n const usage: Required<UsageSummary> = {\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n totalTokens: 0,\n toolCalls: 0,\n };\n\n for (const testCase of cases) {\n const caseUsage = testCase.harness?.usage;\n usage.inputTokens += caseUsage?.inputTokens ?? 0;\n usage.outputTokens += caseUsage?.outputTokens ?? 0;\n usage.reasoningTokens += caseUsage?.reasoningTokens ?? 0;\n usage.totalTokens +=\n caseUsage?.totalTokens ??\n (caseUsage?.inputTokens ?? 0) +\n (caseUsage?.outputTokens ?? 0) +\n (caseUsage?.reasoningTokens ?? 0);\n usage.toolCalls += toolCallCount(testCase);\n }\n\n return usage;\n}\n\nfunction toolCallCount(testCase: EvalCase) {\n const usageToolCalls = testCase.harness?.usage?.toolCalls;\n if (usageToolCalls !== undefined) {\n return Math.max(usageToolCalls, testCase.toolCalls.length);\n }\n\n return testCase.toolCalls.length;\n}\n","import type { EvalCase, EvalReport, ToolCallSummary } from \"./types\";\nimport {\n compactLine,\n escapeFence,\n escapeHtml,\n formatDuration,\n formatLocation,\n formatNumber,\n formatScore,\n stringifyValue,\n truncate,\n} from \"./utils\";\n\n/** Options for rendering GitHub Actions summary markdown. */\nexport type SummaryOptions = {\n maxFailures?: number;\n maxReasonChars?: number;\n maxOutputChars?: number;\n maxToolCalls?: number;\n};\n\nconst DEFAULT_MAX_FAILURES = 20;\nconst DEFAULT_MAX_REASON_CHARS = 8000;\nconst DEFAULT_MAX_OUTPUT_CHARS = 4000;\nconst DEFAULT_MAX_TOOL_CALLS = 20;\nconst SCORE_DISTRIBUTION_BUCKETS = [\n \"0-19%\",\n \"20-39%\",\n \"40-59%\",\n \"60-79%\",\n \"80-100%\",\n] as const;\nconst SCORE_DISTRIBUTION_BAR_WIDTH = 20;\n\n/** Renders the GitHub Actions job summary markdown for an eval report. */\nexport function renderJobSummary(\n report: EvalReport,\n options: SummaryOptions = {},\n) {\n const maxFailures = options.maxFailures ?? DEFAULT_MAX_FAILURES;\n const failures = report.failures.slice(0, maxFailures);\n const nonEvalFailures = report.totals.failed - report.totals.evalFailed;\n const lines: string[] = [\n \"# vitest-evals\",\n \"\",\n ...renderSummaryTable(report, nonEvalFailures),\n \"\",\n ...renderScoreDistribution(report),\n \"## Results\",\n \"\",\n ];\n\n if (report.failures.length > 0) {\n lines.push(\"### Failures\", \"\");\n failures.forEach((testCase, index) => {\n lines.push(...renderFailureDetails(testCase, index + 1, options), \"\");\n });\n\n if (report.failures.length > failures.length) {\n lines.push(\n `${report.failures.length - failures.length} more failures omitted from this summary.`,\n \"\",\n );\n }\n } else if (report.totals.evalTotal > 0) {\n lines.push(\"### Failures\", \"\", \"No eval failures.\", \"\");\n }\n\n if (report.totals.evalTotal === 0) {\n lines.push(\"No eval metadata was found in the Vitest JSON report.\", \"\");\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction formatCountLine(passed: number, failed: number, total: number) {\n return `${formatNumber(passed)} passed, ${formatNumber(failed)} failed, ${formatNumber(total)} total`;\n}\n\nfunction renderSummaryTable(report: EvalReport, nonEvalFailures: number) {\n const rows: Array<[string, string]> = [\n [\"Status\", report.status],\n [\n \"Evals\",\n formatCountLine(\n report.totals.evalPassed,\n report.totals.evalFailed,\n report.totals.evalTotal,\n ),\n ],\n ];\n\n if (report.score) {\n rows.push([\"Score\", formatScoreSummary(report.score)]);\n }\n\n if (nonEvalFailures > 0) {\n rows.push([\n \"Other Failures\",\n `${formatNumber(nonEvalFailures)} non-eval test failure${\n nonEvalFailures === 1 ? \"\" : \"s\"\n }`,\n ]);\n }\n\n rows.push([\"Duration\", formatDuration(report.durationMs)]);\n\n return [\n \"| Metric | Value |\",\n \"| --- | --- |\",\n ...rows.map(\n ([metric, value]) =>\n `| ${escapeTableCell(metric)} | ${escapeTableCell(value)} |`,\n ),\n ];\n}\n\nfunction formatScoreSummary(score: NonNullable<EvalReport[\"score\"]>) {\n return `avg ${formatScore(score.average)}${\n score.minimum === undefined ? \"\" : `, min ${formatScore(score.minimum)}`\n }`;\n}\n\nfunction escapeTableCell(value: string) {\n return value\n .replace(/\\r?\\n/g, \" \")\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\|/g, \"\\\\|\");\n}\n\nfunction renderScoreDistribution(report: EvalReport) {\n const scores = report.cases\n .map((testCase) => testCase.eval?.avgScore)\n .filter(\n (score): score is number =>\n typeof score === \"number\" && Number.isFinite(score),\n );\n if (scores.length === 0) {\n return [];\n }\n\n const counts = SCORE_DISTRIBUTION_BUCKETS.map(() => 0);\n for (const score of scores) {\n const bucket = Math.min(\n SCORE_DISTRIBUTION_BUCKETS.length - 1,\n Math.max(0, Math.floor(score * SCORE_DISTRIBUTION_BUCKETS.length)),\n );\n counts[bucket] = (counts[bucket] ?? 0) + 1;\n }\n\n const maxCount = Math.max(...counts);\n return [\n \"## Scores\",\n \"\",\n \"```text\",\n ...SCORE_DISTRIBUTION_BUCKETS.map((label, index) =>\n formatScoreDistributionBucket(label, counts[index] ?? 0, maxCount),\n ),\n \"```\",\n \"\",\n ];\n}\n\nfunction formatScoreDistributionBucket(\n label: string,\n count: number,\n maxCount: number,\n) {\n const barLength =\n count === 0\n ? 0\n : Math.max(\n 1,\n Math.round((count / maxCount) * SCORE_DISTRIBUTION_BAR_WIDTH),\n );\n const bar = \"#\".repeat(barLength).padEnd(SCORE_DISTRIBUTION_BAR_WIDTH, \" \");\n return `${label.padEnd(7)} | ${bar} ${formatNumber(count)}`;\n}\n\nfunction renderFailureDetails(\n testCase: EvalCase,\n number: number,\n options: SummaryOptions,\n) {\n const failure = testCase.primaryFailure;\n const maxReasonChars = options.maxReasonChars ?? DEFAULT_MAX_REASON_CHARS;\n const maxOutputChars = options.maxOutputChars ?? DEFAULT_MAX_OUTPUT_CHARS;\n const maxToolCalls = options.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS;\n const usage = formatCaseUsage(testCase);\n const finalOutput = testCase.eval?.output ?? testCase.harness?.output;\n const summary = `${number}. ${testCase.displayName} - ${\n failure?.judgeName ?? \"failure\"\n } - ${formatScore(failure?.score ?? testCase.eval?.avgScore)}`;\n const lines = [\n \"<details>\",\n `<summary>${escapeHtml(summary)}</summary>`,\n \"\",\n \"```text\",\n ...renderFailureBlock(testCase, {\n finalOutput,\n maxOutputChars,\n maxReasonChars,\n maxToolCalls,\n number,\n usage,\n }).map(escapeFence),\n \"```\",\n \"\",\n \"</details>\",\n ];\n return lines;\n}\n\nfunction renderFailureBlock(\n testCase: EvalCase,\n {\n finalOutput,\n maxOutputChars,\n maxReasonChars,\n maxToolCalls,\n number,\n usage,\n }: {\n finalOutput: unknown;\n maxOutputChars: number;\n maxReasonChars: number;\n maxToolCalls: number;\n number: number;\n usage: string;\n },\n) {\n const failure = testCase.primaryFailure;\n const overviewRows: Array<[string, string]> = [\n [\"Case\", `${number}. ${testCase.displayName}`],\n [\"Status\", testCase.status],\n [\"Location\", formatLocation(testCase.displayFile, testCase.location)],\n [\"Harness\", testCase.harness?.name ?? \"n/a\"],\n [\"Score\", formatScore(failure?.score ?? testCase.eval?.avgScore)],\n [\"Judge\", failure?.judgeName ?? \"n/a\"],\n ];\n if (usage) {\n overviewRows.push([\"Usage\", usage]);\n }\n if (testCase.durationMs !== undefined) {\n overviewRows.push([\"Duration\", formatDuration(testCase.durationMs)]);\n }\n\n const lines = [\n ...renderAsciiSection(\"Result\", renderKeyValues(overviewRows)),\n \"\",\n ];\n\n if (failure?.reason) {\n lines.push(\n ...renderAsciiSection(\n \"Reason\",\n truncate(failure.reason, maxReasonChars).split(/\\r?\\n/),\n ),\n \"\",\n );\n }\n\n if (testCase.eval?.scores.length) {\n lines.push(\n ...renderAsciiTable(\n [\"Judge\", \"Score\"],\n testCase.eval.scores.map((score) => [\n score.name ?? \"Unknown\",\n formatScore(score.score),\n ]),\n ),\n \"\",\n );\n }\n\n if (finalOutput !== undefined) {\n lines.push(\n ...renderAsciiSection(\n \"Final Output\",\n stringifyValue(finalOutput, maxOutputChars).split(/\\r?\\n/),\n ),\n \"\",\n );\n }\n\n if (testCase.toolCalls.length) {\n const toolCalls = testCase.toolCalls.slice(0, maxToolCalls);\n lines.push(\n ...renderAsciiTable(\n [\"Tool\", \"Status\", \"Duration\"],\n toolCalls.map((toolCall) => [\n toolCall.name,\n formatToolCallStatus(toolCall),\n toolCall.durationMs === undefined\n ? \"n/a\"\n : formatDuration(toolCall.durationMs),\n ]),\n ),\n );\n if (testCase.toolCalls.length > maxToolCalls) {\n lines.push(\n `${testCase.toolCalls.length - maxToolCalls} more tool calls omitted`,\n );\n }\n lines.push(\"\");\n }\n\n if (testCase.harness?.errors.length) {\n lines.push(\n ...renderAsciiSection(\n \"Harness Errors\",\n stringifyValue(testCase.harness.errors, maxReasonChars).split(/\\r?\\n/),\n ),\n \"\",\n );\n }\n\n while (lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n return lines;\n}\n\nfunction formatToolCallStatus(toolCall: ToolCallSummary) {\n if (toolCall.status === \"pending\") {\n return \"pending\";\n }\n\n if (toolCall.status === \"error\") {\n return `error: ${compactLine(toolCall.error ?? \"unknown error\", 120)}`;\n }\n\n return \"ok\";\n}\n\nfunction renderAsciiSection(title: string, content: string[]) {\n return [title, \"-\".repeat(title.length), ...content];\n}\n\nfunction renderKeyValues(rows: Array<[string, string]>) {\n const labelWidth = Math.max(...rows.map(([label]) => label.length));\n return rows.map(\n ([label, value]) =>\n `${label.padEnd(labelWidth)} ${compactLine(value, 500)}`,\n );\n}\n\nfunction renderAsciiTable(headers: string[], rows: string[][]) {\n const widths = headers.map((header, index) =>\n Math.max(header.length, ...rows.map((row) => row[index]?.length ?? 0)),\n );\n const renderRow = (row: string[]) =>\n row\n .map((cell, index) => cell.padEnd(widths[index] ?? cell.length))\n .join(\" \")\n .trimEnd();\n\n return [\n renderRow(headers),\n widths.map((width) => \"-\".repeat(width)).join(\" \"),\n ...rows.map(renderRow),\n ];\n}\n\nfunction formatCaseUsage(testCase: EvalCase) {\n const usage = testCase.harness?.usage;\n const parts: string[] = [];\n const totalTokens =\n usage?.totalTokens ??\n (usage?.inputTokens ?? 0) +\n (usage?.outputTokens ?? 0) +\n (usage?.reasoningTokens ?? 0);\n const toolCalls =\n usage?.toolCalls !== undefined\n ? Math.max(usage.toolCalls, testCase.toolCalls.length)\n : testCase.toolCalls.length;\n\n if (totalTokens > 0) {\n parts.push(`${formatNumber(totalTokens)} tokens`);\n }\n if (toolCalls > 0) {\n parts.push(`${formatNumber(toolCalls)} tool${toolCalls === 1 ? \"\" : \"s\"}`);\n }\n if (testCase.harness?.timingMs !== undefined) {\n parts.push(formatDuration(testCase.harness.timingMs));\n }\n\n return parts.join(\", \");\n}\n","import { buildCheckAnnotations } from \"./annotations\";\nimport { renderJobSummary, type SummaryOptions } from \"./summary\";\nimport type { EvalReport } from \"./types\";\n\n/** Options for creating or updating a GitHub Check Run. */\nexport type PublishCheckRunOptions = SummaryOptions & {\n token?: string;\n repository?: string;\n sha?: string;\n name?: string;\n apiUrl?: string;\n checkRunId?: number;\n maxAnnotations?: number;\n};\n\n/** Result of attempting to publish a GitHub Check Run. */\nexport type PublishCheckRunResult =\n | {\n status: \"skipped\";\n reason: string;\n }\n | {\n status: \"created\" | \"updated\";\n id?: number;\n htmlUrl?: string;\n };\n\nconst DEFAULT_CHECK_NAME = \"vitest-evals\";\nconst MAX_CHECK_SUMMARY_LENGTH = 64_000;\nconst CHECK_SUMMARY_TRUNCATION_SUFFIX =\n \"\\n\\n[truncated for GitHub Check Run]\\n\";\n\n/** Publishes the eval report to a GitHub Check Run when configuration allows it. */\nexport async function publishCheckRun(\n report: EvalReport,\n options: PublishCheckRunOptions = {},\n): Promise<PublishCheckRunResult> {\n const token = options.token ?? process.env.GITHUB_TOKEN;\n const repository = options.repository ?? process.env.GITHUB_REPOSITORY;\n const sha = options.sha ?? process.env.GITHUB_SHA;\n\n if (!token) {\n return { status: \"skipped\", reason: \"missing GITHUB_TOKEN\" };\n }\n if (!repository) {\n return { status: \"skipped\", reason: \"missing GITHUB_REPOSITORY\" };\n }\n if (!sha && options.checkRunId === undefined) {\n return { status: \"skipped\", reason: \"missing GITHUB_SHA\" };\n }\n\n const [owner, repo] = repository.split(\"/\");\n if (!owner || !repo) {\n return {\n status: \"skipped\",\n reason: `invalid GitHub repository: ${repository}`,\n };\n }\n\n const payload = buildCheckRunPayload(report, options);\n const apiUrl =\n options.apiUrl ?? process.env.GITHUB_API_URL ?? \"https://api.github.com\";\n const requestUrl =\n options.checkRunId === undefined\n ? `${apiUrl}/repos/${owner}/${repo}/check-runs`\n : `${apiUrl}/repos/${owner}/${repo}/check-runs/${options.checkRunId}`;\n const response = await fetch(requestUrl, {\n method: options.checkRunId === undefined ? \"POST\" : \"PATCH\",\n headers: {\n accept: \"application/vnd.github+json\",\n authorization: `Bearer ${token}`,\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\",\n },\n body: JSON.stringify(\n options.checkRunId === undefined\n ? {\n name: options.name ?? DEFAULT_CHECK_NAME,\n head_sha: sha,\n ...payload,\n }\n : payload,\n ),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\n `GitHub Check Run request failed: ${response.status} ${response.statusText} ${text}`.trim(),\n );\n }\n\n const data = (await response.json()) as {\n id?: number;\n html_url?: string;\n };\n\n return {\n status: options.checkRunId === undefined ? \"created\" : \"updated\",\n id: data.id,\n htmlUrl: data.html_url,\n };\n}\n\nfunction buildCheckRunPayload(\n report: EvalReport,\n options: PublishCheckRunOptions,\n) {\n const annotations = buildCheckAnnotations(report, {\n maxAnnotations: options.maxAnnotations,\n });\n const title =\n report.failures.length === 0 && report.status === \"passed\"\n ? \"No eval failures\"\n : report.failures.length === 0\n ? \"Vitest run failed\"\n : `${report.failures.length} eval failure${\n report.failures.length === 1 ? \"\" : \"s\"\n }`;\n\n return {\n status: \"completed\",\n conclusion: report.status === \"passed\" ? \"success\" : \"failure\",\n completed_at: new Date().toISOString(),\n output: {\n title,\n summary: truncateCheckSummary(\n renderJobSummary(report, {\n ...options,\n maxFailures: options.maxFailures ?? 5,\n maxReasonChars: options.maxReasonChars ?? 4000,\n maxOutputChars: options.maxOutputChars ?? 2000,\n maxToolCalls: options.maxToolCalls ?? 10,\n }),\n ),\n annotations,\n },\n };\n}\n\nfunction truncateCheckSummary(summary: string) {\n if (summary.length <= MAX_CHECK_SUMMARY_LENGTH) {\n return summary;\n }\n\n return `${summary\n .slice(0, MAX_CHECK_SUMMARY_LENGTH - CHECK_SUMMARY_TRUNCATION_SUFFIX.length)\n .trimEnd()}${CHECK_SUMMARY_TRUNCATION_SUFFIX}`;\n}\n","import type { EvalReport, UsageSummary } from \"./types\";\n\n/** Merges multiple collected eval reports into one combined report. */\nexport function mergeEvalReports(reports: EvalReport[]): EvalReport {\n const cases = reports.flatMap((report) => report.cases);\n const failures = reports.flatMap((report) => report.failures);\n const scoredCases = cases\n .map((testCase) => testCase.eval?.avgScore)\n .filter(\n (score): score is number =>\n typeof score === \"number\" && Number.isFinite(score),\n );\n const startedAtValues = reports\n .map((report) => report.startedAt)\n .filter(\n (startedAt): startedAt is number =>\n typeof startedAt === \"number\" && Number.isFinite(startedAt),\n );\n const startedAt =\n startedAtValues.length > 0 ? Math.min(...startedAtValues) : undefined;\n\n return {\n status: reports.some((report) => report.status === \"failed\")\n ? \"failed\"\n : \"passed\",\n startedAt,\n durationMs: mergeDuration(reports),\n totals: {\n total: sum(reports, (report) => report.totals.total),\n passed: sum(reports, (report) => report.totals.passed),\n failed: sum(reports, (report) => report.totals.failed),\n skipped: sum(reports, (report) => report.totals.skipped),\n evalTotal: sum(reports, (report) => report.totals.evalTotal),\n evalPassed: sum(reports, (report) => report.totals.evalPassed),\n evalFailed: sum(reports, (report) => report.totals.evalFailed),\n },\n score:\n scoredCases.length > 0\n ? {\n average:\n scoredCases.reduce((total, score) => total + score, 0) /\n scoredCases.length,\n minimum: Math.min(...scoredCases),\n }\n : undefined,\n usage: mergeUsage(reports.map((report) => report.usage)),\n cases,\n failures,\n };\n}\n\nfunction mergeUsage(usages: Array<Required<UsageSummary>>) {\n return {\n inputTokens: sum(usages, (usage) => usage.inputTokens),\n outputTokens: sum(usages, (usage) => usage.outputTokens),\n reasoningTokens: sum(usages, (usage) => usage.reasoningTokens),\n totalTokens: sum(usages, (usage) => usage.totalTokens),\n toolCalls: sum(usages, (usage) => usage.toolCalls),\n };\n}\n\nfunction mergeDuration(reports: EvalReport[]) {\n const durations = reports\n .map((report) => report.durationMs)\n .filter(\n (durationMs): durationMs is number =>\n typeof durationMs === \"number\" && Number.isFinite(durationMs),\n );\n const intervals = reports\n .map((report) => {\n if (\n typeof report.startedAt !== \"number\" ||\n !Number.isFinite(report.startedAt) ||\n typeof report.durationMs !== \"number\" ||\n !Number.isFinite(report.durationMs)\n ) {\n return undefined;\n }\n\n return {\n start: report.startedAt,\n end: report.startedAt + report.durationMs,\n };\n })\n .filter((interval): interval is { start: number; end: number } =>\n Boolean(interval),\n );\n\n if (intervals.length > 0 && intervals.length === durations.length) {\n return (\n Math.max(...intervals.map((interval) => interval.end)) -\n Math.min(...intervals.map((interval) => interval.start))\n );\n }\n\n return durations.length > 0\n ? durations.reduce((total, durationMs) => total + durationMs, 0)\n : undefined;\n}\n\nfunction sum<T>(items: T[], select: (item: T) => number) {\n return items.reduce((total, item) => total + select(item), 0);\n}\n","#!/usr/bin/env node\nimport { parseCliArgs } from \"./cli-options\";\nimport { publishEvalReport } from \"./report\";\nimport { escapeCommandData } from \"./utils\";\n\nmain().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n});\n\nasync function main() {\n const options = parseCliArgs(process.argv.slice(2));\n if (options.help) {\n console.log(usage());\n return;\n }\n\n const result = await publishEvalReport({\n resultPatterns: options.resultPatterns,\n cwd: options.workspace ?? process.env.GITHUB_WORKSPACE ?? process.cwd(),\n workspace:\n options.workspace ?? process.env.GITHUB_WORKSPACE ?? process.cwd(),\n summaryEnabled: options.summaryEnabled,\n summaryPath: options.summaryPath,\n annotations: options.annotations,\n checkRun: options.checkRun,\n checkRunId: options.checkRunId,\n checkName: options.checkName,\n failOnCheckError: options.failOnCheckError,\n maxAnnotations: options.maxAnnotations,\n maxFailures: options.maxFailures,\n repository: options.repository,\n sha: options.sha,\n token: options.token,\n warn,\n });\n\n if (options.failOnFailures && result.report.status === \"failed\") {\n process.exitCode = 1;\n }\n}\n\nfunction warn(message: string) {\n if (process.env.GITHUB_ACTIONS === \"true\") {\n console.log(`::warning::${escapeCommandData(message)}`);\n return;\n }\n console.error(`Warning: ${message}`);\n}\n\nfunction usage() {\n return [\n \"Usage: vitest-evals-github-report [vitest-results.json ...] [--json <path>]\",\n \"\",\n \"Options:\",\n \" --json <path> Read a Vitest JSON report from this path or glob\",\n \" --summary <path> Write job summary markdown to this path\",\n \" --no-summary Disable summary output\",\n \" --annotations Emit GitHub workflow-command annotations\",\n \" --no-annotations Disable workflow-command annotations\",\n \" --check-run Publish a GitHub Check Run when configured\",\n \" --fail-on-failures Exit non-zero when the combined report failed\",\n \" --fail-on-check-error Fail when Check Run publishing fails\",\n \" --check-run-id <id> Update an existing Check Run\",\n \" --check-name <name> Check Run name (default: vitest-evals)\",\n \" --token <token> GitHub token (default: GITHUB_TOKEN)\",\n \" --repo <owner/repo> GitHub repository (default: GITHUB_REPOSITORY)\",\n \" --sha <sha> Git commit SHA (default: GITHUB_SHA)\",\n \" --workspace <path> Workspace path for relative annotation files\",\n \" --max-annotations <n> Maximum annotations to emit\",\n \" --max-failures <n> Maximum failures to include in details\",\n ].join(\"\\n\");\n}\n"],"mappings":"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","names":["usage","score","usage","formatToolCallStatus","startedAt","usage"]}
1
+ {"version":3,"sources":["../src/cli-options.ts","../src/report.ts","../src/utils.ts","../src/annotations.ts","../src/collect.ts","../src/gate.ts","../src/summary.ts","../src/github.ts","../src/merge.ts","../src/cli.ts"],"sourcesContent":["export type CliOptions = {\n resultPatterns: string[];\n summaryPath?: string;\n summaryEnabled: boolean;\n annotations: boolean;\n checkRun: boolean;\n failOnFailures: boolean;\n failOnCheckError: boolean;\n minPassRate?: number;\n minScoreAverage?: number;\n maxAnnotations?: number;\n maxFailures?: number;\n checkRunId?: number;\n checkName?: string;\n token?: string;\n repository?: string;\n sha?: string;\n workspace?: string;\n help: boolean;\n};\n\ntype MutableCliOptions = Omit<CliOptions, \"resultPatterns\"> & {\n resultPatterns: string[];\n};\n\n/** Parses GitHub reporter CLI arguments, with explicit arguments taking precedence over environment defaults. */\nexport function parseCliArgs(\n args: string[],\n env: NodeJS.ProcessEnv = process.env,\n): CliOptions {\n const options: MutableCliOptions = {\n summaryPath: env.GITHUB_STEP_SUMMARY,\n summaryEnabled: true,\n annotations: env.GITHUB_ACTIONS === \"true\",\n checkRun: false,\n failOnFailures: false,\n failOnCheckError: false,\n resultPatterns: [],\n help: false,\n };\n\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n switch (arg) {\n case \"--json\":\n options.resultPatterns.push(readValue(args, ++index, arg));\n break;\n case \"--summary\":\n options.summaryPath = readValue(args, ++index, arg);\n options.summaryEnabled = true;\n break;\n case \"--no-summary\":\n options.summaryEnabled = false;\n break;\n case \"--annotations\":\n options.annotations = true;\n break;\n case \"--no-annotations\":\n options.annotations = false;\n break;\n case \"--check-run\":\n options.checkRun = true;\n break;\n case \"--fail-on-failures\":\n options.failOnFailures = true;\n break;\n case \"--fail-on-check-error\":\n options.failOnCheckError = true;\n break;\n case \"--min-pass-rate\":\n options.minPassRate = readRatio(args, ++index, arg);\n break;\n case \"--min-score-average\":\n options.minScoreAverage = readRatio(args, ++index, arg);\n break;\n case \"--max-annotations\":\n options.maxAnnotations = readInteger(args, ++index, arg);\n break;\n case \"--max-failures\":\n options.maxFailures = readInteger(args, ++index, arg);\n break;\n case \"--check-run-id\":\n options.checkRunId = readInteger(args, ++index, arg);\n options.checkRun = true;\n break;\n case \"--check-name\":\n options.checkName = readValue(args, ++index, arg);\n break;\n case \"--token\":\n options.token = readValue(args, ++index, arg);\n break;\n case \"--repo\":\n options.repository = readValue(args, ++index, arg);\n break;\n case \"--sha\":\n options.sha = readValue(args, ++index, arg);\n break;\n case \"--workspace\":\n options.workspace = readValue(args, ++index, arg);\n break;\n case \"--help\":\n case \"-h\":\n options.help = true;\n return withDefaultJsonPath(options, env);\n default:\n if (!arg.startsWith(\"-\")) {\n options.resultPatterns.push(arg);\n break;\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n }\n\n return withDefaultJsonPath(options, env);\n}\n\nfunction withDefaultJsonPath(\n options: MutableCliOptions,\n env: NodeJS.ProcessEnv,\n): CliOptions {\n return {\n ...options,\n resultPatterns:\n options.resultPatterns.length > 0\n ? options.resultPatterns\n : [env.VITEST_EVALS_JSON_REPORT || \"vitest-results.json\"],\n };\n}\n\nfunction readValue(args: string[], index: number, flag: string) {\n const value = args[index];\n if (!value) {\n throw new Error(`Missing value for ${flag}`);\n }\n return value;\n}\n\nfunction readInteger(args: string[], index: number, flag: string) {\n const rawValue = readValue(args, index, flag);\n if (!/^\\d+$/.test(rawValue)) {\n throw new Error(`Invalid integer for ${flag}`);\n }\n return Number(rawValue);\n}\n\nfunction readRatio(args: string[], index: number, flag: string) {\n const rawValue = readValue(args, index, flag);\n const parsed = Number(rawValue);\n if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {\n throw new Error(`Invalid ratio for ${flag}`);\n }\n return parsed;\n}\n","import { appendFile } from \"node:fs/promises\";\nimport {\n readVitestJsonReportFile,\n resolveResultFiles,\n} from \"@vitest-evals/core/node\";\nimport { renderWorkflowCommands } from \"./annotations\";\nimport { collectEvalReport } from \"./collect\";\nimport {\n type EvalGatePolicy,\n type EvalGateResult,\n evaluateEvalGate,\n renderGateWorkflowCommand,\n} from \"./gate\";\nimport { type PublishCheckRunResult, publishCheckRun } from \"./github\";\nimport { mergeEvalReports } from \"./merge\";\nimport { type SummaryOptions, renderJobSummary } from \"./summary\";\nimport type { EvalReport } from \"./types\";\n\n/** Options for reading eval JSON files and publishing GitHub report surfaces. */\nexport type PublishEvalReportOptions = SummaryOptions &\n EvalGatePolicy & {\n resultPatterns: string[];\n cwd?: string;\n workspace?: string;\n summaryEnabled?: boolean;\n summaryPath?: string;\n annotations?: boolean;\n checkRun?: boolean;\n failOnCheckError?: boolean;\n maxAnnotations?: number;\n checkRunId?: number;\n checkName?: string;\n token?: string;\n repository?: string;\n sha?: string;\n warn?: (message: string) => void;\n };\n\n/** Result from publishing eval reports, including merged report data. */\nexport type PublishEvalReportResult = {\n report: EvalReport;\n resultFiles: string[];\n gate: EvalGateResult;\n /**\n * True when an enforced gate rejects the report. Advisory (ungated) runs\n * never fail the step, matching `fail-on-failures: false` defaults.\n */\n shouldFail: boolean;\n checkRun?: PublishCheckRunResult;\n};\n\n/** Reads, merges, and publishes eval reports to GitHub Actions surfaces. */\nexport async function publishEvalReport(\n options: PublishEvalReportOptions,\n): Promise<PublishEvalReportResult> {\n const resultFiles = await resolveResultFiles(options.resultPatterns, {\n cwd: options.cwd,\n });\n if (resultFiles.length === 0) {\n throw new Error(\n `No eval result files matched: ${options.resultPatterns.join(\", \")}`,\n );\n }\n\n const reports = await Promise.all(\n resultFiles.map(async (resultFile) => {\n const json = await readVitestJsonReportFile(resultFile);\n return collectEvalReport(json, {\n workspace: options.workspace,\n });\n }),\n );\n const report = mergeEvalReports(reports);\n const gate = evaluateEvalGate(report, {\n failOnFailures: options.failOnFailures,\n minPassRate: options.minPassRate,\n minScoreAverage: options.minScoreAverage,\n });\n const summary = renderJobSummary(report, {\n maxFailures: options.maxFailures,\n maxOutputChars: options.maxOutputChars,\n maxReasonChars: options.maxReasonChars,\n maxToolCalls: options.maxToolCalls,\n gate,\n });\n\n if (options.summaryEnabled !== false) {\n if (options.summaryPath) {\n await appendFile(options.summaryPath, `${summary}\\n`);\n } else {\n console.log(summary);\n }\n }\n\n if (options.annotations) {\n const gateCommand = renderGateWorkflowCommand(gate);\n if (gateCommand) {\n console.log(gateCommand);\n }\n for (const command of renderWorkflowCommands(report, {\n maxAnnotations: options.maxAnnotations,\n gate,\n })) {\n console.log(command);\n }\n }\n\n let checkRun: PublishCheckRunResult | undefined;\n if (options.checkRun) {\n try {\n checkRun = await publishCheckRun(report, {\n checkRunId: options.checkRunId,\n maxAnnotations: options.maxAnnotations,\n maxFailures: options.maxFailures,\n maxOutputChars: options.maxOutputChars,\n maxReasonChars: options.maxReasonChars,\n maxToolCalls: options.maxToolCalls,\n name: options.checkName,\n repository: options.repository,\n sha: options.sha,\n token: options.token,\n gate,\n });\n\n if (checkRun.status === \"skipped\") {\n options.warn?.(`GitHub Check Run skipped: ${checkRun.reason}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (options.failOnCheckError) {\n throw error;\n }\n options.warn?.(message);\n }\n }\n\n return {\n report,\n resultFiles,\n gate,\n shouldFail: gate.enforced && !gate.ok,\n checkRun,\n };\n}\n","import { posix } from \"node:path\";\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function compactLine(value: string, maxLength: number) {\n const line = value\n .split(/\\r?\\n/)\n .map((part) => part.trim())\n .find((part) => part.length > 0);\n if (!line) {\n return \"\";\n }\n return truncate(line, maxLength);\n}\n\nexport function truncate(value: string, maxLength: number) {\n if (maxLength <= 0) {\n return \"\";\n }\n if (value.length <= maxLength) {\n return value;\n }\n return `${value.slice(0, Math.max(0, maxLength - 15)).trimEnd()}... [truncated]`;\n}\n\nexport function stringifyValue(value: unknown, maxLength: number) {\n if (value === undefined) {\n return \"\";\n }\n if (typeof value === \"string\") {\n return truncate(value, maxLength);\n }\n try {\n return truncate(JSON.stringify(value, null, 2), maxLength);\n } catch {\n return truncate(String(value), maxLength);\n }\n}\n\nexport function formatNumber(value: number) {\n return new Intl.NumberFormat(\"en-US\", {\n maximumFractionDigits: 0,\n }).format(value);\n}\n\nexport function formatScore(value: number | null | undefined) {\n if (value == null || !Number.isFinite(value)) {\n return \"n/a\";\n }\n return value.toFixed(2);\n}\n\nexport function formatDuration(ms: number | undefined) {\n if (ms === undefined || !Number.isFinite(ms)) {\n return \"n/a\";\n }\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n const seconds = ms / 1000;\n if (seconds < 60) {\n return `${seconds.toFixed(seconds < 10 ? 1 : 0)}s`;\n }\n const totalSeconds = Math.round(seconds);\n const minutes = Math.floor(totalSeconds / 60);\n const remainingSeconds = totalSeconds % 60;\n return `${minutes}m ${remainingSeconds}s`;\n}\n\nexport function formatLocation(\n file: string,\n location?: { line: number; column: number },\n) {\n if (!location) {\n return file;\n }\n return `${file}:${location.line}`;\n}\n\nexport function normalizePathForGitHub(path: string, workspace?: string) {\n const normalized = path.replace(/\\\\/g, \"/\");\n if (!workspace) {\n return normalized;\n }\n\n const workspacePath = workspace.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n if (\n normalized !== workspacePath &&\n !normalized.startsWith(`${workspacePath}/`)\n ) {\n return normalized;\n }\n\n return posix.relative(workspacePath, normalized);\n}\n\nexport function escapeFence(value: string) {\n return value.replace(/```/g, \"'''\");\n}\n\nexport function escapeHtml(value: string) {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nexport function escapeCommandData(value: string) {\n return value.replace(/%/g, \"%25\").replace(/\\r/g, \"%0D\").replace(/\\n/g, \"%0A\");\n}\n\nexport function escapeCommandProperty(value: string) {\n return escapeCommandData(value).replace(/:/g, \"%3A\").replace(/,/g, \"%2C\");\n}\n","import type { EvalGateResult } from \"./gate\";\nimport type { EvalCase, EvalReport, ToolCallSummary } from \"./types\";\nimport {\n compactLine,\n escapeCommandData,\n escapeCommandProperty,\n formatScore,\n stringifyValue,\n truncate,\n} from \"./utils\";\n\n/** Options for limiting rendered GitHub annotations. */\nexport type AnnotationOptions = {\n maxAnnotations?: number;\n /**\n * Suite gate decision. When the gate passed, quality misses are demoted to\n * warnings so a green score-gated check is not flooded with red failures.\n */\n gate?: EvalGateResult;\n};\n\n/** GitHub Check Run annotation payload. */\nexport type CheckAnnotation = {\n path: string;\n start_line: number;\n end_line: number;\n annotation_level: \"failure\" | \"warning\" | \"notice\";\n message: string;\n title?: string;\n raw_details?: string;\n};\n\nconst DEFAULT_MAX_WORKFLOW_ANNOTATIONS = 10;\nconst DEFAULT_MAX_CHECK_ANNOTATIONS = 50;\nconst MAX_CHECK_FIELD_LENGTH = 64_000;\n\ntype AnnotatedEvalCase = EvalCase & {\n location: { line: number; column: number };\n};\n\n/** Renders GitHub workflow-command annotations for failed eval cases. */\nexport function renderWorkflowCommands(\n report: EvalReport,\n options: AnnotationOptions = {},\n) {\n const maxAnnotations =\n options.maxAnnotations ?? DEFAULT_MAX_WORKFLOW_ANNOTATIONS;\n const command = caseAnnotationCommand(options.gate);\n\n return report.failures\n .filter(hasAnnotationLocation)\n .slice(0, maxAnnotations)\n .map((testCase) =>\n formatWorkflowCommand({\n command,\n properties: {\n file: testCase.displayFile,\n line: String(testCase.location.line),\n col: String(testCase.location.column),\n title: \"vitest-evals\",\n },\n message: formatWorkflowMessage(testCase),\n }),\n );\n}\n\n/** Builds Check Run annotations for failed eval cases. */\nexport function buildCheckAnnotations(\n report: EvalReport,\n options: AnnotationOptions = {},\n): CheckAnnotation[] {\n const maxAnnotations = Math.min(\n options.maxAnnotations ?? DEFAULT_MAX_CHECK_ANNOTATIONS,\n DEFAULT_MAX_CHECK_ANNOTATIONS,\n );\n const annotationLevel = caseAnnotationLevel(options.gate);\n\n return report.failures\n .filter(hasAnnotationLocation)\n .slice(0, maxAnnotations)\n .map((testCase) => ({\n path: testCase.displayFile,\n start_line: testCase.location.line,\n end_line: testCase.location.line,\n annotation_level: annotationLevel,\n title: truncate(\n `${testCase.primaryFailure?.judgeName ?? \"vitest-evals\"} - ${testCase.displayName}`,\n 255,\n ),\n message: truncate(\n formatWorkflowMessage(testCase),\n MAX_CHECK_FIELD_LENGTH,\n ),\n raw_details: truncate(formatRawDetails(testCase), MAX_CHECK_FIELD_LENGTH),\n }));\n}\n\nfunction caseAnnotationCommand(\n gate: EvalGateResult | undefined,\n): \"error\" | \"warning\" {\n return gate?.ok ? \"warning\" : \"error\";\n}\n\nfunction caseAnnotationLevel(\n gate: EvalGateResult | undefined,\n): \"failure\" | \"warning\" {\n return gate?.ok ? \"warning\" : \"failure\";\n}\n\nfunction hasAnnotationLocation(\n testCase: EvalCase,\n): testCase is AnnotatedEvalCase {\n return Boolean(testCase.location);\n}\n\nfunction formatWorkflowMessage(testCase: EvalCase) {\n const failure = testCase.primaryFailure;\n const parts = [\n testCase.displayName,\n `score ${formatScore(failure?.score ?? testCase.eval?.avgScore)}`,\n ];\n\n if (failure?.judgeName) {\n parts.push(failure.judgeName);\n }\n\n const reason = compactLine(failure?.reason ?? \"\", 320);\n if (reason) {\n parts.push(reason);\n }\n\n return parts.join(\" - \");\n}\n\nfunction formatRawDetails(testCase: AnnotatedEvalCase) {\n const lines = [\n `Test: ${testCase.displayName}`,\n `Location: ${testCase.displayFile}:${testCase.location.line}`,\n `Harness: ${testCase.harness?.name ?? \"n/a\"}`,\n `Score: ${formatScore(testCase.primaryFailure?.score ?? testCase.eval?.avgScore)}`,\n `Judge: ${testCase.primaryFailure?.judgeName ?? \"n/a\"}`,\n \"\",\n \"Reason:\",\n testCase.primaryFailure?.reason ?? \"n/a\",\n ];\n\n const finalOutput = testCase.eval?.output ?? testCase.harness?.output;\n if (finalOutput !== undefined) {\n lines.push(\"\", \"Final:\", stringifyValue(finalOutput, 8000));\n }\n\n if (testCase.toolCalls.length) {\n lines.push(\"\", \"Tools:\");\n for (const toolCall of testCase.toolCalls) {\n lines.push(`- ${toolCall.name}: ${formatToolCallStatus(toolCall)}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction formatToolCallStatus(toolCall: ToolCallSummary) {\n if (toolCall.status === \"pending\") {\n return \"pending\";\n }\n\n if (toolCall.status === \"error\") {\n return `error: ${toolCall.error ?? \"unknown error\"}`;\n }\n\n return \"ok\";\n}\n\nfunction formatWorkflowCommand({\n command,\n properties,\n message,\n}: {\n command: \"error\" | \"warning\" | \"notice\";\n properties: Record<string, string>;\n message: string;\n}) {\n const renderedProperties = Object.entries(properties)\n .map(([key, value]) => `${key}=${escapeCommandProperty(value)}`)\n .join(\",\");\n return `::${command} ${renderedProperties}::${escapeCommandData(message)}`;\n}\n","import {\n type HarnessRun,\n type ReportCase,\n type ToolCall,\n type TranscriptToolCallEvent,\n type TranscriptToolResultEvent,\n collectReportWorkspace,\n} from \"@vitest-evals/core\";\nimport type {\n CollectOptions,\n EvalCase,\n EvalFailure,\n EvalReport,\n EvalScore,\n ToolCallSummary,\n UsageSummary,\n VitestJsonReport,\n} from \"./types\";\nimport { compactLine, stringifyValue } from \"./utils\";\n\n/** Converts a Vitest JSON report into the compact eval report model. */\nexport function collectEvalReport(\n input: VitestJsonReport,\n options: CollectOptions = {},\n): EvalReport {\n const workspace = collectReportWorkspace(\n {\n report: input,\n },\n {\n workspace: options.workspace,\n },\n );\n const cases = workspace.cases.map(collectEvalCase);\n const failures = cases.filter((testCase) => testCase.status === \"failed\");\n const evalScores = cases\n .map((testCase) => testCase.eval?.avgScore)\n .filter((score): score is number => isFiniteNumber(score));\n const usage = sumUsage(cases);\n const durationMs = workspace.runs[0]?.durationMs;\n\n return {\n status: input.success && failures.length === 0 ? \"passed\" : \"failed\",\n startedAt: input.startTime,\n durationMs,\n totals: {\n total: input.numTotalTests,\n passed: input.numPassedTests,\n failed: input.numFailedTests,\n skipped: input.numPendingTests + input.numTodoTests,\n evalTotal: cases.length,\n evalPassed: cases.filter((testCase) => testCase.status === \"passed\")\n .length,\n evalFailed: failures.length,\n },\n score:\n evalScores.length > 0\n ? {\n average:\n evalScores.reduce((total, score) => total + score, 0) /\n evalScores.length,\n minimum: Math.min(...evalScores),\n }\n : undefined,\n usage,\n cases,\n failures,\n };\n}\n\nfunction collectEvalCase(reportCase: ReportCase): EvalCase {\n const scores = (reportCase.eval?.scores ?? []).map(normalizeScore);\n const harnessRun = reportCase.harness?.run;\n const toolCalls = collectToolCalls(reportCase);\n const evalCase: EvalCase = {\n id: reportCase.id,\n file: reportCase.file,\n displayFile: reportCase.displayFile,\n title: reportCase.title,\n displayName: reportCase.displayName,\n status: reportCase.status,\n durationMs: numberField(reportCase.durationMs),\n location: reportCase.location,\n failureMessages: reportCase.failureMessages,\n toolCalls,\n eval: reportCase.eval\n ? {\n avgScore: numberField(reportCase.eval.avgScore),\n thresholdFailed: reportCase.eval.thresholdFailed,\n output: reportCase.eval.output,\n scores,\n }\n : undefined,\n harness: reportCase.harness\n ? {\n name: reportCase.harness.name,\n output: harnessRun?.output,\n usage: harnessRun?.usage,\n timingMs: harnessRun?.timings?.totalMs,\n toolCalls,\n errors: harnessRun?.errors ?? [],\n }\n : undefined,\n };\n\n evalCase.primaryFailure = getPrimaryFailure(evalCase);\n return evalCase;\n}\n\nfunction normalizeScore(score: EvalScore): EvalScore {\n return {\n ...score,\n score: numberField(score.score) ?? null,\n };\n}\n\nfunction numberField(value: unknown) {\n return isFiniteNumber(value) ? value : undefined;\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction collectToolCalls(reportCase: ReportCase) {\n const harnessCalls = collectSessionToolCalls(\n reportCase.harness?.run?.session,\n );\n return harnessCalls.length > 0\n ? harnessCalls\n : (reportCase.eval?.toolCalls ?? []).map(toToolCallSummary);\n}\n\nfunction collectSessionToolCalls(session: HarnessRun[\"session\"] | undefined) {\n if (!session) {\n return [];\n }\n\n const resultsById = new Map<string, TranscriptToolResultEvent>();\n for (const event of session.events) {\n if (event.type === \"tool_result\" && !resultsById.has(event.toolCallId)) {\n resultsById.set(event.toolCallId, event);\n }\n }\n\n return session.events.flatMap((event) =>\n event.type === \"tool_call\"\n ? [toSessionToolCallSummary(event, resultsById.get(event.id))]\n : [],\n );\n}\n\nfunction toToolCallSummary(call: ToolCall): ToolCallSummary {\n return {\n name: call.name,\n status: call.status,\n error: call.status === \"error\" ? getToolCallError(call.error) : undefined,\n };\n}\n\nfunction toSessionToolCallSummary(\n call: TranscriptToolCallEvent,\n result: TranscriptToolResultEvent | undefined,\n): ToolCallSummary {\n if (!result) {\n return {\n name: call.name,\n status: \"pending\",\n ...(call.durationMs !== undefined ? { durationMs: call.durationMs } : {}),\n };\n }\n\n const durationMs = result.durationMs ?? call.durationMs;\n return {\n name: call.name,\n status: result.error ? \"error\" : \"ok\",\n ...(durationMs !== undefined ? { durationMs } : {}),\n ...(result.error ? { error: getToolCallError(result.error) } : {}),\n };\n}\n\nfunction getToolCallError(value: unknown) {\n const error = value as { message?: unknown };\n if (\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof error.message === \"string\"\n ) {\n return error.message;\n }\n if (value !== undefined) {\n return stringifyValue(value, 240);\n }\n return undefined;\n}\n\nfunction getPrimaryFailure(testCase: EvalCase): EvalFailure | undefined {\n const failingScores = [...(testCase.eval?.scores ?? [])]\n .filter(\n (score) =>\n (score.score ?? 0) < 1 ||\n score.metadata?.rationale !== undefined ||\n score.metadata?.output !== undefined,\n )\n .sort((left, right) => (left.score ?? 0) - (right.score ?? 0));\n const primary = failingScores[0];\n const score =\n typeof primary?.score === \"number\"\n ? primary.score\n : testCase.eval?.avgScore;\n const reason =\n stringifyReason(primary?.metadata?.rationale) ??\n compactLine(testCase.failureMessages.join(\"\\n\"), 500);\n\n if (!primary && !reason && score === undefined) {\n return undefined;\n }\n\n return {\n judgeName: primary?.name,\n score,\n reason: reason || undefined,\n };\n}\n\nfunction stringifyReason(value: unknown) {\n if (value === undefined) {\n return undefined;\n }\n return typeof value === \"string\" ? value : stringifyValue(value, 4000);\n}\n\nfunction sumUsage(cases: EvalCase[]) {\n const usage: Required<UsageSummary> = {\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n totalTokens: 0,\n toolCalls: 0,\n };\n\n for (const testCase of cases) {\n const caseUsage = testCase.harness?.usage;\n usage.inputTokens += caseUsage?.inputTokens ?? 0;\n usage.outputTokens += caseUsage?.outputTokens ?? 0;\n usage.reasoningTokens += caseUsage?.reasoningTokens ?? 0;\n usage.totalTokens +=\n caseUsage?.totalTokens ??\n (caseUsage?.inputTokens ?? 0) +\n (caseUsage?.outputTokens ?? 0) +\n (caseUsage?.reasoningTokens ?? 0);\n usage.toolCalls += toolCallCount(testCase);\n }\n\n return usage;\n}\n\nfunction toolCallCount(testCase: EvalCase) {\n const usageToolCalls = testCase.harness?.usage?.toolCalls;\n if (usageToolCalls !== undefined) {\n return Math.max(usageToolCalls, testCase.toolCalls.length);\n }\n\n return testCase.toolCalls.length;\n}\n","import type { EvalReport } from \"./types\";\nimport {\n escapeCommandData,\n escapeCommandProperty,\n formatNumber,\n formatScore,\n} from \"./utils\";\n\n/** Optional floors and legacy fail-on-any-failure policy for a combined report. */\nexport type EvalGatePolicy = {\n /**\n * Minimum fraction of eval cases that must pass, in the range `[0, 1]`.\n * Example: `0.8` requires at least 80% of eval cases to pass.\n */\n minPassRate?: number;\n /**\n * Minimum average eval score across scored cases, in the range `[0, 1]`.\n */\n minScoreAverage?: number;\n /**\n * When true, require every eval case to pass. Equivalent to setting\n * `minPassRate` to `1`, and combined with an explicit floor by taking the\n * stricter value.\n */\n failOnFailures?: boolean;\n};\n\n/** Result of applying a gate policy to a combined eval report. */\nexport type EvalGateResult = {\n /** Whether the configured policy accepts this report. */\n ok: boolean;\n /** Compact status used by action outputs and summaries. */\n status: \"passed\" | \"failed\";\n /** True when any gate input was configured. */\n enforced: boolean;\n /** Eval pass rate when the report includes at least one eval case. */\n passRate: number | null;\n /** Short title for Check Runs and workflow annotations. */\n title: string;\n /** Longer explanation used in logs, summaries, and annotations. */\n message: string;\n};\n\n/**\n * Decide whether a combined eval report meets the configured CI gate.\n *\n * With no policy inputs, the result mirrors the report status and is not\n * treated as an enforced gate. With floors or `failOnFailures`, non-eval\n * failures and empty eval reports fail closed, and qualitative misses only\n * fail when they break the configured floors.\n */\nexport function evaluateEvalGate(\n report: EvalReport,\n policy: EvalGatePolicy = {},\n): EvalGateResult {\n const minPassRate = resolveMinPassRate(policy);\n const minScoreAverage = policy.minScoreAverage;\n const enforced =\n minPassRate !== undefined ||\n minScoreAverage !== undefined ||\n policy.failOnFailures === true;\n\n const passRate = computePassRate(report);\n const counts = formatEvalCounts(report, passRate);\n\n if (!enforced) {\n const ok = report.status === \"passed\";\n return {\n ok,\n status: ok ? \"passed\" : \"failed\",\n enforced: false,\n passRate,\n title: defaultCheckTitle(report),\n message: ok\n ? `eval report passed: ${counts}`\n : `eval report failed: ${counts}`,\n };\n }\n\n const nonEvalFailures = Math.max(\n 0,\n report.totals.failed - report.totals.evalFailed,\n );\n if (nonEvalFailures > 0) {\n return {\n ok: false,\n status: \"failed\",\n enforced: true,\n passRate,\n title: \"Eval report hard failure\",\n message: `${formatNumber(nonEvalFailures)} non-eval test failure${\n nonEvalFailures === 1 ? \"\" : \"s\"\n }; ${counts}`,\n };\n }\n\n if (report.totals.evalTotal === 0) {\n return {\n ok: false,\n status: \"failed\",\n enforced: true,\n passRate: null,\n title: \"Eval report hard failure\",\n message: \"no eval cases were reported\",\n };\n }\n\n // Preserve Vitest-level hard failures that did not produce counted test\n // failures (for example success:false with empty assertion results).\n if (\n report.status === \"failed\" &&\n report.totals.failed === 0 &&\n report.failures.length === 0\n ) {\n return {\n ok: false,\n status: \"failed\",\n enforced: true,\n passRate,\n title: \"Eval report hard failure\",\n message: `vitest run failed without counted test failures; ${counts}`,\n };\n }\n\n if (\n minPassRate !== undefined &&\n (passRate === null || passRate + Number.EPSILON < minPassRate)\n ) {\n return {\n ok: false,\n status: \"failed\",\n enforced: true,\n passRate,\n title: `Eval pass rate ${formatPercent(passRate)} — required ${formatPercent(minPassRate)}`,\n message: `eval pass rate below floor: ${counts}; required >= ${formatPercent(minPassRate)}`,\n };\n }\n\n if (minScoreAverage !== undefined) {\n const average = report.score?.average;\n if (average === undefined || !Number.isFinite(average)) {\n return {\n ok: false,\n status: \"failed\",\n enforced: true,\n passRate,\n title: \"Eval score gate failed\",\n message: `no score average available; required avg score >= ${formatScore(minScoreAverage)}`,\n };\n }\n if (average + Number.EPSILON < minScoreAverage) {\n return {\n ok: false,\n status: \"failed\",\n enforced: true,\n passRate,\n title: `Avg score ${formatScore(average)} — required ${formatScore(minScoreAverage)}`,\n message: `avg score below floor: ${counts}; required avg score >= ${formatScore(minScoreAverage)}`,\n };\n }\n }\n\n return {\n ok: true,\n status: \"passed\",\n enforced: true,\n passRate,\n title: enforcedPassTitle(report, passRate, minPassRate, minScoreAverage),\n message: `eval gate passed: ${counts}${formatFloorSuffix(minPassRate, minScoreAverage)}`,\n };\n}\n\n/** Compute the eval pass rate for a report, or null when there are no evals. */\nexport function computePassRate(report: EvalReport): number | null {\n if (report.totals.evalTotal <= 0) {\n return null;\n }\n return report.totals.evalPassed / report.totals.evalTotal;\n}\n\n/** Format a 0-1 ratio as a percentage with one decimal place. */\nexport function formatPercent(value: number | null | undefined) {\n if (value == null || !Number.isFinite(value)) {\n return \"n/a\";\n }\n return `${(value * 100).toFixed(1)}%`;\n}\n\n/** Build a suite-level workflow annotation for a failed enforced gate. */\nexport function renderGateWorkflowCommand(gate: EvalGateResult) {\n if (gate.ok || !gate.enforced) {\n return undefined;\n }\n return `::error title=${escapeCommandProperty(gate.title)}::${escapeCommandData(gate.message)}`;\n}\n\nfunction resolveMinPassRate(policy: EvalGatePolicy) {\n const configured = policy.minPassRate;\n if (policy.failOnFailures) {\n if (configured === undefined) {\n return 1;\n }\n return Math.max(configured, 1);\n }\n return configured;\n}\n\nfunction defaultCheckTitle(report: EvalReport) {\n if (report.failures.length === 0 && report.status === \"passed\") {\n return \"No eval failures\";\n }\n if (report.failures.length === 0) {\n return \"Vitest run failed\";\n }\n return `${report.failures.length} eval failure${\n report.failures.length === 1 ? \"\" : \"s\"\n }`;\n}\n\nfunction enforcedPassTitle(\n report: EvalReport,\n passRate: number | null,\n minPassRate: number | undefined,\n minScoreAverage: number | undefined,\n) {\n if (minPassRate !== undefined) {\n return `Eval pass rate ${formatPercent(passRate)} — floor ${formatPercent(minPassRate)}`;\n }\n if (minScoreAverage !== undefined) {\n return `Avg score ${formatScore(report.score?.average)} — floor ${formatScore(minScoreAverage)}`;\n }\n return defaultCheckTitle(report);\n}\n\nfunction formatEvalCounts(report: EvalReport, passRate: number | null) {\n const scoreText =\n report.score?.average === undefined\n ? \"n/a\"\n : formatScore(report.score.average);\n const passRateText = passRate === null ? \"n/a\" : formatPercent(passRate);\n return `${formatNumber(report.totals.evalPassed)}/${formatNumber(\n report.totals.evalTotal,\n )} passed (${passRateText}), avg score ${scoreText}`;\n}\n\nfunction formatFloorSuffix(\n minPassRate: number | undefined,\n minScoreAverage: number | undefined,\n) {\n const parts: string[] = [];\n if (minPassRate !== undefined) {\n parts.push(`pass rate floor ${formatPercent(minPassRate)}`);\n }\n if (minScoreAverage !== undefined) {\n parts.push(`avg score floor ${formatScore(minScoreAverage)}`);\n }\n return parts.length === 0 ? \"\" : `; ${parts.join(\", \")}`;\n}\n","import type { EvalGateResult } from \"./gate\";\nimport { formatPercent } from \"./gate\";\nimport type { EvalCase, EvalReport, ToolCallSummary } from \"./types\";\nimport {\n compactLine,\n escapeFence,\n escapeHtml,\n formatDuration,\n formatLocation,\n formatNumber,\n formatScore,\n stringifyValue,\n truncate,\n} from \"./utils\";\n\n/** Options for rendering GitHub Actions summary markdown. */\nexport type SummaryOptions = {\n maxFailures?: number;\n maxReasonChars?: number;\n maxOutputChars?: number;\n maxToolCalls?: number;\n gate?: EvalGateResult;\n};\n\nconst DEFAULT_MAX_FAILURES = 20;\nconst DEFAULT_MAX_REASON_CHARS = 8000;\nconst DEFAULT_MAX_OUTPUT_CHARS = 4000;\nconst DEFAULT_MAX_TOOL_CALLS = 20;\nconst SCORE_DISTRIBUTION_BUCKETS = [\n \"0-19%\",\n \"20-39%\",\n \"40-59%\",\n \"60-79%\",\n \"80-100%\",\n] as const;\nconst SCORE_DISTRIBUTION_BAR_WIDTH = 20;\n\n/** Renders the GitHub Actions job summary markdown for an eval report. */\nexport function renderJobSummary(\n report: EvalReport,\n options: SummaryOptions = {},\n) {\n const maxFailures = options.maxFailures ?? DEFAULT_MAX_FAILURES;\n const failures = report.failures.slice(0, maxFailures);\n const nonEvalFailures = report.totals.failed - report.totals.evalFailed;\n const lines: string[] = [\n \"# vitest-evals\",\n \"\",\n ...renderSummaryTable(report, nonEvalFailures, options.gate),\n \"\",\n ...renderScoreDistribution(report),\n \"## Results\",\n \"\",\n ];\n\n if (report.failures.length > 0) {\n const failureHeading =\n options.gate?.ok === true ? \"### Quality Misses\" : \"### Failures\";\n lines.push(failureHeading, \"\");\n failures.forEach((testCase, index) => {\n lines.push(...renderFailureDetails(testCase, index + 1, options), \"\");\n });\n\n if (report.failures.length > failures.length) {\n const omittedLabel =\n options.gate?.ok === true ? \"quality misses\" : \"failures\";\n lines.push(\n `${report.failures.length - failures.length} more ${omittedLabel} omitted from this summary.`,\n \"\",\n );\n }\n } else if (report.totals.evalTotal > 0) {\n lines.push(\"### Failures\", \"\", \"No eval failures.\", \"\");\n }\n\n if (report.totals.evalTotal === 0) {\n lines.push(\"No eval metadata was found in the Vitest JSON report.\", \"\");\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction formatCountLine(passed: number, failed: number, total: number) {\n return `${formatNumber(passed)} passed, ${formatNumber(failed)} failed, ${formatNumber(total)} total`;\n}\n\nfunction renderSummaryTable(\n report: EvalReport,\n nonEvalFailures: number,\n gate?: EvalGateResult,\n) {\n const rows: Array<[string, string]> = [\n [\"Status\", gate?.status ?? report.status],\n [\n \"Evals\",\n formatCountLine(\n report.totals.evalPassed,\n report.totals.evalFailed,\n report.totals.evalTotal,\n ),\n ],\n ];\n\n if (gate?.passRate !== undefined && gate.passRate !== null) {\n rows.push([\"Pass Rate\", formatPercent(gate.passRate)]);\n } else if (report.totals.evalTotal > 0) {\n rows.push([\n \"Pass Rate\",\n formatPercent(report.totals.evalPassed / report.totals.evalTotal),\n ]);\n }\n\n if (report.score) {\n rows.push([\"Score\", formatScoreSummary(report.score)]);\n }\n\n if (gate?.enforced) {\n rows.push([\"Gate\", gate.message]);\n }\n\n if (nonEvalFailures > 0) {\n rows.push([\n \"Other Failures\",\n `${formatNumber(nonEvalFailures)} non-eval test failure${\n nonEvalFailures === 1 ? \"\" : \"s\"\n }`,\n ]);\n }\n\n rows.push([\"Duration\", formatDuration(report.durationMs)]);\n\n return [\n \"| Metric | Value |\",\n \"| --- | --- |\",\n ...rows.map(\n ([metric, value]) =>\n `| ${escapeTableCell(metric)} | ${escapeTableCell(value)} |`,\n ),\n ];\n}\n\nfunction formatScoreSummary(score: NonNullable<EvalReport[\"score\"]>) {\n return `avg ${formatScore(score.average)}${\n score.minimum === undefined ? \"\" : `, min ${formatScore(score.minimum)}`\n }`;\n}\n\nfunction escapeTableCell(value: string) {\n return value\n .replace(/\\r?\\n/g, \" \")\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\|/g, \"\\\\|\");\n}\n\nfunction renderScoreDistribution(report: EvalReport) {\n const scores = report.cases\n .map((testCase) => testCase.eval?.avgScore)\n .filter(\n (score): score is number =>\n typeof score === \"number\" && Number.isFinite(score),\n );\n if (scores.length === 0) {\n return [];\n }\n\n const counts = SCORE_DISTRIBUTION_BUCKETS.map(() => 0);\n for (const score of scores) {\n const bucket = Math.min(\n SCORE_DISTRIBUTION_BUCKETS.length - 1,\n Math.max(0, Math.floor(score * SCORE_DISTRIBUTION_BUCKETS.length)),\n );\n counts[bucket] = (counts[bucket] ?? 0) + 1;\n }\n\n const maxCount = Math.max(...counts);\n return [\n \"## Scores\",\n \"\",\n \"```text\",\n ...SCORE_DISTRIBUTION_BUCKETS.map((label, index) =>\n formatScoreDistributionBucket(label, counts[index] ?? 0, maxCount),\n ),\n \"```\",\n \"\",\n ];\n}\n\nfunction formatScoreDistributionBucket(\n label: string,\n count: number,\n maxCount: number,\n) {\n const barLength =\n count === 0\n ? 0\n : Math.max(\n 1,\n Math.round((count / maxCount) * SCORE_DISTRIBUTION_BAR_WIDTH),\n );\n const bar = \"#\".repeat(barLength).padEnd(SCORE_DISTRIBUTION_BAR_WIDTH, \" \");\n return `${label.padEnd(7)} | ${bar} ${formatNumber(count)}`;\n}\n\nfunction renderFailureDetails(\n testCase: EvalCase,\n number: number,\n options: SummaryOptions,\n) {\n const failure = testCase.primaryFailure;\n const maxReasonChars = options.maxReasonChars ?? DEFAULT_MAX_REASON_CHARS;\n const maxOutputChars = options.maxOutputChars ?? DEFAULT_MAX_OUTPUT_CHARS;\n const maxToolCalls = options.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS;\n const usage = formatCaseUsage(testCase);\n const finalOutput = testCase.eval?.output ?? testCase.harness?.output;\n const summary = `${number}. ${testCase.displayName} - ${\n failure?.judgeName ?? \"failure\"\n } - ${formatScore(failure?.score ?? testCase.eval?.avgScore)}`;\n const lines = [\n \"<details>\",\n `<summary>${escapeHtml(summary)}</summary>`,\n \"\",\n \"```text\",\n ...renderFailureBlock(testCase, {\n finalOutput,\n maxOutputChars,\n maxReasonChars,\n maxToolCalls,\n number,\n usage,\n }).map(escapeFence),\n \"```\",\n \"\",\n \"</details>\",\n ];\n return lines;\n}\n\nfunction renderFailureBlock(\n testCase: EvalCase,\n {\n finalOutput,\n maxOutputChars,\n maxReasonChars,\n maxToolCalls,\n number,\n usage,\n }: {\n finalOutput: unknown;\n maxOutputChars: number;\n maxReasonChars: number;\n maxToolCalls: number;\n number: number;\n usage: string;\n },\n) {\n const failure = testCase.primaryFailure;\n const overviewRows: Array<[string, string]> = [\n [\"Case\", `${number}. ${testCase.displayName}`],\n [\"Status\", testCase.status],\n [\"Location\", formatLocation(testCase.displayFile, testCase.location)],\n [\"Harness\", testCase.harness?.name ?? \"n/a\"],\n [\"Score\", formatScore(failure?.score ?? testCase.eval?.avgScore)],\n [\"Judge\", failure?.judgeName ?? \"n/a\"],\n ];\n if (usage) {\n overviewRows.push([\"Usage\", usage]);\n }\n if (testCase.durationMs !== undefined) {\n overviewRows.push([\"Duration\", formatDuration(testCase.durationMs)]);\n }\n\n const lines = [\n ...renderAsciiSection(\"Result\", renderKeyValues(overviewRows)),\n \"\",\n ];\n\n if (failure?.reason) {\n lines.push(\n ...renderAsciiSection(\n \"Reason\",\n truncate(failure.reason, maxReasonChars).split(/\\r?\\n/),\n ),\n \"\",\n );\n }\n\n if (testCase.eval?.scores.length) {\n lines.push(\n ...renderAsciiTable(\n [\"Judge\", \"Score\"],\n testCase.eval.scores.map((score) => [\n score.name ?? \"Unknown\",\n formatScore(score.score),\n ]),\n ),\n \"\",\n );\n }\n\n if (finalOutput !== undefined) {\n lines.push(\n ...renderAsciiSection(\n \"Final Output\",\n stringifyValue(finalOutput, maxOutputChars).split(/\\r?\\n/),\n ),\n \"\",\n );\n }\n\n if (testCase.toolCalls.length) {\n const toolCalls = testCase.toolCalls.slice(0, maxToolCalls);\n lines.push(\n ...renderAsciiTable(\n [\"Tool\", \"Status\", \"Duration\"],\n toolCalls.map((toolCall) => [\n toolCall.name,\n formatToolCallStatus(toolCall),\n toolCall.durationMs === undefined\n ? \"n/a\"\n : formatDuration(toolCall.durationMs),\n ]),\n ),\n );\n if (testCase.toolCalls.length > maxToolCalls) {\n lines.push(\n `${testCase.toolCalls.length - maxToolCalls} more tool calls omitted`,\n );\n }\n lines.push(\"\");\n }\n\n if (testCase.harness?.errors.length) {\n lines.push(\n ...renderAsciiSection(\n \"Harness Errors\",\n stringifyValue(testCase.harness.errors, maxReasonChars).split(/\\r?\\n/),\n ),\n \"\",\n );\n }\n\n while (lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n return lines;\n}\n\nfunction formatToolCallStatus(toolCall: ToolCallSummary) {\n if (toolCall.status === \"pending\") {\n return \"pending\";\n }\n\n if (toolCall.status === \"error\") {\n return `error: ${compactLine(toolCall.error ?? \"unknown error\", 120)}`;\n }\n\n return \"ok\";\n}\n\nfunction renderAsciiSection(title: string, content: string[]) {\n return [title, \"-\".repeat(title.length), ...content];\n}\n\nfunction renderKeyValues(rows: Array<[string, string]>) {\n const labelWidth = Math.max(...rows.map(([label]) => label.length));\n return rows.map(\n ([label, value]) =>\n `${label.padEnd(labelWidth)} ${compactLine(value, 500)}`,\n );\n}\n\nfunction renderAsciiTable(headers: string[], rows: string[][]) {\n const widths = headers.map((header, index) =>\n Math.max(header.length, ...rows.map((row) => row[index]?.length ?? 0)),\n );\n const renderRow = (row: string[]) =>\n row\n .map((cell, index) => cell.padEnd(widths[index] ?? cell.length))\n .join(\" \")\n .trimEnd();\n\n return [\n renderRow(headers),\n widths.map((width) => \"-\".repeat(width)).join(\" \"),\n ...rows.map(renderRow),\n ];\n}\n\nfunction formatCaseUsage(testCase: EvalCase) {\n const usage = testCase.harness?.usage;\n const parts: string[] = [];\n const totalTokens =\n usage?.totalTokens ??\n (usage?.inputTokens ?? 0) +\n (usage?.outputTokens ?? 0) +\n (usage?.reasoningTokens ?? 0);\n const toolCalls =\n usage?.toolCalls !== undefined\n ? Math.max(usage.toolCalls, testCase.toolCalls.length)\n : testCase.toolCalls.length;\n\n if (totalTokens > 0) {\n parts.push(`${formatNumber(totalTokens)} tokens`);\n }\n if (toolCalls > 0) {\n parts.push(`${formatNumber(toolCalls)} tool${toolCalls === 1 ? \"\" : \"s\"}`);\n }\n if (testCase.harness?.timingMs !== undefined) {\n parts.push(formatDuration(testCase.harness.timingMs));\n }\n\n return parts.join(\", \");\n}\n","import { buildCheckAnnotations } from \"./annotations\";\nimport { type EvalGateResult, evaluateEvalGate } from \"./gate\";\nimport { type SummaryOptions, renderJobSummary } from \"./summary\";\nimport type { EvalReport } from \"./types\";\n\n/** Options for creating or updating a GitHub Check Run. */\nexport type PublishCheckRunOptions = SummaryOptions & {\n token?: string;\n repository?: string;\n sha?: string;\n name?: string;\n apiUrl?: string;\n checkRunId?: number;\n maxAnnotations?: number;\n /**\n * Suite gate decision. When omitted, the report is evaluated with the\n * default advisory policy so title/conclusion stay consistent.\n */\n gate?: EvalGateResult;\n};\n\n/** Result of attempting to publish a GitHub Check Run. */\nexport type PublishCheckRunResult =\n | {\n status: \"skipped\";\n reason: string;\n }\n | {\n status: \"created\" | \"updated\";\n id?: number;\n htmlUrl?: string;\n };\n\nconst DEFAULT_CHECK_NAME = \"vitest-evals\";\nconst MAX_CHECK_SUMMARY_LENGTH = 64_000;\nconst CHECK_SUMMARY_TRUNCATION_SUFFIX =\n \"\\n\\n[truncated for GitHub Check Run]\\n\";\n\n/** Publishes the eval report to a GitHub Check Run when configuration allows it. */\nexport async function publishCheckRun(\n report: EvalReport,\n options: PublishCheckRunOptions = {},\n): Promise<PublishCheckRunResult> {\n const token = options.token ?? process.env.GITHUB_TOKEN;\n const repository = options.repository ?? process.env.GITHUB_REPOSITORY;\n const sha = options.sha ?? process.env.GITHUB_SHA;\n\n if (!token) {\n return { status: \"skipped\", reason: \"missing GITHUB_TOKEN\" };\n }\n if (!repository) {\n return { status: \"skipped\", reason: \"missing GITHUB_REPOSITORY\" };\n }\n if (!sha && options.checkRunId === undefined) {\n return { status: \"skipped\", reason: \"missing GITHUB_SHA\" };\n }\n\n const [owner, repo] = repository.split(\"/\");\n if (!owner || !repo) {\n return {\n status: \"skipped\",\n reason: `invalid GitHub repository: ${repository}`,\n };\n }\n\n const payload = buildCheckRunPayload(report, options);\n const apiUrl =\n options.apiUrl ?? process.env.GITHUB_API_URL ?? \"https://api.github.com\";\n const requestUrl =\n options.checkRunId === undefined\n ? `${apiUrl}/repos/${owner}/${repo}/check-runs`\n : `${apiUrl}/repos/${owner}/${repo}/check-runs/${options.checkRunId}`;\n const response = await fetch(requestUrl, {\n method: options.checkRunId === undefined ? \"POST\" : \"PATCH\",\n headers: {\n accept: \"application/vnd.github+json\",\n authorization: `Bearer ${token}`,\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\",\n },\n body: JSON.stringify(\n options.checkRunId === undefined\n ? {\n name: options.name ?? DEFAULT_CHECK_NAME,\n head_sha: sha,\n ...payload,\n }\n : payload,\n ),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\n `GitHub Check Run request failed: ${response.status} ${response.statusText} ${text}`.trim(),\n );\n }\n\n const data = (await response.json()) as {\n id?: number;\n html_url?: string;\n };\n\n return {\n status: options.checkRunId === undefined ? \"created\" : \"updated\",\n id: data.id,\n htmlUrl: data.html_url,\n };\n}\n\nfunction buildCheckRunPayload(\n report: EvalReport,\n options: PublishCheckRunOptions,\n) {\n const gate = options.gate ?? evaluateEvalGate(report);\n const annotations = buildCheckAnnotations(report, {\n maxAnnotations: options.maxAnnotations,\n gate,\n });\n\n return {\n status: \"completed\",\n conclusion: gate.ok ? \"success\" : \"failure\",\n completed_at: new Date().toISOString(),\n output: {\n title: gate.title,\n summary: truncateCheckSummary(\n renderJobSummary(report, {\n ...options,\n maxFailures: options.maxFailures ?? 5,\n maxReasonChars: options.maxReasonChars ?? 4000,\n maxOutputChars: options.maxOutputChars ?? 2000,\n maxToolCalls: options.maxToolCalls ?? 10,\n gate,\n }),\n ),\n annotations,\n },\n };\n}\n\nfunction truncateCheckSummary(summary: string) {\n if (summary.length <= MAX_CHECK_SUMMARY_LENGTH) {\n return summary;\n }\n\n return `${summary\n .slice(0, MAX_CHECK_SUMMARY_LENGTH - CHECK_SUMMARY_TRUNCATION_SUFFIX.length)\n .trimEnd()}${CHECK_SUMMARY_TRUNCATION_SUFFIX}`;\n}\n","import type { EvalReport, UsageSummary } from \"./types\";\n\n/** Merges multiple collected eval reports into one combined report. */\nexport function mergeEvalReports(reports: EvalReport[]): EvalReport {\n const cases = reports.flatMap((report) => report.cases);\n const failures = reports.flatMap((report) => report.failures);\n const scoredCases = cases\n .map((testCase) => testCase.eval?.avgScore)\n .filter(\n (score): score is number =>\n typeof score === \"number\" && Number.isFinite(score),\n );\n const startedAtValues = reports\n .map((report) => report.startedAt)\n .filter(\n (startedAt): startedAt is number =>\n typeof startedAt === \"number\" && Number.isFinite(startedAt),\n );\n const startedAt =\n startedAtValues.length > 0 ? Math.min(...startedAtValues) : undefined;\n\n return {\n status: reports.some((report) => report.status === \"failed\")\n ? \"failed\"\n : \"passed\",\n startedAt,\n durationMs: mergeDuration(reports),\n totals: {\n total: sum(reports, (report) => report.totals.total),\n passed: sum(reports, (report) => report.totals.passed),\n failed: sum(reports, (report) => report.totals.failed),\n skipped: sum(reports, (report) => report.totals.skipped),\n evalTotal: sum(reports, (report) => report.totals.evalTotal),\n evalPassed: sum(reports, (report) => report.totals.evalPassed),\n evalFailed: sum(reports, (report) => report.totals.evalFailed),\n },\n score:\n scoredCases.length > 0\n ? {\n average:\n scoredCases.reduce((total, score) => total + score, 0) /\n scoredCases.length,\n minimum: Math.min(...scoredCases),\n }\n : undefined,\n usage: mergeUsage(reports.map((report) => report.usage)),\n cases,\n failures,\n };\n}\n\nfunction mergeUsage(usages: Array<Required<UsageSummary>>) {\n return {\n inputTokens: sum(usages, (usage) => usage.inputTokens),\n outputTokens: sum(usages, (usage) => usage.outputTokens),\n reasoningTokens: sum(usages, (usage) => usage.reasoningTokens),\n totalTokens: sum(usages, (usage) => usage.totalTokens),\n toolCalls: sum(usages, (usage) => usage.toolCalls),\n };\n}\n\nfunction mergeDuration(reports: EvalReport[]) {\n const durations = reports\n .map((report) => report.durationMs)\n .filter(\n (durationMs): durationMs is number =>\n typeof durationMs === \"number\" && Number.isFinite(durationMs),\n );\n const intervals = reports\n .map((report) => {\n if (\n typeof report.startedAt !== \"number\" ||\n !Number.isFinite(report.startedAt) ||\n typeof report.durationMs !== \"number\" ||\n !Number.isFinite(report.durationMs)\n ) {\n return undefined;\n }\n\n return {\n start: report.startedAt,\n end: report.startedAt + report.durationMs,\n };\n })\n .filter((interval): interval is { start: number; end: number } =>\n Boolean(interval),\n );\n\n if (intervals.length > 0 && intervals.length === durations.length) {\n return (\n Math.max(...intervals.map((interval) => interval.end)) -\n Math.min(...intervals.map((interval) => interval.start))\n );\n }\n\n return durations.length > 0\n ? durations.reduce((total, durationMs) => total + durationMs, 0)\n : undefined;\n}\n\nfunction sum<T>(items: T[], select: (item: T) => number) {\n return items.reduce((total, item) => total + select(item), 0);\n}\n","#!/usr/bin/env node\nimport { parseCliArgs } from \"./cli-options\";\nimport { publishEvalReport } from \"./report\";\nimport { escapeCommandData } from \"./utils\";\n\nmain().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n});\n\nasync function main() {\n const options = parseCliArgs(process.argv.slice(2));\n if (options.help) {\n console.log(usage());\n return;\n }\n\n const result = await publishEvalReport({\n resultPatterns: options.resultPatterns,\n cwd: options.workspace ?? process.env.GITHUB_WORKSPACE ?? process.cwd(),\n workspace:\n options.workspace ?? process.env.GITHUB_WORKSPACE ?? process.cwd(),\n summaryEnabled: options.summaryEnabled,\n summaryPath: options.summaryPath,\n annotations: options.annotations,\n checkRun: options.checkRun,\n checkRunId: options.checkRunId,\n checkName: options.checkName,\n failOnCheckError: options.failOnCheckError,\n failOnFailures: options.failOnFailures,\n minPassRate: options.minPassRate,\n minScoreAverage: options.minScoreAverage,\n maxAnnotations: options.maxAnnotations,\n maxFailures: options.maxFailures,\n repository: options.repository,\n sha: options.sha,\n token: options.token,\n warn,\n });\n\n if (result.shouldFail) {\n console.error(result.gate.message);\n process.exitCode = 1;\n }\n}\n\nfunction warn(message: string) {\n if (process.env.GITHUB_ACTIONS === \"true\") {\n console.log(`::warning::${escapeCommandData(message)}`);\n return;\n }\n console.error(`Warning: ${message}`);\n}\n\nfunction usage() {\n return [\n \"Usage: vitest-evals-github-report [vitest-results.json ...] [--json <path>]\",\n \"\",\n \"Options:\",\n \" --json <path> Read a Vitest JSON report from this path or glob\",\n \" --summary <path> Write job summary markdown to this path\",\n \" --no-summary Disable summary output\",\n \" --annotations Emit GitHub workflow-command annotations\",\n \" --no-annotations Disable workflow-command annotations\",\n \" --check-run Publish a GitHub Check Run when configured\",\n \" --fail-on-failures Exit non-zero when any eval case failed\",\n \" --min-pass-rate <0-1> Exit non-zero when eval pass rate is below this floor\",\n \" --min-score-average <0-1> Exit non-zero when average score is below this floor\",\n \" --fail-on-check-error Fail when Check Run publishing fails\",\n \" --check-run-id <id> Update an existing Check Run\",\n \" --check-name <name> Check Run name (default: vitest-evals)\",\n \" --token <token> GitHub token (default: GITHUB_TOKEN)\",\n \" --repo <owner/repo> GitHub repository (default: GITHUB_REPOSITORY)\",\n \" --sha <sha> Git commit SHA (default: GITHUB_SHA)\",\n \" --workspace <path> Workspace path for relative annotation files\",\n \" --max-annotations <n> Maximum annotations to emit\",\n \" --max-failures <n> Maximum failures to include in details\",\n ].join(\"\\n\");\n}\n"],"mappings":"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","names":["usage","score","usage","formatToolCallStatus","startedAt","usage"]}
package/dist/index.d.mts CHANGED
@@ -80,9 +80,63 @@ type CollectOptions = {
80
80
  /** Converts a Vitest JSON report into the compact eval report model. */
81
81
  declare function collectEvalReport(input: VitestJsonReport, options?: CollectOptions): EvalReport;
82
82
 
83
+ /** Optional floors and legacy fail-on-any-failure policy for a combined report. */
84
+ type EvalGatePolicy = {
85
+ /**
86
+ * Minimum fraction of eval cases that must pass, in the range `[0, 1]`.
87
+ * Example: `0.8` requires at least 80% of eval cases to pass.
88
+ */
89
+ minPassRate?: number;
90
+ /**
91
+ * Minimum average eval score across scored cases, in the range `[0, 1]`.
92
+ */
93
+ minScoreAverage?: number;
94
+ /**
95
+ * When true, require every eval case to pass. Equivalent to setting
96
+ * `minPassRate` to `1`, and combined with an explicit floor by taking the
97
+ * stricter value.
98
+ */
99
+ failOnFailures?: boolean;
100
+ };
101
+ /** Result of applying a gate policy to a combined eval report. */
102
+ type EvalGateResult = {
103
+ /** Whether the configured policy accepts this report. */
104
+ ok: boolean;
105
+ /** Compact status used by action outputs and summaries. */
106
+ status: "passed" | "failed";
107
+ /** True when any gate input was configured. */
108
+ enforced: boolean;
109
+ /** Eval pass rate when the report includes at least one eval case. */
110
+ passRate: number | null;
111
+ /** Short title for Check Runs and workflow annotations. */
112
+ title: string;
113
+ /** Longer explanation used in logs, summaries, and annotations. */
114
+ message: string;
115
+ };
116
+ /**
117
+ * Decide whether a combined eval report meets the configured CI gate.
118
+ *
119
+ * With no policy inputs, the result mirrors the report status and is not
120
+ * treated as an enforced gate. With floors or `failOnFailures`, non-eval
121
+ * failures and empty eval reports fail closed, and qualitative misses only
122
+ * fail when they break the configured floors.
123
+ */
124
+ declare function evaluateEvalGate(report: EvalReport, policy?: EvalGatePolicy): EvalGateResult;
125
+ /** Compute the eval pass rate for a report, or null when there are no evals. */
126
+ declare function computePassRate(report: EvalReport): number | null;
127
+ /** Format a 0-1 ratio as a percentage with one decimal place. */
128
+ declare function formatPercent(value: number | null | undefined): string;
129
+ /** Build a suite-level workflow annotation for a failed enforced gate. */
130
+ declare function renderGateWorkflowCommand(gate: EvalGateResult): string | undefined;
131
+
83
132
  /** Options for limiting rendered GitHub annotations. */
84
133
  type AnnotationOptions = {
85
134
  maxAnnotations?: number;
135
+ /**
136
+ * Suite gate decision. When the gate passed, quality misses are demoted to
137
+ * warnings so a green score-gated check is not flooded with red failures.
138
+ */
139
+ gate?: EvalGateResult;
86
140
  };
87
141
  /** GitHub Check Run annotation payload. */
88
142
  type CheckAnnotation = {
@@ -105,6 +159,7 @@ type SummaryOptions = {
105
159
  maxReasonChars?: number;
106
160
  maxOutputChars?: number;
107
161
  maxToolCalls?: number;
162
+ gate?: EvalGateResult;
108
163
  };
109
164
  /** Renders the GitHub Actions job summary markdown for an eval report. */
110
165
  declare function renderJobSummary(report: EvalReport, options?: SummaryOptions): string;
@@ -118,6 +173,11 @@ type PublishCheckRunOptions = SummaryOptions & {
118
173
  apiUrl?: string;
119
174
  checkRunId?: number;
120
175
  maxAnnotations?: number;
176
+ /**
177
+ * Suite gate decision. When omitted, the report is evaluated with the
178
+ * default advisory policy so title/conclusion stay consistent.
179
+ */
180
+ gate?: EvalGateResult;
121
181
  };
122
182
  /** Result of attempting to publish a GitHub Check Run. */
123
183
  type PublishCheckRunResult = {
@@ -131,4 +191,37 @@ type PublishCheckRunResult = {
131
191
  /** Publishes the eval report to a GitHub Check Run when configuration allows it. */
132
192
  declare function publishCheckRun(report: EvalReport, options?: PublishCheckRunOptions): Promise<PublishCheckRunResult>;
133
193
 
134
- export { type AnnotationOptions, type CheckAnnotation, type EvalCase, type EvalFailure, type EvalReport, type PublishCheckRunOptions, type PublishCheckRunResult, type SummaryOptions, buildCheckAnnotations, collectEvalReport, publishCheckRun, renderJobSummary, renderWorkflowCommands };
194
+ /** Options for reading eval JSON files and publishing GitHub report surfaces. */
195
+ type PublishEvalReportOptions = SummaryOptions & EvalGatePolicy & {
196
+ resultPatterns: string[];
197
+ cwd?: string;
198
+ workspace?: string;
199
+ summaryEnabled?: boolean;
200
+ summaryPath?: string;
201
+ annotations?: boolean;
202
+ checkRun?: boolean;
203
+ failOnCheckError?: boolean;
204
+ maxAnnotations?: number;
205
+ checkRunId?: number;
206
+ checkName?: string;
207
+ token?: string;
208
+ repository?: string;
209
+ sha?: string;
210
+ warn?: (message: string) => void;
211
+ };
212
+ /** Result from publishing eval reports, including merged report data. */
213
+ type PublishEvalReportResult = {
214
+ report: EvalReport;
215
+ resultFiles: string[];
216
+ gate: EvalGateResult;
217
+ /**
218
+ * True when an enforced gate rejects the report. Advisory (ungated) runs
219
+ * never fail the step, matching `fail-on-failures: false` defaults.
220
+ */
221
+ shouldFail: boolean;
222
+ checkRun?: PublishCheckRunResult;
223
+ };
224
+ /** Reads, merges, and publishes eval reports to GitHub Actions surfaces. */
225
+ declare function publishEvalReport(options: PublishEvalReportOptions): Promise<PublishEvalReportResult>;
226
+
227
+ export { type AnnotationOptions, type CheckAnnotation, type EvalCase, type EvalFailure, type EvalGatePolicy, type EvalGateResult, type EvalReport, type PublishCheckRunOptions, type PublishCheckRunResult, type PublishEvalReportOptions, type PublishEvalReportResult, type SummaryOptions, buildCheckAnnotations, collectEvalReport, computePassRate, evaluateEvalGate, formatPercent, publishCheckRun, publishEvalReport, renderGateWorkflowCommand, renderJobSummary, renderWorkflowCommands };
package/dist/index.d.ts CHANGED
@@ -80,9 +80,63 @@ type CollectOptions = {
80
80
  /** Converts a Vitest JSON report into the compact eval report model. */
81
81
  declare function collectEvalReport(input: VitestJsonReport, options?: CollectOptions): EvalReport;
82
82
 
83
+ /** Optional floors and legacy fail-on-any-failure policy for a combined report. */
84
+ type EvalGatePolicy = {
85
+ /**
86
+ * Minimum fraction of eval cases that must pass, in the range `[0, 1]`.
87
+ * Example: `0.8` requires at least 80% of eval cases to pass.
88
+ */
89
+ minPassRate?: number;
90
+ /**
91
+ * Minimum average eval score across scored cases, in the range `[0, 1]`.
92
+ */
93
+ minScoreAverage?: number;
94
+ /**
95
+ * When true, require every eval case to pass. Equivalent to setting
96
+ * `minPassRate` to `1`, and combined with an explicit floor by taking the
97
+ * stricter value.
98
+ */
99
+ failOnFailures?: boolean;
100
+ };
101
+ /** Result of applying a gate policy to a combined eval report. */
102
+ type EvalGateResult = {
103
+ /** Whether the configured policy accepts this report. */
104
+ ok: boolean;
105
+ /** Compact status used by action outputs and summaries. */
106
+ status: "passed" | "failed";
107
+ /** True when any gate input was configured. */
108
+ enforced: boolean;
109
+ /** Eval pass rate when the report includes at least one eval case. */
110
+ passRate: number | null;
111
+ /** Short title for Check Runs and workflow annotations. */
112
+ title: string;
113
+ /** Longer explanation used in logs, summaries, and annotations. */
114
+ message: string;
115
+ };
116
+ /**
117
+ * Decide whether a combined eval report meets the configured CI gate.
118
+ *
119
+ * With no policy inputs, the result mirrors the report status and is not
120
+ * treated as an enforced gate. With floors or `failOnFailures`, non-eval
121
+ * failures and empty eval reports fail closed, and qualitative misses only
122
+ * fail when they break the configured floors.
123
+ */
124
+ declare function evaluateEvalGate(report: EvalReport, policy?: EvalGatePolicy): EvalGateResult;
125
+ /** Compute the eval pass rate for a report, or null when there are no evals. */
126
+ declare function computePassRate(report: EvalReport): number | null;
127
+ /** Format a 0-1 ratio as a percentage with one decimal place. */
128
+ declare function formatPercent(value: number | null | undefined): string;
129
+ /** Build a suite-level workflow annotation for a failed enforced gate. */
130
+ declare function renderGateWorkflowCommand(gate: EvalGateResult): string | undefined;
131
+
83
132
  /** Options for limiting rendered GitHub annotations. */
84
133
  type AnnotationOptions = {
85
134
  maxAnnotations?: number;
135
+ /**
136
+ * Suite gate decision. When the gate passed, quality misses are demoted to
137
+ * warnings so a green score-gated check is not flooded with red failures.
138
+ */
139
+ gate?: EvalGateResult;
86
140
  };
87
141
  /** GitHub Check Run annotation payload. */
88
142
  type CheckAnnotation = {
@@ -105,6 +159,7 @@ type SummaryOptions = {
105
159
  maxReasonChars?: number;
106
160
  maxOutputChars?: number;
107
161
  maxToolCalls?: number;
162
+ gate?: EvalGateResult;
108
163
  };
109
164
  /** Renders the GitHub Actions job summary markdown for an eval report. */
110
165
  declare function renderJobSummary(report: EvalReport, options?: SummaryOptions): string;
@@ -118,6 +173,11 @@ type PublishCheckRunOptions = SummaryOptions & {
118
173
  apiUrl?: string;
119
174
  checkRunId?: number;
120
175
  maxAnnotations?: number;
176
+ /**
177
+ * Suite gate decision. When omitted, the report is evaluated with the
178
+ * default advisory policy so title/conclusion stay consistent.
179
+ */
180
+ gate?: EvalGateResult;
121
181
  };
122
182
  /** Result of attempting to publish a GitHub Check Run. */
123
183
  type PublishCheckRunResult = {
@@ -131,4 +191,37 @@ type PublishCheckRunResult = {
131
191
  /** Publishes the eval report to a GitHub Check Run when configuration allows it. */
132
192
  declare function publishCheckRun(report: EvalReport, options?: PublishCheckRunOptions): Promise<PublishCheckRunResult>;
133
193
 
134
- export { type AnnotationOptions, type CheckAnnotation, type EvalCase, type EvalFailure, type EvalReport, type PublishCheckRunOptions, type PublishCheckRunResult, type SummaryOptions, buildCheckAnnotations, collectEvalReport, publishCheckRun, renderJobSummary, renderWorkflowCommands };
194
+ /** Options for reading eval JSON files and publishing GitHub report surfaces. */
195
+ type PublishEvalReportOptions = SummaryOptions & EvalGatePolicy & {
196
+ resultPatterns: string[];
197
+ cwd?: string;
198
+ workspace?: string;
199
+ summaryEnabled?: boolean;
200
+ summaryPath?: string;
201
+ annotations?: boolean;
202
+ checkRun?: boolean;
203
+ failOnCheckError?: boolean;
204
+ maxAnnotations?: number;
205
+ checkRunId?: number;
206
+ checkName?: string;
207
+ token?: string;
208
+ repository?: string;
209
+ sha?: string;
210
+ warn?: (message: string) => void;
211
+ };
212
+ /** Result from publishing eval reports, including merged report data. */
213
+ type PublishEvalReportResult = {
214
+ report: EvalReport;
215
+ resultFiles: string[];
216
+ gate: EvalGateResult;
217
+ /**
218
+ * True when an enforced gate rejects the report. Advisory (ungated) runs
219
+ * never fail the step, matching `fail-on-failures: false` defaults.
220
+ */
221
+ shouldFail: boolean;
222
+ checkRun?: PublishCheckRunResult;
223
+ };
224
+ /** Reads, merges, and publishes eval reports to GitHub Actions surfaces. */
225
+ declare function publishEvalReport(options: PublishEvalReportOptions): Promise<PublishEvalReportResult>;
226
+
227
+ export { type AnnotationOptions, type CheckAnnotation, type EvalCase, type EvalFailure, type EvalGatePolicy, type EvalGateResult, type EvalReport, type PublishCheckRunOptions, type PublishCheckRunResult, type PublishEvalReportOptions, type PublishEvalReportResult, type SummaryOptions, buildCheckAnnotations, collectEvalReport, computePassRate, evaluateEvalGate, formatPercent, publishCheckRun, publishEvalReport, renderGateWorkflowCommand, renderJobSummary, renderWorkflowCommands };