import { useState } from "react"; import type { QuestionData } from "../types"; import { highlightTrace } from "../utils/traceHighlight"; import { parsePrompt, type ParsedMessage } from "../utils/promptParser"; export interface DragHandleProps { draggable: true; onDragStart: (e: React.DragEvent) => void; onDragEnd: (e: React.DragEvent) => void; } interface TracePanelProps { datasetName: string; repoName?: string; data: QuestionData | undefined; sampleIdx: number; isLoading?: boolean; dragHandleProps?: DragHandleProps; } export default function TracePanel({ datasetName, repoName, data, sampleIdx, isLoading, dragHandleProps }: TracePanelProps) { const [promptExpanded, setPromptExpanded] = useState(false); if (isLoading) { return (
Loading...
); } if (!data) { return (
No data
); } const isCorrect = data.eval_correct[sampleIdx]; const analysis = data.analyses[sampleIdx]; const extraction = data.extractions?.[sampleIdx]; const borderColor = isCorrect === undefined ? "border-gray-700" : isCorrect ? "border-green-600" : "border-red-600"; const thinkSegments = highlightTrace(analysis?.think_text || ""); const answerText = analysis?.answer_text || ""; const promptMessages = data.prompt_text ? parsePrompt(data.prompt_text) : []; return (
{/* Header */}
{datasetName} {isCorrect !== undefined && ( {isCorrect ? "CORRECT" : "WRONG"} )}
{analysis && ( <>Think: {analysis.think_len.toLocaleString()} | BT: {analysis.backtracks} )} {dragHandleProps && ( )}
{/* Extraction / extracted answer */} {extraction && (
Extracted: {extraction}
)} {/* Trace content */}
{/* Prompt section — collapsible */} {promptMessages.length > 0 && (
{promptExpanded && (
{promptMessages.map((msg, i) => ( ))}
)}
)} {/* Thinking section */}
Thinking ({analysis?.think_len.toLocaleString() || 0} chars)
            {thinkSegments.map((seg, i) => (
              {seg.text}
            ))}
          
{/* Answer section */} {answerText && (
Answer ({analysis?.answer_len.toLocaleString() || 0} chars)
              {answerText}
            
)}
); } const ROLE_STYLES: Record = { system: { border: "border-l-purple-500", label: "text-purple-400", bg: "bg-purple-500/5" }, user: { border: "border-l-blue-500", label: "text-blue-400", bg: "bg-blue-500/5" }, assistant: { border: "border-l-green-500", label: "text-green-400", bg: "bg-green-500/5" }, prompt: { border: "border-l-gray-500", label: "text-gray-400", bg: "bg-gray-500/5" }, }; function PromptMessage({ message }: { message: ParsedMessage }) { const style = ROLE_STYLES[message.role] || ROLE_STYLES.prompt; return (
{message.role}
        {message.content}
      
); }