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
{!onlyImage && (
)}
);
}
return (
{cleanContent}
{search_results && search_results.length > 0 && (
Web Search Results for "{search_query}"
{search_results.map((result: any, index: number) => (
))}
)}
{(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 (
{/* 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
);
}