why-agent / client /frontend /src /components /ReportView.tsx
MapoTofu9's picture
deploy: HF Spaces
5d30bdc
Raw
History Blame Contribute Delete
3.63 kB
"use client";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import type { ReportData } from "@/lib/types";
function stripThinkTags(text: string): string {
return text.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
}
export default function ReportView({ report }: { report: ReportData }) {
const text = stripThinkTags(report.text ?? "");
const hypotheses = report.hypotheses ?? [];
return (
<div className="space-y-4">
<div className="report-body">
<ReactMarkdown remarkPlugins={[remarkGfm]} components={{
table: ({ children }) => (
<div className="overflow-x-auto my-4">
<table className="min-w-full text-sm border border-frame rounded-lg overflow-hidden">{children}</table>
</div>
),
thead: ({ children }) => <thead className="bg-surface text-violet-200">{children}</thead>,
tbody: ({ children }) => <tbody className="divide-y divide-frame">{children}</tbody>,
tr: ({ children }) => <tr className="hover:bg-surface/50">{children}</tr>,
th: ({ children }) => <th className="px-3 py-2 text-left font-semibold text-violet-300 whitespace-nowrap">{children}</th>,
td: ({ children }) => <td className="px-3 py-2 text-violet-100">{children}</td>,
h1: ({ children }) => <h1 className="text-2xl font-bold text-white mt-6 mb-3 border-b border-frame pb-2">{children}</h1>,
h2: ({ children }) => <h2 className="text-xl font-semibold text-white mt-5 mb-2">{children}</h2>,
h3: ({ children }) => <h3 className="text-base font-semibold text-violet-300 mt-4 mb-1.5">{children}</h3>,
p: ({ children }) => <p className="text-violet-100 mb-3 leading-7 text-sm">{children}</p>,
ul: ({ children }) => <ul className="list-disc list-outside pl-5 text-violet-100 mb-3 space-y-1">{children}</ul>,
ol: ({ children }) => <ol className="list-decimal list-outside pl-5 text-violet-100 mb-3 space-y-1">{children}</ol>,
li: ({ children }) => <li className="text-violet-100 text-sm leading-relaxed">{children}</li>,
strong: ({ children }) => <strong className="text-white font-semibold">{children}</strong>,
hr: () => <hr className="border-frame my-5" />,
code: ({ children }) => <code className="text-violet-300 font-mono text-xs bg-violet-950/50 px-1.5 py-0.5 rounded">{children}</code>,
blockquote: ({ children }) => <blockquote className="border-l-2 border-violet-500 pl-4 text-violet-300 italic my-3">{children}</blockquote>,
}}>
{text}
</ReactMarkdown>
</div>
{hypotheses.length > 0 && (
<details className="border border-frame rounded-lg">
<summary className="px-4 py-2.5 text-sm text-violet-400 cursor-pointer hover:text-violet-200 transition-colors">
Hypotheses ({hypotheses.length})
</summary>
<div className="px-4 pb-3 space-y-2">
{hypotheses.map((h) => (
<div key={h.id} className="text-sm">
<span className="font-semibold text-violet-300">{h.status === "confirmed" ? "✅" : "🔍"} [{h.id}]</span>
{" "}<span className="text-violet-100">{h.description}</span>
</div>
))}
</div>
</details>
)}
<p className="text-xs text-violet-600 font-mono">
{report.evidence_count} tool calls · {hypotheses.length} hypotheses
{report.error && <span className="text-red-400 ml-2">⚠ {report.error}</span>}
</p>
</div>
);
}