import { useState } from "react"; import type { RlmIterDetail } from "../types"; interface IterationDetailProps { data: RlmIterDetail; } function parsePromptMessages(promptStr: string): { role: string; content: string }[] { try { const parsed = JSON.parse(promptStr); if (Array.isArray(parsed)) return parsed; } catch { /* not JSON */ } return [{ role: "raw", content: promptStr }]; } const roleColors: Record = { system: "border-violet-500 bg-violet-950", user: "border-emerald-500 bg-emerald-950", assistant: "border-sky-500 bg-sky-950", raw: "border-gray-500 bg-gray-900", }; export default function IterationDetail({ data }: IterationDetailProps) { const [promptExpanded, setPromptExpanded] = useState(false); const messages = parsePromptMessages(data.prompt); return (
{/* Stats */}
Model: {data.model} In: {(data.input_tokens / 1000).toFixed(1)}k Out: {(data.output_tokens / 1000).toFixed(1)}k Time: {data.execution_time.toFixed(1)}s
{/* Prompt section (collapsible) */}
{promptExpanded && (
{messages.map((msg, i) => (
{msg.role}
{msg.content.length > 8000 ? msg.content.slice(0, 8000) + "\n...(truncated)" : msg.content}
))}
)}
{/* Response */}
Response
{data.response}
{/* Code Blocks */} {data.code_blocks.length > 0 && (
Code Blocks ({data.code_blocks.length})
{data.code_blocks.map((cb, i) => (
python Block {i + 1}
                  {cb.code}
                
{cb.stdout && (
stdout
                      {cb.stdout}
                    
)}
))}
)} {/* Final Answer */} {data.final_answer && (
Final Answer
{data.final_answer}
)}
); }