import { useState, useRef, useEffect } from 'react' import type { ChatMessage, Metrics, MemorySamples } from '../types' import { SourceBadge } from './SourceBadge' interface ApiProps { connected: boolean metrics: Metrics | null loading: boolean sendMessage: (message: string, temperature?: number, maxTokens?: number) => Promise teachModel: (question: string, answer: string) => Promise learnText: (text: string) => Promise dream: (cycles: number) => Promise reason: (question: string) => Promise } type SidebarTab = 'chat' | 'teach' | 'learn' | 'dream' | 'stats' const SUGGESTIONS = [ { icon: '๐Ÿ‘‹', title: 'Say hello', q: 'hello' }, { icon: '๐Ÿง ', title: 'Who are you?', q: 'who are you' }, { icon: '๐Ÿ', title: 'What is Python?', q: 'what is python' }, { icon: 'โœจ', title: 'Write a poem', q: 'write a poem about the sea' }, { icon: '๐Ÿ’ป', title: 'Write code', q: 'write a python function to check if a number is prime' }, { icon: '๐Ÿ“–', title: 'Explain something', q: 'explain how the internet works' }, { icon: '๐ŸŒ‘', title: 'Science facts', q: 'what is dark matter' }, { icon: '๐Ÿ’ก', title: 'Get advice', q: 'how to stay focused' }, ] export function ChatGPTLayout({ api }: { api: ApiProps }) { const [messages, setMessages] = useState([]) const [input, setInput] = useState('') const [sidebarOpen, setSidebarOpen] = useState(true) const [tab, setTab] = useState('chat') const scrollRef = useRef(null) // Teach state const [teachQ, setTeachQ] = useState('') const [teachA, setTeachA] = useState('') const [teachHistory, setTeachHistory] = useState<{q: string, a: string, tokens: number}[]>([]) // Learn state const [learnText, setLearnText] = useState('') const [learnResult, setLearnResult] = useState(null) // Dream state const [dreamResult, setDreamResult] = useState(null) useEffect(() => { if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight }, [messages, api.loading]) const handleSend = async () => { const msg = input.trim() if (!msg || api.loading) return setInput('') const userMsg: ChatMessage = { id: `u-${Date.now()}`, role: 'user', text: msg, timestamp: Date.now() } setMessages(prev => [...prev, userMsg]) try { const resp = await api.sendMessage(msg) setMessages(prev => [...prev, { id: `b-${Date.now()}`, role: 'palimpseste', text: resp.response, confidence: resp.confidence, source: resp.source, explanation: resp.explanation, chain: resp.chain, elapsed_ms: resp.elapsed_ms, timestamp: Date.now(), }]) } catch { setMessages(prev => [...prev, { id: `e-${Date.now()}`, role: 'palimpseste', text: 'โš ๏ธ Cannot connect to server. Is the API running on :3332?', source: 'fallback', confidence: 0, timestamp: Date.now(), }]) } } const handleTeach = async () => { if (!teachQ.trim() || !teachA.trim() || api.loading) return try { const resp = await api.teachModel(teachQ, teachA) setTeachHistory(prev => [{ q: teachQ, a: teachA, tokens: resp.tokens_written }, ...prev]) setTeachQ(''); setTeachA('') } catch {} } const handleLearn = async () => { if (!learnText.trim() || api.loading) return try { const r = await api.learnText(learnText) setLearnResult(r) } catch {} } const handleDream = async () => { try { const r = await api.dream(3) setDreamResult(r) } catch {} } const newChat = () => { setMessages([]); setTab('chat') } return (
{/* Background orbs */}
{/* Sidebar */} {sidebarOpen && ( )} {/* Main content */}
{/* Top bar */}
PALIMPSESTE BPE
{api.metrics && (
D={api.metrics.model.D.toLocaleString()} ยท |M|={api.metrics.model.n_traces.toLocaleString()}
)}
{/* Content area */} {tab === 'chat' && ( <> {/* Messages */}
{messages.length === 0 ? (
๐Ÿง 

PALIMPSESTE

A self-referential hypervectorial cortex

{SUGGESTIONS.map(s => ( ))}
) : (
{messages.map(msg => (
{msg.role === 'palimpseste' && (
๐Ÿง 
)}

{msg.text}

{msg.role === 'palimpseste' && msg.source && (
{msg.elapsed_ms !== undefined && ( {msg.elapsed_ms < 1 ? '<1' : msg.elapsed_ms.toFixed(0)}ms )}
)}
{msg.role === 'user' && (
๐Ÿง‘
)}
))} {api.loading && (
๐Ÿง 
)}
)}
{/* Input bar */}