"use client"; import { Markdown } from "@copilotkit/react-ui"; import { useState } from "react"; interface SourceRef { chunk_id: string; document_uri: string; document_title: string; chunk_position: number; } interface ResearchState { question: string; phase: string; status: string; plan: Array<{ id: number; question: string; status: string; search_results?: { type: string; results: Array<{ chunk: string; chunk_id: string; document_uri: string; document_title: string; chunk_position: number; full_chunk_content: string; score: number; expanded: boolean; }>; }; }>; current_question_index: number; insights: Array<{ summary: string; confidence: number; source_refs: SourceRef[]; }>; document_registry: Record< string, { title: string; chunks_referenced: string[]; } >; current_document: { uri: string; title: string; content: string; total_chunks: number; metadata?: Record; } | null; confidence: number; final_report: { title: string; summary: string; findings: string[]; conclusions: string[]; sources: string[]; citations: Array<{ document_uri: string; document_title: string; chunk_ids: string[]; }>; } | null; } interface StateDisplayProps { state: ResearchState; } export default function StateDisplay({ state }: StateDisplayProps) { const [expandedSections, setExpandedSections] = useState< Record >({ plan: true, insights: true, report: true, document: true, }); const [expandedQuestions, setExpandedQuestions] = useState< Record >({}); const toggleSection = (section: string) => { setExpandedSections((prev) => ({ ...prev, [section]: !prev[section], })); }; const toggleQuestion = (questionId: number) => { setExpandedQuestions((prev) => ({ ...prev, [questionId]: !prev[questionId], })); }; // Calculate research progress const completedQuestions = state.plan.filter( (q) => q.status === "done", ).length; const totalQuestions = state.plan.length; const researchProgress = totalQuestions > 0 ? (completedQuestions / totalQuestions) * 100 : 0; return (
{/* Current Phase & Status */}
Current Phase
{state.phase}
{state.status && (
{state.status}
)}
{/* Research Progress Bar */} {totalQuestions > 0 && state.phase !== "idle" && (
Research Progress {completedQuestions}/{totalQuestions} questions
)}
{/* Question */} {state.question && (
Question
{state.question}
)} {/* Confidence Meter */} {state.confidence > 0 && (
Confidence
0.8 ? "#48bb78" : state.confidence > 0.5 ? "#ed8936" : "#f56565", transition: "width 0.3s ease", }} />
0.8 ? "#48bb78" : state.confidence > 0.5 ? "#ed8936" : "#f56565", }} > {(state.confidence * 100).toFixed(0)}%
)} {/* Research Plan */} {state.plan.length > 0 && (
{expandedSections.plan && (
{state.plan.map((item) => (
{/* Search Results nested inside question */} {expandedQuestions[item.id] && item.search_results && (
Search Type: {item.search_results.type}
{item.search_results.results.map((result, idx) => (
{result.document_title}
{result.expanded && ( Expanded )} 0.8 ? "#48bb78" : result.score > 0.6 ? "#ed8936" : "#a0aec0", }} > {result.score.toFixed(2)}
))}
)}
))}
)}
)} {/* Insights */} {state.insights.length > 0 && (
{expandedSections.insights && (
{state.insights.map((insight, idx) => (
{(insight.confidence * 100).toFixed(0)}% confidence {insight.source_refs?.length || 0} sources
{insight.source_refs && insight.source_refs.length > 0 && (
Sources: {insight.source_refs.map((ref, refIdx) => ( {refIdx > 0 && ", "} {ref.document_title} ))}
)}
))}
)}
)} {/* Final Report */} {state.final_report && (
{expandedSections.report && (

{state.final_report.title}

Executive Summary

Main Findings

    {state.final_report.findings.map((finding, idx) => (
  • ))}

Conclusions

    {state.final_report.conclusions.map((conclusion, idx) => (
  • ))}

Citations

{state.final_report.citations && state.final_report.citations.length > 0 ? (
{state.final_report.citations.map((citation) => (
{citation.document_title}
{citation.chunk_ids.length} chunk {citation.chunk_ids.length !== 1 ? "s" : ""}{" "} referenced
))}
) : (
{state.final_report.sources?.map((source) => (
{source}
))}
)}
)}
)}
); }