@vitest-evals/github-reporter 0.16.0 → 0.17.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/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"]}
1
+ {"version":3,"sources":["../src/cli-options.ts","../src/report.ts","../src/utils.ts","../src/annotations.ts","../src/collect.ts","../src/gate.ts","../src/github.ts","../src/summary.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 softFail?: 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 \"--soft-fail\":\n options.softFail = true;\n break;\n case \"--no-soft-fail\":\n options.softFail = false;\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 /**\n * When true, keep the workflow step green on a failed gate so the Check\n * Run owns PR status instead of a canned job failure line. Defaults to\n * true only when a Check Run is actually published; if publishing is\n * skipped/fails, the step still exits non-zero on a failed gate.\n */\n softFail?: boolean;\n maxAnnotations?: number;\n checkRunId?: number;\n checkName?: string;\n token?: string;\n repository?: string;\n sha?: string;\n detailsUrl?: string;\n externalId?: 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 and soft-fail did not keep\n * the step green. Advisory (ungated) runs never fail the step, matching\n * `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 detailsUrl: options.detailsUrl,\n externalId: options.externalId,\n token: options.token,\n gate,\n });\n\n if (checkRun.status === \"skipped\") {\n options.warn?.(`GitHub Check Run skipped: ${checkRun.reason}`);\n } else if (checkRun.htmlUrl) {\n console.log(`published check run: ${checkRun.htmlUrl}`);\n } else if (checkRun.id !== undefined) {\n console.log(`published check run id: ${checkRun.id}`);\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 const gateFailed = gate.enforced && !gate.ok;\n // Soft-fail only when a Check Run actually published. Explicit soft-fail:true\n // still requires a published check so a failed gate cannot go silent.\n const wantsSoftFail = options.softFail ?? options.checkRun === true;\n const softFail = wantsSoftFail && checkRunPublished(checkRun);\n const shouldFail = gateFailed && !softFail;\n\n return {\n report,\n resultFiles,\n gate,\n shouldFail,\n checkRun,\n };\n}\n\nfunction checkRunPublished(checkRun: PublishCheckRunResult | undefined) {\n return checkRun?.status === \"created\" || checkRun?.status === \"updated\";\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 UsageSummary as HarnessUsageSummary,\n type ReportCase,\n type ToolCall,\n type TranscriptToolCallEvent,\n type TranscriptToolResultEvent,\n collectReportWorkspace,\n} from \"@vitest-evals/core\";\nimport type {\n AggregatedUsageSummary,\n CollectOptions,\n EvalCase,\n EvalFailure,\n EvalReport,\n EvalScore,\n ToolCallSummary,\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 = sumAppUsage(cases);\n const judgeUsage = sumJudgeUsage(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 judgeUsage,\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 emptyUsage(): AggregatedUsageSummary {\n return {\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n totalTokens: 0,\n toolCalls: 0,\n };\n}\n\nfunction addRunUsage(\n total: AggregatedUsageSummary,\n usage: HarnessUsageSummary | undefined,\n) {\n total.inputTokens += usage?.inputTokens ?? 0;\n total.outputTokens += usage?.outputTokens ?? 0;\n total.reasoningTokens += usage?.reasoningTokens ?? 0;\n total.totalTokens +=\n usage?.totalTokens ??\n (usage?.inputTokens ?? 0) +\n (usage?.outputTokens ?? 0) +\n (usage?.reasoningTokens ?? 0);\n if (usage?.costUsd !== undefined) {\n total.costUsd = (total.costUsd ?? 0) + usage.costUsd;\n }\n total.toolCalls += usage?.toolCalls ?? 0;\n}\n\nfunction sumAppUsage(cases: EvalCase[]) {\n const usage = emptyUsage();\n const runUsages = cases\n .map(appUsageForCase)\n .filter((item): item is HarnessUsageSummary => item !== undefined);\n for (const runUsage of runUsages) {\n addRunUsage(usage, runUsage);\n }\n omitPartialCost(usage, runUsages);\n return usage;\n}\n\nfunction appUsageForCase(testCase: EvalCase): HarnessUsageSummary | undefined {\n const usage = testCase.harness?.usage;\n const effectiveToolCalls = toolCallCount(testCase);\n if (!usage && effectiveToolCalls === 0) {\n return undefined;\n }\n return {\n ...usage,\n ...(effectiveToolCalls > 0 ? { toolCalls: effectiveToolCalls } : {}),\n };\n}\n\nfunction sumJudgeUsage(cases: EvalCase[]) {\n const usage = emptyUsage();\n const runUsages: Array<HarnessUsageSummary | undefined> = [];\n for (const testCase of cases) {\n for (const score of testCase.eval?.scores ?? []) {\n for (const run of score.judgeRuns ?? []) {\n runUsages.push(run.usage);\n addRunUsage(usage, run.usage);\n }\n }\n }\n omitPartialCost(usage, runUsages);\n return usage;\n}\n\nfunction omitPartialCost(\n total: AggregatedUsageSummary,\n usages: Array<HarnessUsageSummary | undefined>,\n) {\n if (usages.some(hasUsageWithoutCost)) {\n total.costUsd = undefined;\n }\n}\n\nfunction hasUsageWithoutCost(usage: HarnessUsageSummary | undefined) {\n return (\n usage?.costUsd === undefined &&\n ((usage?.totalTokens ??\n (usage?.inputTokens ?? 0) +\n (usage?.outputTokens ?? 0) +\n (usage?.reasoningTokens ?? 0)) > 0 ||\n (usage?.toolCalls ?? 0) > 0)\n );\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 run failed\",\n message: `${formatNumber(nonEvalFailures)} test failure${\n nonEvalFailures === 1 ? \"\" : \"s\"\n } outside eval cases; ${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 run failed\",\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 run failed\",\n message: `Vitest failed without reporting a failed test; ${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: `pass rate is below the minimum: ${counts}; minimum ${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: \"Average score unavailable\",\n message: `no average score was reported; minimum ${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: `Average score ${formatScore(average)} — required ${formatScore(minScoreAverage)}`,\n message: `average score is below the minimum: ${counts}; minimum ${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: `requirements met: ${counts}${formatMinimumSuffix(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 cases failed\";\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)} — minimum ${formatPercent(minPassRate)}`;\n }\n if (minScoreAverage !== undefined) {\n return `Average score ${formatScore(report.score?.average)} — minimum ${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}), average score ${scoreText}`;\n}\n\nfunction formatMinimumSuffix(\n minPassRate: number | undefined,\n minScoreAverage: number | undefined,\n) {\n const parts: string[] = [];\n if (minPassRate !== undefined) {\n parts.push(`minimum pass rate ${formatPercent(minPassRate)}`);\n }\n if (minScoreAverage !== undefined) {\n parts.push(`minimum average score ${formatScore(minScoreAverage)}`);\n }\n return parts.length === 0 ? \"\" : `; ${parts.join(\", \")}`;\n}\n","import { readFileSync } from \"node:fs\";\nimport { 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 detailsUrl?: string;\n externalId?: 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 sha?: 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/**\n * Resolve the commit SHA a Check Run should attach to.\n *\n * On `pull_request`, `GITHUB_SHA` is the temporary merge commit. PR status and\n * required checks attach to the head commit, so prefer an explicit head SHA\n * (option/env or `pull_request.head.sha` from the event payload) first.\n */\nexport function resolveCheckSha(\n env: NodeJS.ProcessEnv = process.env,\n options: { sha?: string; eventPath?: string } = {},\n): string | undefined {\n const explicit = options.sha?.trim() || env.GITHUB_PR_HEAD_SHA?.trim();\n if (explicit) {\n return explicit;\n }\n\n const eventPath = options.eventPath?.trim() || env.GITHUB_EVENT_PATH?.trim();\n if (eventPath) {\n try {\n const event = JSON.parse(readFileSync(eventPath, \"utf8\")) as {\n pull_request?: { head?: { sha?: unknown } };\n };\n const headSha = event.pull_request?.head?.sha;\n if (typeof headSha === \"string\" && headSha.trim()) {\n return headSha.trim();\n }\n } catch {\n // Fall through to GITHUB_SHA when the event payload is unavailable.\n }\n }\n\n return env.GITHUB_SHA?.trim() || undefined;\n}\n\n/**\n * Build a Check Run details URL that points back at the current workflow job\n * (or run) when GitHub Actions env is present.\n */\nexport function resolveCheckDetailsUrl(\n env: NodeJS.ProcessEnv = process.env,\n options: { detailsUrl?: string } = {},\n): string | undefined {\n const explicit = options.detailsUrl?.trim();\n if (explicit) {\n return explicit;\n }\n\n const server = env.GITHUB_SERVER_URL?.replace(/\\/$/, \"\");\n const repository = env.GITHUB_REPOSITORY?.trim();\n const runId = env.GITHUB_RUN_ID?.trim();\n if (!server || !repository || !runId) {\n return undefined;\n }\n\n // GITHUB_JOB is the job id/key, not the numeric job database id, so link the\n // run page. Consumers can override with an explicit details URL when needed.\n return `${server}/${repository}/actions/runs/${runId}`;\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 = resolveCheckSha(process.env, { sha: options.sha });\n const detailsUrl = resolveCheckDetailsUrl(process.env, {\n detailsUrl: options.detailsUrl,\n });\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 {\n status: \"skipped\",\n reason:\n \"missing commit SHA (set --sha / options.sha, GITHUB_PR_HEAD_SHA, pull_request.head.sha, or GITHUB_SHA)\",\n };\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, detailsUrl);\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 ...(options.externalId ? { external_id: options.externalId } : {}),\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 sha,\n };\n}\n\nfunction buildCheckRunPayload(\n report: EvalReport,\n options: PublishCheckRunOptions,\n detailsUrl?: string,\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 ...(detailsUrl ? { details_url: detailsUrl } : {}),\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 { EvalGateResult } from \"./gate\";\nimport { formatPercent } from \"./gate\";\nimport type {\n AggregatedUsageSummary,\n EvalCase,\n EvalReport,\n ToolCallSummary,\n} 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 ? \"### Cases Below Target\" : \"### 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 ? \"cases below target\" : \"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 cases failed.\", \"\");\n }\n\n if (report.totals.evalTotal === 0) {\n lines.push(\"No eval results were 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\", capitalize(gate?.status ?? report.status)],\n [\n \"Eval cases\",\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 (hasUsage(report.usage) || hasUsage(report.judgeUsage)) {\n rows.push([\"App usage\", formatUsage(report.usage)]);\n rows.push([\"Judge usage\", formatUsage(report.judgeUsage)]);\n rows.push([\n \"Total usage\",\n formatUsage(sumUsage(report.usage, report.judgeUsage)),\n ]);\n }\n\n if (gate?.enforced) {\n rows.push([\"Requirements\", gate.message]);\n }\n\n if (nonEvalFailures > 0) {\n rows.push([\n \"Other test failures\",\n `${formatNumber(nonEvalFailures)} test failure${\n nonEvalFailures === 1 ? \"\" : \"s\"\n } outside eval cases`,\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 `average ${formatScore(score.average)}${\n score.minimum === undefined ? \"\" : `, lowest ${formatScore(score.minimum)}`\n }`;\n}\n\nfunction capitalize(value: string) {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction hasUsage(usage: AggregatedUsageSummary) {\n return (\n usage.totalTokens > 0 || usage.costUsd !== undefined || usage.toolCalls > 0\n );\n}\n\nfunction sumUsage(\n app: AggregatedUsageSummary,\n judge: AggregatedUsageSummary,\n): AggregatedUsageSummary {\n const appCostKnown = !hasUsageWithoutCost(app);\n const judgeCostKnown = !hasUsageWithoutCost(judge);\n return {\n inputTokens: app.inputTokens + judge.inputTokens,\n outputTokens: app.outputTokens + judge.outputTokens,\n reasoningTokens: app.reasoningTokens + judge.reasoningTokens,\n totalTokens: app.totalTokens + judge.totalTokens,\n ...(appCostKnown && judgeCostKnown\n ? { costUsd: (app.costUsd ?? 0) + (judge.costUsd ?? 0) }\n : {}),\n toolCalls: app.toolCalls + judge.toolCalls,\n };\n}\n\nfunction hasUsageWithoutCost(usage: AggregatedUsageSummary) {\n return (\n usage.costUsd === undefined &&\n (usage.totalTokens > 0 || usage.toolCalls > 0)\n );\n}\n\nfunction formatUsage(usage: AggregatedUsageSummary) {\n const parts: string[] = [];\n if (usage.totalTokens > 0) {\n parts.push(`${formatNumber(usage.totalTokens)} tokens`);\n }\n if (usage.costUsd !== undefined) {\n parts.push(\n usage.costUsd.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n minimumFractionDigits: 2,\n maximumFractionDigits: 6,\n }),\n );\n }\n if (hasUsageWithoutCost(usage)) {\n parts.push(\"cost unavailable\");\n }\n if (usage.toolCalls > 0) {\n parts.push(\n `${formatNumber(usage.toolCalls)} tool call${usage.toolCalls === 1 ? \"\" : \"s\"}`,\n );\n }\n return parts.join(\", \") || \"none\";\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 [\"App runner\", 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 \"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 \"App 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(\n `${formatNumber(toolCalls)} tool call${toolCalls === 1 ? \"\" : \"s\"}`,\n );\n }\n if (testCase.harness?.timingMs !== undefined) {\n parts.push(formatDuration(testCase.harness.timingMs));\n }\n\n return parts.join(\", \");\n}\n","import type { AggregatedUsageSummary, EvalReport } 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 judgeUsage: mergeUsage(reports.map((report) => report.judgeUsage)),\n cases,\n failures,\n };\n}\n\nfunction mergeUsage(usages: AggregatedUsageSummary[]): AggregatedUsageSummary {\n const costs = usages\n .map((usage) => usage.costUsd)\n .filter((cost): cost is number => cost !== undefined);\n const costComplete = !usages.some(\n (usage) =>\n usage.costUsd === undefined &&\n (usage.totalTokens > 0 || usage.toolCalls > 0),\n );\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 ...(costComplete && costs.length > 0\n ? { costUsd: costs.reduce((total, cost) => total + cost, 0) }\n : {}),\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 softFail: options.softFail,\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 \" --soft-fail Keep exit 0 when a published Check Run owns gate status\",\n \" --no-soft-fail Always exit non-zero when an enforced gate fails\",\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: PR head, then 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","hasUsageWithoutCost","formatToolCallStatus","startedAt","usage"]}
package/dist/index.d.mts CHANGED
@@ -53,7 +53,10 @@ type EvalReport = {
53
53
  average: number;
54
54
  minimum?: number;
55
55
  };
56
- usage: Required<UsageSummary>;
56
+ /** Application and other upstream usage. */
57
+ usage: AggregatedUsageSummary;
58
+ /** Judge-model usage. */
59
+ judgeUsage: AggregatedUsageSummary;
57
60
  cases: EvalCase[];
58
61
  failures: EvalCase[];
59
62
  };
@@ -63,8 +66,11 @@ type UsageSummary = {
63
66
  outputTokens?: number;
64
67
  reasoningTokens?: number;
65
68
  totalTokens?: number;
69
+ costUsd?: number;
66
70
  toolCalls?: number;
67
71
  };
72
+ /** Aggregated usage; cost stays absent when no run reported one. */
73
+ type AggregatedUsageSummary = Required<Omit<UsageSummary, "costUsd">> & Pick<UsageSummary, "costUsd">;
68
74
  /** Tool-call summary shown in reporter output. */
69
75
  type ToolCallSummary = {
70
76
  name: string;
@@ -171,6 +177,8 @@ type PublishCheckRunOptions = SummaryOptions & {
171
177
  sha?: string;
172
178
  name?: string;
173
179
  apiUrl?: string;
180
+ detailsUrl?: string;
181
+ externalId?: string;
174
182
  checkRunId?: number;
175
183
  maxAnnotations?: number;
176
184
  /**
@@ -187,7 +195,26 @@ type PublishCheckRunResult = {
187
195
  status: "created" | "updated";
188
196
  id?: number;
189
197
  htmlUrl?: string;
198
+ sha?: string;
190
199
  };
200
+ /**
201
+ * Resolve the commit SHA a Check Run should attach to.
202
+ *
203
+ * On `pull_request`, `GITHUB_SHA` is the temporary merge commit. PR status and
204
+ * required checks attach to the head commit, so prefer an explicit head SHA
205
+ * (option/env or `pull_request.head.sha` from the event payload) first.
206
+ */
207
+ declare function resolveCheckSha(env?: NodeJS.ProcessEnv, options?: {
208
+ sha?: string;
209
+ eventPath?: string;
210
+ }): string | undefined;
211
+ /**
212
+ * Build a Check Run details URL that points back at the current workflow job
213
+ * (or run) when GitHub Actions env is present.
214
+ */
215
+ declare function resolveCheckDetailsUrl(env?: NodeJS.ProcessEnv, options?: {
216
+ detailsUrl?: string;
217
+ }): string | undefined;
191
218
  /** Publishes the eval report to a GitHub Check Run when configuration allows it. */
192
219
  declare function publishCheckRun(report: EvalReport, options?: PublishCheckRunOptions): Promise<PublishCheckRunResult>;
193
220
 
@@ -201,12 +228,21 @@ type PublishEvalReportOptions = SummaryOptions & EvalGatePolicy & {
201
228
  annotations?: boolean;
202
229
  checkRun?: boolean;
203
230
  failOnCheckError?: boolean;
231
+ /**
232
+ * When true, keep the workflow step green on a failed gate so the Check
233
+ * Run owns PR status instead of a canned job failure line. Defaults to
234
+ * true only when a Check Run is actually published; if publishing is
235
+ * skipped/fails, the step still exits non-zero on a failed gate.
236
+ */
237
+ softFail?: boolean;
204
238
  maxAnnotations?: number;
205
239
  checkRunId?: number;
206
240
  checkName?: string;
207
241
  token?: string;
208
242
  repository?: string;
209
243
  sha?: string;
244
+ detailsUrl?: string;
245
+ externalId?: string;
210
246
  warn?: (message: string) => void;
211
247
  };
212
248
  /** Result from publishing eval reports, including merged report data. */
@@ -215,8 +251,9 @@ type PublishEvalReportResult = {
215
251
  resultFiles: string[];
216
252
  gate: EvalGateResult;
217
253
  /**
218
- * True when an enforced gate rejects the report. Advisory (ungated) runs
219
- * never fail the step, matching `fail-on-failures: false` defaults.
254
+ * True when an enforced gate rejects the report and soft-fail did not keep
255
+ * the step green. Advisory (ungated) runs never fail the step, matching
256
+ * `fail-on-failures: false` defaults.
220
257
  */
221
258
  shouldFail: boolean;
222
259
  checkRun?: PublishCheckRunResult;
@@ -224,4 +261,4 @@ type PublishEvalReportResult = {
224
261
  /** Reads, merges, and publishes eval reports to GitHub Actions surfaces. */
225
262
  declare function publishEvalReport(options: PublishEvalReportOptions): Promise<PublishEvalReportResult>;
226
263
 
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 };
264
+ 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, resolveCheckDetailsUrl, resolveCheckSha };