@vitest-evals/github-reporter 0.16.0 → 0.16.1

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/index.mjs CHANGED
@@ -528,6 +528,9 @@ function formatFloorSuffix(minPassRate, minScoreAverage) {
528
528
  return parts.length === 0 ? "" : `; ${parts.join(", ")}`;
529
529
  }
530
530
 
531
+ // src/github.ts
532
+ import { readFileSync } from "fs";
533
+
531
534
  // src/summary.ts
532
535
  var DEFAULT_MAX_FAILURES = 20;
533
536
  var DEFAULT_MAX_REASON_CHARS = 8e3;
@@ -828,10 +831,44 @@ function formatCaseUsage(testCase) {
828
831
  var DEFAULT_CHECK_NAME = "vitest-evals";
829
832
  var MAX_CHECK_SUMMARY_LENGTH = 64e3;
830
833
  var CHECK_SUMMARY_TRUNCATION_SUFFIX = "\n\n[truncated for GitHub Check Run]\n";
834
+ function resolveCheckSha(env = process.env, options = {}) {
835
+ const explicit = options.sha?.trim() || env.GITHUB_PR_HEAD_SHA?.trim();
836
+ if (explicit) {
837
+ return explicit;
838
+ }
839
+ const eventPath = options.eventPath?.trim() || env.GITHUB_EVENT_PATH?.trim();
840
+ if (eventPath) {
841
+ try {
842
+ const event = JSON.parse(readFileSync(eventPath, "utf8"));
843
+ const headSha = event.pull_request?.head?.sha;
844
+ if (typeof headSha === "string" && headSha.trim()) {
845
+ return headSha.trim();
846
+ }
847
+ } catch {
848
+ }
849
+ }
850
+ return env.GITHUB_SHA?.trim() || void 0;
851
+ }
852
+ function resolveCheckDetailsUrl(env = process.env, options = {}) {
853
+ const explicit = options.detailsUrl?.trim();
854
+ if (explicit) {
855
+ return explicit;
856
+ }
857
+ const server = env.GITHUB_SERVER_URL?.replace(/\/$/, "");
858
+ const repository = env.GITHUB_REPOSITORY?.trim();
859
+ const runId = env.GITHUB_RUN_ID?.trim();
860
+ if (!server || !repository || !runId) {
861
+ return void 0;
862
+ }
863
+ return `${server}/${repository}/actions/runs/${runId}`;
864
+ }
831
865
  async function publishCheckRun(report, options = {}) {
832
866
  const token = options.token ?? process.env.GITHUB_TOKEN;
833
867
  const repository = options.repository ?? process.env.GITHUB_REPOSITORY;
834
- const sha = options.sha ?? process.env.GITHUB_SHA;
868
+ const sha = resolveCheckSha(process.env, { sha: options.sha });
869
+ const detailsUrl = resolveCheckDetailsUrl(process.env, {
870
+ detailsUrl: options.detailsUrl
871
+ });
835
872
  if (!token) {
836
873
  return { status: "skipped", reason: "missing GITHUB_TOKEN" };
837
874
  }
@@ -839,7 +876,10 @@ async function publishCheckRun(report, options = {}) {
839
876
  return { status: "skipped", reason: "missing GITHUB_REPOSITORY" };
840
877
  }
841
878
  if (!sha && options.checkRunId === void 0) {
842
- return { status: "skipped", reason: "missing GITHUB_SHA" };
879
+ return {
880
+ status: "skipped",
881
+ reason: "missing commit SHA (set --sha / options.sha, GITHUB_PR_HEAD_SHA, pull_request.head.sha, or GITHUB_SHA)"
882
+ };
843
883
  }
844
884
  const [owner, repo] = repository.split("/");
845
885
  if (!owner || !repo) {
@@ -848,7 +888,7 @@ async function publishCheckRun(report, options = {}) {
848
888
  reason: `invalid GitHub repository: ${repository}`
849
889
  };
850
890
  }
851
- const payload = buildCheckRunPayload(report, options);
891
+ const payload = buildCheckRunPayload(report, options, detailsUrl);
852
892
  const apiUrl = options.apiUrl ?? process.env.GITHUB_API_URL ?? "https://api.github.com";
853
893
  const requestUrl = options.checkRunId === void 0 ? `${apiUrl}/repos/${owner}/${repo}/check-runs` : `${apiUrl}/repos/${owner}/${repo}/check-runs/${options.checkRunId}`;
854
894
  const response = await fetch(requestUrl, {
@@ -863,6 +903,7 @@ async function publishCheckRun(report, options = {}) {
863
903
  options.checkRunId === void 0 ? {
864
904
  name: options.name ?? DEFAULT_CHECK_NAME,
865
905
  head_sha: sha,
906
+ ...options.externalId ? { external_id: options.externalId } : {},
866
907
  ...payload
867
908
  } : payload
868
909
  )
@@ -877,10 +918,11 @@ async function publishCheckRun(report, options = {}) {
877
918
  return {
878
919
  status: options.checkRunId === void 0 ? "created" : "updated",
879
920
  id: data.id,
880
- htmlUrl: data.html_url
921
+ htmlUrl: data.html_url,
922
+ sha
881
923
  };
882
924
  }
883
- function buildCheckRunPayload(report, options) {
925
+ function buildCheckRunPayload(report, options, detailsUrl) {
884
926
  const gate = options.gate ?? evaluateEvalGate(report);
885
927
  const annotations = buildCheckAnnotations(report, {
886
928
  maxAnnotations: options.maxAnnotations,
@@ -890,6 +932,7 @@ function buildCheckRunPayload(report, options) {
890
932
  status: "completed",
891
933
  conclusion: gate.ok ? "success" : "failure",
892
934
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
935
+ ...detailsUrl ? { details_url: detailsUrl } : {},
893
936
  output: {
894
937
  title: gate.title,
895
938
  summary: truncateCheckSummary(
@@ -1050,11 +1093,17 @@ async function publishEvalReport(options) {
1050
1093
  name: options.checkName,
1051
1094
  repository: options.repository,
1052
1095
  sha: options.sha,
1096
+ detailsUrl: options.detailsUrl,
1097
+ externalId: options.externalId,
1053
1098
  token: options.token,
1054
1099
  gate
1055
1100
  });
1056
1101
  if (checkRun.status === "skipped") {
1057
1102
  options.warn?.(`GitHub Check Run skipped: ${checkRun.reason}`);
1103
+ } else if (checkRun.htmlUrl) {
1104
+ console.log(`published check run: ${checkRun.htmlUrl}`);
1105
+ } else if (checkRun.id !== void 0) {
1106
+ console.log(`published check run id: ${checkRun.id}`);
1058
1107
  }
1059
1108
  } catch (error) {
1060
1109
  const message = error instanceof Error ? error.message : String(error);
@@ -1064,14 +1113,21 @@ async function publishEvalReport(options) {
1064
1113
  options.warn?.(message);
1065
1114
  }
1066
1115
  }
1116
+ const gateFailed = gate.enforced && !gate.ok;
1117
+ const wantsSoftFail = options.softFail ?? options.checkRun === true;
1118
+ const softFail = wantsSoftFail && checkRunPublished(checkRun);
1119
+ const shouldFail = gateFailed && !softFail;
1067
1120
  return {
1068
1121
  report,
1069
1122
  resultFiles,
1070
1123
  gate,
1071
- shouldFail: gate.enforced && !gate.ok,
1124
+ shouldFail,
1072
1125
  checkRun
1073
1126
  };
1074
1127
  }
1128
+ function checkRunPublished(checkRun) {
1129
+ return checkRun?.status === "created" || checkRun?.status === "updated";
1130
+ }
1075
1131
  export {
1076
1132
  buildCheckAnnotations,
1077
1133
  collectEvalReport,
@@ -1082,6 +1138,8 @@ export {
1082
1138
  publishEvalReport,
1083
1139
  renderGateWorkflowCommand,
1084
1140
  renderJobSummary,
1085
- renderWorkflowCommands
1141
+ renderWorkflowCommands,
1142
+ resolveCheckDetailsUrl,
1143
+ resolveCheckSha
1086
1144
  };
1087
1145
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/collect.ts","../src/utils.ts","../src/annotations.ts","../src/gate.ts","../src/summary.ts","../src/github.ts","../src/report.ts","../src/merge.ts"],"sourcesContent":["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 { 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 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 { 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 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"],"mappings":"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","names":["score","formatToolCallStatus","startedAt"]}
1
+ {"version":3,"sources":["../src/collect.ts","../src/utils.ts","../src/annotations.ts","../src/gate.ts","../src/github.ts","../src/summary.ts","../src/report.ts","../src/merge.ts"],"sourcesContent":["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 { 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 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 { 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 { 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 { 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 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"],"mappings":"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","names":["score","formatToolCallStatus","startedAt"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest-evals/github-reporter",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "GitHub Actions reporting internals for vitest-evals runs.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,7 +35,7 @@
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
- "@vitest-evals/core": "0.16.0"
38
+ "@vitest-evals/core": "0.16.1"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "vitest": ">=4 <5"