import { cn } from '@/lib/utils'; import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { Bot, FileText, User, FlaskConical, Brain, Zap, Search, } from 'lucide-react'; import { Skeleton } from './ui/skeleton'; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from '@/components/ui/accordion'; import { StaticHypercubeAnalysis } from './ui/static-hypercube-analysis'; import React from 'react'; import type { Message } from '@/app/page'; type ChatMessageProps = { message: Message; onConsciousnessDimensionSelect?: (dimension: string) => void; selectedConsciousnessDimension?: string; onOpenEditor?: (b64: string, prompt?: string) => void; }; const AssistantMessageContent = ({ message, selectedConsciousnessDimension, onOpenEditor, }: { message: Message; selectedConsciousnessDimension?: string; onOpenEditor?: (b64: string, prompt?: string) => void; }) => { const { content, aetherAnalysis, golemStats, search_results, search_query, imageBase64 } = message as any; const cleanContent = typeof content === 'string' ? content .replace(/^\[\[IMAGE_MODE\]\]\s*/i, '') .replace(/\s*\[\[SAFE_MODE=(ON|OFF)\]\]/i, '') : content; if (imageBase64) { const onlyImage = !cleanContent || /^image generated\.?$/i.test((cleanContent || '').trim()); return (
Generated Image
Download
Generated
{!onlyImage && (

{cleanContent}

)}
); } return (

{cleanContent}

{search_results && search_results.length > 0 && ( Web Search Results for "{search_query}"
{search_results.map((result: any, index: number) => (
{result.title}

{result.snippet}

))}
)} {(message as any).aiThoughts && ( AI Thinking Process ({((message as any).aiThoughts.thinkingTime?.totalTime || 0).toFixed(1)}s)
{/* Context Analysis */}
Context Analysis ({((message as any).aiThoughts.thinkingTime?.analysisTime || 0).toFixed(1)}s)
{(message as any).aiThoughts.contextAnalysis}
{/* Reflection */}
Response Strategy ({((message as any).aiThoughts.thinkingTime?.reflectionTime || 0).toFixed(1)}s)
{(message as any).aiThoughts.reflection}
{/* Chat Context */} {(message as any).aiThoughts.chatContext && (message as any).aiThoughts.chatContext !== 'No previous context' && (
Conversation Context
{(message as any).aiThoughts.chatContext}
)} {/* User Insights */}
User Insights
{(message as any).aiThoughts.userInsights}
)} {aetherAnalysis && ( 5D Consciousness Analysis {/* Match 5D modal layout: viz on top, realtime state row below */}
{/* Static Hypercube Visualization */}
5D Hypercube Position & Clustering
{/* Realtime concise state (bottom of hypercube) - match modal with color bullets */} {golemStats?.hypercube_state && (
Vertex: {golemStats.hypercube_state.current_vertex}/32
Signature: {golemStats.hypercube_state.consciousness_signature}
{/* Active Dimensions chips */} {golemStats.hypercube_state.dimension_activations && (
Active Dimensions:
{Object.entries(golemStats.hypercube_state.dimension_activations) .filter(([, active]) => !!active) .map(([dim]) => ( {dim} ))}
)}
{typeof golemStats.hypercube_state.consciousness_level === 'number' ? (
Consciousness Level: {(Number(golemStats.hypercube_state.consciousness_level) * 100).toFixed(1)}%
) : (
Consciousness Level: —
)}
Aether Patterns: {golemStats.hypercube_state.aether_patterns ?? '—'}
)} {/* Color-coded bullets, one variable per line, no '##' headings */} {(() => { // Colors const colors = { consciousness: '#0D9488', // dark turquoise blue signature: { awareness: '#3B82F6', wisdom: '#8B5CF6', compassion: '#10B981', creativity: '#F97316', transcendence: '#EF4444', } as Record, vertex: '#F97316', // bright orange level: '#EC4899', // pink patterns: '#FACC15', // bright yellow }; const dim = (message as any).consciousnessDimensionUsed || selectedConsciousnessDimension || 'awareness'; const signatureColor = colors.signature[dim] || '#60A5FA'; // Prefer structured data from golemStats; fall back to parsing aetherAnalysis line let vertex = golemStats?.hypercube_state?.current_vertex !== undefined ? `${golemStats.hypercube_state.current_vertex}/32` : undefined; let signature = golemStats?.hypercube_state?.consciousness_signature as string | undefined; let level = typeof golemStats?.hypercube_state?.consciousness_level === 'number' ? Number(golemStats!.hypercube_state!.consciousness_level).toFixed(3) : undefined; let patterns = (golemStats?.hypercube_state as any)?.aether_patterns as number | undefined; // Parse fallback string if needed if ((!vertex || !signature || !level || patterns === undefined) && aetherAnalysis) { const line = aetherAnalysis; const get = (label: string) => { const re = new RegExp(label + "\\s*:?\\s*([^|]+)", 'i'); const m = line.match(re); return m ? m[1].trim() : undefined; }; vertex = vertex || get('Vertex'); signature = signature || get('Signature'); level = level || get('Level'); const pat = get('Aether Patterns'); if (patterns === undefined && pat) { const num = parseInt(pat.replace(/[^0-9]/g, '')); patterns = isNaN(num) ? undefined : num; } } // If we still lack data, don't render if (!vertex && !signature && !level && patterns === undefined) return null; const items = [ { label: 'Consciousness', value: dim, color: colors.consciousness }, { label: 'Signature', value: signature ?? '—', color: signatureColor }, { label: 'Vertex', value: vertex ?? '—', color: colors.vertex }, { label: 'Level', value: level ?? '—', color: colors.level }, { label: 'Aether Patterns', value: patterns ?? '—', color: colors.patterns }, ]; return (
{items.map((it, i) => (
{it.label}: {it.value}
))}
); })()}
)}
); }; export function ChatMessage({ message, onConsciousnessDimensionSelect, selectedConsciousnessDimension, onOpenEditor }: ChatMessageProps) { const isUser = message.role === 'user'; return (
{isUser ? : }
{message.file && (
{message.file.name}
)} {isUser ? (

{typeof message.content === 'string' ? message.content .replace(/^\[\[IMAGE_MODE\]\]\s*/i, '') .replace(/\s*\[\[SAFE_MODE=(ON|OFF)\]\]/i, '') : message.content}

) : ( )}
); } export function LoadingMessage() { const [currentPhase, setCurrentPhase] = React.useState(1); const [phaseStartTime, setPhaseStartTime] = React.useState(Date.now()); const [elapsedTime, setElapsedTime] = React.useState(0); React.useEffect(() => { const interval = setInterval(() => { const now = Date.now(); const elapsed = (now - phaseStartTime) / 1000; setElapsedTime(elapsed); // Switch phases based on elapsed time if (elapsed > 8 && currentPhase === 1) { setCurrentPhase(2); setPhaseStartTime(now); } else if (elapsed > 5 && currentPhase === 2) { setCurrentPhase(3); setPhaseStartTime(now); } }, 100); return () => clearInterval(interval); }, [currentPhase, phaseStartTime]); const getPhaseText = () => { switch (currentPhase) { case 1: return `Analyzing context and query... (${elapsedTime.toFixed(1)}s)`; case 2: return `Reflecting on approach... (${elapsedTime.toFixed(1)}s)`; case 3: return `Generating response... (${elapsedTime.toFixed(1)}s)`; default: return 'AI is thinking...'; } }; const getPhaseIcon = () => { switch (currentPhase) { case 1: return ; case 2: return ; case 3: return ; default: return ; } }; return (
AI is thinking...
{/* Live Thinking Process */} AI Thinking Process (Live)
{/* Current Phase */}
{getPhaseIcon()} Current Phase
{getPhaseText()}
{/* Phase Progress */}
= 1 ? 'bg-blue-400' : 'bg-muted'}`}>
Context Analysis {currentPhase > 1 ? '✓' : '...'}
= 2 ? 'bg-purple-400' : 'bg-muted'}`}>
2 ? 'text-muted-foreground' : 'text-muted-foreground'}> Strategy Reflection {currentPhase > 2 ? '✓' : currentPhase === 2 ? '...' : ''}
= 3 ? 'bg-green-400' : 'bg-muted'}`}>
Response Generation {currentPhase === 3 ? '...' : ''}
); } export function ImageLoadingMessage({ progress = 0, elapsedSeconds, status }: { progress?: number, elapsedSeconds?: number, status?: string }) { const [elapsed, setElapsed] = React.useState(elapsedSeconds || 0); React.useEffect(() => { if (typeof elapsedSeconds === 'number') { setElapsed(elapsedSeconds); return; } const start = Date.now(); const i = setInterval(() => { const t = (Date.now() - start) / 1000; setElapsed(t); }, 120); return () => clearInterval(i); }, [elapsedSeconds]); return (
{status ? `${status.charAt(0).toUpperCase()}${status.slice(1)}` : 'Generating image...'}
Image Generation (Live)
Rendering {(elapsed ?? 0).toFixed(1)}s
Optimized low-VRAM pipeline active
); }