palimpseste-max / web /src /components /TeachPanel.tsx
thefinalboss's picture
Upload folder using huggingface_hub
6e62ad1 verified
Raw
History Blame Contribute Delete
5.38 kB
import { useState } from 'react'
interface TeachPanelProps {
onTeach: (question: string, answer: string) => Promise<any>
loading: boolean
}
interface TeachResult {
question: string
answer: string
tokensWritten: number
message: string
timestamp: number
}
export function TeachPanel({ onTeach, loading }: TeachPanelProps) {
const [question, setQuestion] = useState('')
const [answer, setAnswer] = useState('')
const [history, setHistory] = useState<TeachResult[]>([])
const handleTeach = async () => {
if (!question.trim() || !answer.trim() || loading) return
try {
const resp = await onTeach(question.trim(), answer.trim())
setHistory(prev => [{
question: question.trim(),
answer: answer.trim(),
tokensWritten: resp.tokens_written,
message: resp.message,
timestamp: Date.now(),
}, ...prev])
setQuestion('')
setAnswer('')
} catch {
setHistory(prev => [{
question: question.trim(),
answer: answer.trim(),
tokensWritten: 0,
message: 'Error: API not reachable',
timestamp: Date.now(),
}, ...prev])
}
}
return (
<div className="flex flex-col h-full glass-card overflow-hidden">
<div className="px-5 py-3 border-b border-pal-border">
<div className="flex items-center gap-2">
<span className="text-base">📚</span>
<h2 className="text-sm font-semibold text-pal-text">Teach</h2>
<span className="text-xs text-pal-muted">O(1) learning</span>
</div>
</div>
<div className="flex-1 overflow-y-auto p-4 space-y-3">
{/* Input form */}
<div className="space-y-2">
<div>
<label className="text-[11px] text-pal-muted font-medium uppercase tracking-wide block mb-1">
Question
</label>
<input
type="text"
value={question}
onChange={e => setQuestion(e.target.value)}
onKeyDown={e => e.key === 'Enter' && !e.shiftKey && handleTeach()}
placeholder="what is the capital of france"
className="w-full bg-pal-surface border border-pal-border rounded-lg px-3 py-2 text-sm text-pal-text placeholder:text-pal-muted focus:outline-none focus:border-pal-green/50 transition-all"
/>
</div>
<div>
<label className="text-[11px] text-pal-muted font-medium uppercase tracking-wide block mb-1">
Answer
</label>
<input
type="text"
value={answer}
onChange={e => setAnswer(e.target.value)}
onKeyDown={e => e.key === 'Enter' && !e.shiftKey && handleTeach()}
placeholder="paris"
className="w-full bg-pal-surface border border-pal-border rounded-lg px-3 py-2 text-sm text-pal-text placeholder:text-pal-muted focus:outline-none focus:border-pal-green/50 transition-all"
/>
</div>
<button
onClick={handleTeach}
disabled={!question.trim() || !answer.trim() || loading}
className="w-full py-2 rounded-lg bg-gradient-to-r from-pal-green to-pal-accent2 text-white font-semibold text-sm transition-all hover:scale-[1.02] hover:shadow-lg hover:shadow-pal-green/20 disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:scale-100"
>
{loading ? 'Teaching...' : '⚡ Teach Instantly'}
</button>
</div>
{/* History */}
{history.length > 0 && (
<div className="space-y-2 pt-2 border-t border-pal-border">
<span className="text-[11px] text-pal-muted font-medium uppercase tracking-wide">
Taught ({history.length})
</span>
{history.map((h, i) => (
<div
key={i}
className="p-2.5 rounded-lg bg-pal-surface/60 border border-pal-border/50 animate-slide-up"
>
<div className="flex items-start justify-between gap-2 mb-1">
<div className="flex-1 min-w-0">
<div className="text-xs text-pal-text font-medium truncate">
{h.question}
</div>
<div className="text-xs text-pal-green font-medium">
→ {h.answer}
</div>
</div>
{h.tokensWritten > 0 && (
<span className="text-[10px] px-1.5 py-0.5 rounded-full bg-pal-green/10 text-pal-green font-mono whitespace-nowrap">
+{h.tokensWritten} tok
</span>
)}
</div>
{h.message && (
<p className="text-[10px] text-pal-muted mt-1">{h.message}</p>
)}
</div>
))}
</div>
)}
{history.length === 0 && (
<div className="text-center py-8">
<div className="text-3xl mb-2 opacity-50"></div>
<p className="text-xs text-pal-muted">
Teach PALIMPSESTE new facts.<br/>
Each fact is written to memory in O(1) —<br/>
instantly retrievable, never forgotten.
</p>
</div>
)}
</div>
</div>
)
}