Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions helm-frontend/src/components/Predictions.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import type DisplayPrediction from "@/types/DisplayPrediction";
import type DisplayRequest from "@/types/DisplayRequest";
import type MetricFieldMap from "@/types/MetricFieldMap";
import Predictions from "./Predictions";

it("renders instance metrics in a compact two-column list", () => {
const predictions: DisplayPrediction[] = [
{
instance_id: "instance-1",
predicted_text: "hello world",
train_trial_index: 0,
stats: {
very_long_metric_name_for_layout_regression: 0.75,
exact_match: 1,
},
mapped_output: undefined,
},
];
const requests: DisplayRequest[] = [
{
instance_id: "instance-1",
train_trial_index: 0,
request: {
echo_prompt: false,
embedding: false,
frequency_penalty: 0,
max_tokens: 16,
model: "example/model",
num_completions: 1,
presence_penalty: 0,
prompt: "Prompt text",
stop_sequences: [],
temperature: 0,
top_k_per_token: 1,
top_p: 1,
multimodal_prompt: undefined,
messages: undefined,
},
},
];
const metricFieldMap: MetricFieldMap = {
very_long_metric_name_for_layout_regression: {
name: "very_long_metric_name_for_layout_regression",
display_name: "Very long metric name for layout regression",
short_display_name: "Very long metric",
description: "Long label used to verify compact metric layout rendering.",
lower_is_better: false,
},
exact_match: {
name: "exact_match",
display_name: "Exact match",
short_display_name: "EM",
description: "Exact match metric",
lower_is_better: false,
},
};

render(
<Predictions
predictions={predictions}
requests={requests}
metricFieldMap={metricFieldMap}
/>,
);

const metricsContainer = screen.getByTestId("prediction-metrics");
expect(metricsContainer).toHaveClass("max-w-3xl");
expect(
screen.getByText("Very long metric name for layout regression"),
).toBeInTheDocument();
expect(screen.getByText("0.75")).toBeInTheDocument();
expect(screen.getByText("Exact match")).toBeInTheDocument();
});
25 changes: 16 additions & 9 deletions helm-frontend/src/components/Predictions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type MetricFieldMap from "@/types/MetricFieldMap";
import Indicator from "@/components/Indicator";
import Request from "@/components/Request";
import Preview from "@/components/Preview";
import { List, ListItem } from "@tremor/react";
import AnnotationsDisplay from "./AnnotationsDisplay";

type Props = {
Expand Down Expand Up @@ -72,22 +71,30 @@ export default function Predictions({
<AnnotationsDisplay
predictionAnnotations={prediction.annotations}
/>
<div className="mx-1">
<div className="mx-1 max-w-3xl" data-testid="prediction-metrics">
<h3>Metrics</h3>
<List>
<ul className="divide-y divide-gray-200 rounded-md border border-gray-200 bg-white">
{Object.keys(prediction.stats).map((statKey, idx) => (
<ListItem key={idx}>
<li
className="grid grid-cols-[minmax(0,1fr)_auto] gap-4 px-4 py-2"
key={idx}
>
{metricFieldMap[statKey] ? (
<span title={metricFieldMap[statKey].description}>
<span
className="min-w-0 break-words"
title={metricFieldMap[statKey].description}
>
{metricFieldMap[statKey].display_name}
</span>
) : (
<span>{statKey}</span>
<span className="min-w-0 break-words">{statKey}</span>
)}
<span>{String(prediction.stats[statKey])}</span>
</ListItem>
<span className="whitespace-nowrap text-right font-medium">
{String(prediction.stats[statKey])}
</span>
</li>
))}
</List>
</ul>
</div>
<details className="collapse collapse-arrow border rounded-md bg-white">
<summary className="collapse-title">Request details</summary>
Expand Down