diff --git a/app/components/evaluations/CategoryMetricsTable.tsx b/app/components/evaluations/CategoryMetricsTable.tsx
index cb5b9d6..a154dfc 100644
--- a/app/components/evaluations/CategoryMetricsTable.tsx
+++ b/app/components/evaluations/CategoryMetricsTable.tsx
@@ -1,6 +1,7 @@
"use client";
import { CategoryMetric } from "@/app/lib/types/evaluation";
+import VerdictBadge from "./VerdictBadge";
interface CategoryMetricsTableProps {
categoryMetrics: CategoryMetric[];
@@ -60,7 +61,13 @@ export default function CategoryMetricsTable({
{formatScore(row.avg_cosine)}
- {summary.name}
+
+
+ {summary.name}
+
+
{summary.avg !== undefined ? summary.avg.toFixed(3) : "N/A"}
diff --git a/app/components/evaluations/ScoreDisplay.tsx b/app/components/evaluations/ScoreDisplay.tsx
index 68efa33..d0eddec 100644
--- a/app/components/evaluations/ScoreDisplay.tsx
+++ b/app/components/evaluations/ScoreDisplay.tsx
@@ -7,6 +7,7 @@
import type { ScoreObject } from "@/app/lib/types/evaluation";
import { hasSummaryScores } from "@/app/lib/utils/evaluation";
+import VerdictBadge from "./VerdictBadge";
interface ScoreDisplayProps {
score: ScoreObject | null;
@@ -75,6 +76,11 @@ export default function ScoreDisplay({
{summary.name}:
{value}
{std !== null && ±{std}}
+
);
})}
diff --git a/app/components/evaluations/VerdictBadge.tsx b/app/components/evaluations/VerdictBadge.tsx
new file mode 100644
index 0000000..166fc2b
--- /dev/null
+++ b/app/components/evaluations/VerdictBadge.tsx
@@ -0,0 +1,41 @@
+"use client";
+
+import {
+ getVerdictBand,
+ VERDICT_LABELS,
+ VerdictBand,
+} from "@/app/lib/utils/evaluation";
+
+interface VerdictBadgeProps {
+ value: number | string | null | undefined;
+ dataType?: "NUMERIC" | "CATEGORICAL";
+ name?: string;
+ size?: "sm" | "md";
+}
+
+const VERDICT_CLASSES: Record = {
+ good: "bg-status-success-bg text-status-success-text",
+ needs_refinement: "bg-status-warning-bg text-status-warning-text",
+ needs_improvement: "bg-status-error-bg text-status-error-text",
+};
+
+export default function VerdictBadge({
+ value,
+ dataType,
+ name,
+ size = "sm",
+}: VerdictBadgeProps) {
+ const band = getVerdictBand(value, dataType, name);
+ if (!band) return null;
+
+ const padding =
+ size === "md" ? "px-2.5 py-1 text-xs" : "px-2 py-0.5 text-[10px]";
+
+ return (
+
+ {VERDICT_LABELS[band]}
+
+ );
+}
diff --git a/app/components/evaluations/index.ts b/app/components/evaluations/index.ts
index 6f2fa03..96aff05 100644
--- a/app/components/evaluations/index.ts
+++ b/app/components/evaluations/index.ts
@@ -13,4 +13,5 @@ export { default as MetricsOverview } from "./MetricsOverview";
export { default as RunEvaluationForm } from "./RunEvaluationForm";
export { default as RunModeBadge } from "./RunModeBadge";
export { default as ScoreDisplay } from "./ScoreDisplay";
+export { default as VerdictBadge } from "./VerdictBadge";
export { default as ViewDatasetModal } from "./ViewDatasetModal";
diff --git a/app/lib/utils/evaluation.ts b/app/lib/utils/evaluation.ts
index 1403499..8c62b57 100644
--- a/app/lib/utils/evaluation.ts
+++ b/app/lib/utils/evaluation.ts
@@ -8,6 +8,36 @@ import type {
TraceItem,
} from "@/app/lib/types/evaluation";
+export type VerdictBand = "good" | "needs_refinement" | "needs_improvement";
+
+export const VERDICT_LABELS: Record = {
+ good: "Good",
+ needs_refinement: "Needs Refinement",
+ needs_improvement: "Needs Improvement",
+};
+
+/**
+ * Judge-metric scores are banded 0-5: Good (4-5), Needs Refinement (2-3),
+ * Needs Improvement (0-1). Cosine scores and categorical/N/A entries carry
+ * no verdict, so this returns null for them.
+ */
+export function getVerdictBand(
+ value: number | string | null | undefined,
+ dataType: "NUMERIC" | "CATEGORICAL" | undefined,
+ name?: string,
+): VerdictBand | null {
+ if (dataType === "CATEGORICAL") return null;
+ if (name && /cosine/i.test(name)) return null;
+ if (value === null || value === undefined) return null;
+
+ const numValue = Number(value);
+ if (!Number.isFinite(numValue)) return null;
+
+ if (numValue >= 4) return "good";
+ if (numValue >= 2) return "needs_refinement";
+ return "needs_improvement";
+}
+
export function hasSummaryScores(
score: ScoreObject | null | undefined,
): score is NewScoreObjectV2 | BasicScoreObject {