pyaesonegtckglay-dotcom
feat: GOD MODE+ v3.0 — Full Autonomous AI Operating System
a20767f
'use client'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism'
import { Copy, Check, User, Bot, Code2, Bug, Zap, Brain, Plug, Rocket, Workflow, Terminal, Palette } from 'lucide-react'
import { useState } from 'react'
import type { Message, AgentName } from '@/hooks/useAgentStore'
import { formatDistanceToNow } from 'date-fns'
const AGENT_META: Record<string, { icon: React.ElementType; color: string; label: string }> = {
chat: { icon: Bot, color: '#22d3ee', label: 'Chat' },
planner: { icon: Zap, color: '#a78bfa', label: 'Planner' },
coding: { icon: Code2, color: '#34d399', label: 'Coding' },
debug: { icon: Bug, color: '#f87171', label: 'Debug' },
memory: { icon: Brain, color: '#fbbf24', label: 'Memory' },
connector: { icon: Plug, color: '#60a5fa', label: 'Connector' },
deploy: { icon: Rocket, color: '#f472b6', label: 'Deploy' },
workflow: { icon: Workflow, color: '#fb923c', label: 'Workflow' },
sandbox: { icon: Terminal, color: '#4ade80', label: 'Sandbox' },
ui: { icon: Palette, color: '#e879f9', label: 'UI' },
}
function CopyButton({ text }: { text: string }) {
const [copied, setCopied] = useState(false)
return (
<button
onClick={() => { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000) }}
className="absolute top-2 right-2 p-1.5 rounded-md opacity-0 group-hover:opacity-100 transition-opacity"
style={{ background: 'rgba(255,255,255,0.1)' }}
>
{copied ? <Check size={12} className="text-green-400" /> : <Copy size={12} style={{ color: 'var(--text-muted)' }} />}
</button>
)
}
export default function MessageBubble({ message }: { message: Message }) {
const isUser = message.role === 'user'
const agentMeta = message.agent ? AGENT_META[message.agent] : AGENT_META['chat']
const AgentIcon = agentMeta?.icon || Bot
return (
<div className={`flex gap-3 mb-4 animate-fade-in ${isUser ? 'flex-row-reverse' : 'flex-row'}`}>
{/* Avatar */}
<div className="flex-shrink-0 mt-1">
{isUser ? (
<div className="w-7 h-7 rounded-full flex items-center justify-center"
style={{ background: 'rgba(99,102,241,0.2)', border: '1px solid rgba(99,102,241,0.4)' }}>
<User size={14} className="text-indigo-400" />
</div>
) : (
<div className="w-7 h-7 rounded-full flex items-center justify-center"
style={{
background: `${agentMeta?.color || '#6366f1'}15`,
border: `1px solid ${agentMeta?.color || '#6366f1'}40`,
}}>
<AgentIcon size={13} style={{ color: agentMeta?.color || '#6366f1' }} />
</div>
)}
</div>
{/* Content */}
<div className={`flex-1 min-w-0 ${isUser ? 'items-end' : 'items-start'} flex flex-col gap-1`}>
{/* Header */}
{!isUser && (
<div className="flex items-center gap-2 mb-1">
{message.agent && (
<span className="text-[10px] font-semibold px-1.5 py-0.5 rounded-full"
style={{
background: `${agentMeta.color}15`,
color: agentMeta.color,
border: `1px solid ${agentMeta.color}30`,
}}>
{agentMeta.label}Agent
</span>
)}
<span className="text-[10px]" style={{ color: 'var(--text-muted)' }}>
{formatDistanceToNow(message.timestamp, { addSuffix: true })}
</span>
</div>
)}
{/* Bubble */}
<div className={`rounded-2xl px-4 py-3 max-w-[85%] ${
isUser
? 'rounded-tr-sm text-white'
: 'rounded-tl-sm'
}`}
style={{
background: isUser ? 'var(--brand)' : 'var(--bg-3)',
border: isUser ? 'none' : '1px solid var(--border)',
}}>
{isUser ? (
<p className="text-sm leading-relaxed whitespace-pre-wrap">{message.content}</p>
) : (
<div className="prose-god text-sm">
{message.streaming && !message.content ? (
<div className="flex items-center gap-1 py-1">
{[0, 1, 2].map(i => (
<div key={i} className="typing-dot" style={{ animationDelay: `${i * 0.16}s` }} />
))}
</div>
) : (
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
code({ node, inline, className, children, ...props }: any) {
const match = /language-(\w+)/.exec(className || '')
const code = String(children).replace(/\n$/, '')
if (!inline && match) {
return (
<div className="relative group my-2">
<div className="flex items-center justify-between px-3 py-1.5 rounded-t-lg"
style={{ background: '#1a1b26', borderBottom: '1px solid var(--border)' }}>
<span className="text-[10px] font-mono" style={{ color: 'var(--text-muted)' }}>
{match[1]}
</span>
<CopyButton text={code} />
</div>
<SyntaxHighlighter
style={oneDark as any}
language={match[1]}
PreTag="div"
customStyle={{
margin: 0,
borderRadius: '0 0 8px 8px',
fontSize: '0.75rem',
background: '#0f1017',
border: '1px solid var(--border)',
borderTop: 'none',
}}
{...props}
>
{code}
</SyntaxHighlighter>
</div>
)
}
return (
<code className={className} {...props}
style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: '0.8em' }}>
{children}
</code>
)
},
}}
>
{message.content}
</ReactMarkdown>
)}
{message.streaming && message.content && (
<span className="inline-block w-0.5 h-4 ml-0.5 animate-pulse rounded-full"
style={{ background: 'var(--brand)', verticalAlign: 'middle' }} />
)}
</div>
)}
</div>
{/* Metadata badges */}
{message.metadata?.task_id && (
<div className="flex items-center gap-1 mt-0.5">
<span className="text-[10px] px-1.5 py-0.5 rounded font-mono"
style={{ background: 'var(--bg-3)', color: 'var(--text-muted)', border: '1px solid var(--border)' }}>
{message.metadata.task_id}
</span>
</div>
)}
</div>
</div>
)
}