Zayne Rea Sprague
new tab
b630916
import { useEffect, useState } from "react";
import type { ExampleDetailData, RlmIterDetail } from "../types";
import IterationDetail from "./IterationDetail";
interface ExampleDetailLevelProps {
datasetId: string;
exampleIdx: number;
fetchExampleDetail: (dsId: string, exampleIdx: number) => Promise<ExampleDetailData>;
fetchIterDetail: (dsId: string, exampleIdx: number, rlmIter: number) => Promise<RlmIterDetail>;
}
export default function ExampleDetailLevel({
datasetId,
exampleIdx,
fetchExampleDetail,
fetchIterDetail,
}: ExampleDetailLevelProps) {
const [data, setData] = useState<ExampleDetailData | null>(null);
const [expandedIter, setExpandedIter] = useState<number | null>(null);
const [iterDetail, setIterDetail] = useState<RlmIterDetail | null>(null);
useEffect(() => {
fetchExampleDetail(datasetId, exampleIdx).then(setData).catch(() => {});
}, [datasetId, exampleIdx, fetchExampleDetail]);
useEffect(() => {
if (expandedIter === null) {
setIterDetail(null);
return;
}
fetchIterDetail(datasetId, exampleIdx, expandedIter)
.then(setIterDetail)
.catch(() => {});
}, [datasetId, exampleIdx, expandedIter, fetchIterDetail]);
if (!data) return <div className="p-4 text-gray-400">Loading example detail...</div>;
return (
<div className="p-4 space-y-4 overflow-y-auto">
{/* Question text */}
<div className="bg-gray-800 border border-gray-700 rounded-lg p-4">
<div className="flex items-center gap-2 mb-2">
<div className="text-xs font-semibold text-emerald-400">Question</div>
{data.eval_correct === true && (
<span className="text-emerald-400 text-xs font-bold">&#10003; Correct</span>
)}
{data.eval_correct === false && (
<span className="text-red-400 text-xs font-bold">&#10007; Incorrect</span>
)}
</div>
<div className="text-sm text-gray-200 whitespace-pre-wrap max-h-40 overflow-y-auto">
{data.question_text}
</div>
</div>
{/* Stats row */}
<div className="flex gap-4 text-xs text-gray-400">
<span>
Total tokens:{" "}
<span className="text-gray-200">
{((data.total_input_tokens + data.total_output_tokens) / 1000).toFixed(1)}k
</span>
</span>
<span>
Time: <span className="text-gray-200">{data.total_execution_time.toFixed(1)}s</span>
</span>
<span>
Iterations: <span className="text-gray-200">{data.iterations.length}</span>
</span>
</div>
{/* Iteration timeline */}
<div>
<div className="text-xs font-semibold text-gray-400 mb-2">Iteration Timeline</div>
<div className="flex gap-2 overflow-x-auto pb-2">
{data.iterations.map((it) => (
<div
key={it.rlm_iter}
className={`flex-shrink-0 w-56 bg-gray-800 border rounded-lg p-3 cursor-pointer transition-colors hover:border-emerald-500 ${
expandedIter === it.rlm_iter
? "border-emerald-500 ring-1 ring-emerald-500"
: it.has_final_answer
? "border-emerald-600"
: "border-gray-700"
}`}
onClick={() =>
setExpandedIter(expandedIter === it.rlm_iter ? null : it.rlm_iter)
}
>
<div className="flex items-center justify-between mb-2">
<span className="bg-gray-700 text-gray-200 text-xs font-mono px-2 py-0.5 rounded">
iter {it.rlm_iter}
</span>
<div className="flex gap-1">
{it.has_code_blocks && (
<span className="bg-emerald-900 text-emerald-300 text-xs px-1.5 py-0.5 rounded">
{it.n_code_blocks} code
</span>
)}
{it.has_final_answer && (
<span className="bg-amber-900 text-amber-300 text-xs px-1.5 py-0.5 rounded">
FINAL
</span>
)}
</div>
</div>
<div className="flex justify-between text-xs text-gray-500 mb-2">
<span>{((it.input_tokens + it.output_tokens) / 1000).toFixed(1)}k tok</span>
<span>{it.execution_time.toFixed(1)}s</span>
</div>
<div className="text-xs text-gray-400 line-clamp-3 leading-relaxed">
{it.response_preview || "(empty)"}
</div>
</div>
))}
</div>
</div>
{/* Expanded iteration detail */}
{expandedIter !== null && iterDetail && (
<IterationDetail data={iterDetail} />
)}
{/* Final answer if present */}
{data.final_answer && (
<div className="bg-emerald-950 border border-emerald-700 rounded-lg p-4">
<div className="text-xs font-semibold text-emerald-400 mb-2">Final Answer</div>
<div className="text-sm text-gray-200 whitespace-pre-wrap max-h-60 overflow-y-auto">
{data.final_answer}
</div>
</div>
)}
</div>
);
}