import React, { useState } from 'react'; import { Sparkles, Clock, Terminal, ChevronDown, ChevronUp, AlertCircle, Brain, Cpu } from 'lucide-react'; // Render LaTeX and text mixed together function RenderLatex({ text }) { if (!text) return null; // Split text by $$ (block math) first, then by $ (inline math) const blockParts = text.split(/(\$\$.*?\$\$)/g); return ( <> {blockParts.map((bp, bpIdx) => { if (bp.startsWith('$$') && bp.endsWith('$$')) { const formula = bp.slice(2, -2); try { if (window.katex) { const html = window.katex.renderToString(formula, { displayMode: true, throwOnError: false }); return
; } } catch (e) { console.error(e); } return
{bp}
; } // Inline math split const inlineParts = bp.split(/(\$.*?\$)/g); return ( {inlineParts.map((ip, ipIdx) => { if (ip.startsWith('$') && ip.endsWith('$')) { const formula = ip.slice(1, -1); if (formula.trim()) { try { if (window.katex) { const html = window.katex.renderToString(formula, { displayMode: false, throwOnError: false }); return ; } } catch (e) { console.error(e); } } return {ip}; } return ; })} ); })} ); } // A simple local Markdown parser that converts basic markdown elements to safe HTML function SafeMarkdown({ content }) { if (!content) return null; const parts = content.split(/(```[\s\S]*?```)/g); return (
{parts.map((part, index) => { if (part.startsWith('```') && part.endsWith('```')) { const code = part.slice(3, -3).replace(/^\w+\n/, ''); return (
              {code}
            
); } const formatted = part .split('\n\n') .map((para, paraIdx) => { if (!para.trim()) return null; // Handle bullet points if (para.trim().startsWith('- ') || para.trim().startsWith('* ')) { const items = para.split(/\n\s*[-*]\s+/); return ( ); } return (

); }); return {formatted}; })}
); } // Format bold (**), italics (*), and inline code (`) function formatInline(text) { return text .replace(/\*\*([^*]+)\*\*/g, '$1') .replace(/\*([^*]+)\*/g, '$1') .replace(/`([^`]+)`/g, '$1') .replace(/\n/g, '
'); } export default function ChatWindow({ history = [], loading, error, onSubmitFollowUp }) { const [openInspectors, setOpenInspectors] = useState({}); const toggleInspector = (idx) => { setOpenInspectors(prev => ({ ...prev, [idx]: !prev[idx] })); }; // Render loading skeleton if (loading && history.length === 0) { return (

Socratic Tutor

Analyzing Sentiment...

--s
); } // Render error message if (error) { return (

Analysis Failed

{error}

); } // Render empty state if (history.length === 0) { return (

Welcome to Socratic Sentiment Tutor

Ask any question about math, science, or programming. The Socratic tutor will detect your mood and guide you towards the answers without giving them away directly.

); } return (
{/* Scrollable Conversation Thread */}
{history.map((msg, idx) => { const isUser = msg.role === 'user'; if (isUser) { return (
You

{msg.content}

); } // Assistant / Tutor Bubble return (
{/* Card Header with sentiment state & metrics */}

Socratic Tutor

{msg.sentiment && (
{msg.latency}s {msg.tokens !== undefined && ( <> | {msg.tokens}t )} {msg.cost !== undefined && ( <> | ${msg.cost.toFixed(5)} )}
)}
{/* Chat Bubble Body */}
{/* Prompt Context Inspector Toggle */} {msg.prompt_context && (
toggleInspector(idx)} style={{ padding: '0.6rem 1.25rem', fontSize: '0.8rem', background: 'rgba(255,255,255,0.01)' }} > View Socratic Context Inspector {openInspectors[idx] ? : }
{openInspectors[idx] && (
Detected Student Sentiment: {msg.sentiment.replace(/_/g, ' ')}
Prompt Context:
{msg.prompt_context}
)}
)}
); })} {/* Loading Bubble when generating */} {loading && (

Socratic Tutor thinking...

)}
{/* Follow-up / Reply Area */} {history.length > 0 && !loading && (

Socratic Dialogue

Reply to the Socratic tutor's guide question to continue exploring the concept.

{ e.preventDefault(); const inputEl = e.target.elements.followUpText; const val = inputEl.value.trim(); if (val) { onSubmitFollowUp(val); inputEl.value = ''; } }} className="query-input-wrapper" >