import { useState } from 'react' import { ChevronDown, ChevronUp, Clock, Zap, Pin, AlertTriangle, Code, Activity } from 'lucide-react' import clsx from 'clsx' import ChartPanel from '@/components/dashboard/ChartPanel' import AgentTrace from '@/components/dashboard/AgentTrace' import type { QueryResponse, TraceEvent } from '@/api' interface Props { query: string response: QueryResponse streamingText?: string isStreaming?: boolean onPin?: (resp: QueryResponse, query: string) => void traceEvents?: TraceEvent[] } export default function ChatMessage({ query, response, streamingText, isStreaming, onPin, traceEvents }: Props) { const [showCode, setShowCode] = useState(false) const [showTrace, setShowTrace] = useState(false) const [showExplain, setShowExplain] = useState(false) const displayText = isStreaming ? (streamingText ?? '') : response.insight_text const anomalies = (response as any).anomalies || [] const trace = traceEvents || (response as any).trace || [] const queryPlan = (response as any).query_plan || (response as any).trace_summary?.query_plan return (
{/* User bubble */}
{query}
{/* Agent response */}
AI
{/* Insight text */}
{displayText || (isStreaming ? Thinking… : '—')} {isStreaming && displayText && }
{/* Anomaly callouts */} {!isStreaming && anomalies.length > 0 && (
Did you know?
{anomalies.map((a: string, i: number) => (

$1') .replace(/`(.*?)`/g, '$1') }} /> ))}

)} {/* Chart */} {!isStreaming && response.chart_spec && (
)} {/* Agent trace (collapsible) */} {!isStreaming && trace.length > 0 && showTrace && ( )} {/* Explainability panel */} {!isStreaming && showExplain && (

Query Explanation

{queryPlan && (

Approach

{queryPlan.approach || '—'}

{queryPlan.tables && (
{queryPlan.tables.map((t: string) => ( {t} ))}
)} {queryPlan.complexity && ( {queryPlan.complexity} )}
)} {response.correction_attempts > 0 && (

Self-Correction

The agent fixed its own code {response.correction_attempts} time{response.correction_attempts > 1 ? 's' : ''} before producing the correct result.

)} {response.execution_result && response.execution_result.length > 0 && (

Raw Data Preview ({response.execution_result.length} rows)

{Object.keys(response.execution_result[0]).map(col => ( ))} {response.execution_result.slice(0, 10).map((row, i) => ( {Object.values(row).map((val, j) => ( ))} ))}
{col}
{String(val ?? '')}
)}
)} {/* Footer row */} {!isStreaming && (
{/* Badges */} {response.code_type.toUpperCase()} {response.from_cache && cached} {response.correction_attempts > 0 && ( {response.correction_attempts} fix{response.correction_attempts > 1 ? 'es' : ''} )} {response.latency_ms}ms {/* Toggle buttons */} {/* Pin to dashboard */} {onPin && response.chart_spec && ( )}
)} {/* Code block */} {showCode && response.generated_code && (
              {response.generated_code}
            
)}
) }