import React, { useState } from 'react'; import { Database, Search, Trash2, Clock, Layers, Archive, Share2, AlertCircle, } from 'lucide-react'; import { Card, CardHeader, CardContent } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import { Input } from '@/components/ui/Input'; import { useMemory, useClearMemory, useQueryMemory, getMemoryLayerBadge, formatMemorySize, } from '@/hooks/useMemory'; import { useCurrentEpisode } from '@/hooks/useEpisode'; import { formatTimestamp, truncateText } from '@/utils/helpers'; import type { MemoryEntry, MemoryLayer } from '@/types'; interface MemoryPanelProps { className?: string; } const MEMORY_TABS: { key: MemoryLayer; label: string; icon: React.ReactNode }[] = [ { key: 'short_term', label: 'Short-Term', icon: }, { key: 'working', label: 'Working', icon: }, { key: 'long_term', label: 'Long-Term', icon: }, { key: 'shared', label: 'Shared', icon: }, ]; const MemoryEntryCard: React.FC<{ entry: MemoryEntry }> = ({ entry }) => { const [isExpanded, setIsExpanded] = useState(false); return (
setIsExpanded(!isExpanded)} >
{entry.type}

{isExpanded ? entry.content : truncateText(entry.content, 80)}

{formatTimestamp(entry.timestamp)}
{isExpanded && entry.metadata && Object.keys(entry.metadata).length > 0 && (
{JSON.stringify(entry.metadata, null, 2)}
)}
); }; export const MemoryPanel: React.FC = ({ className }) => { const { data: episode } = useCurrentEpisode(); const { data: memory, isLoading } = useMemory(episode?.id); const clearMemoryMutation = useClearMemory(episode?.id); const queryMemoryMutation = useQueryMemory(episode?.id); const [activeTab, setActiveTab] = useState('working'); const [searchQuery, setSearchQuery] = useState(''); const handleSearch = () => { if (searchQuery.trim() && episode?.id) { queryMemoryMutation.mutate({ query: searchQuery, layer: activeTab, limit: 10, }); } }; const handleClear = () => { if (episode?.id && confirm(`Clear all ${activeTab.replace('_', ' ')} memory?`)) { clearMemoryMutation.mutate(activeTab); } }; const getEntriesForTab = (): MemoryEntry[] => { if (!memory) return []; switch (activeTab) { case 'short_term': return memory.shortTerm; case 'working': return memory.working; case 'long_term': return memory.longTerm; case 'shared': return memory.shared; default: return []; } }; const entries = queryMemoryMutation.data ?? getEntriesForTab(); return ( } action={ memory && ( {formatMemorySize(memory.memoryUsage)} ) } /> {/* Tabs */}
{MEMORY_TABS.map((tab) => ( ))}
{/* Search */}
setSearchQuery(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSearch()} leftIcon={} className="flex-1" />
{/* Memory Entries */}
{isLoading ? (
) : entries.length === 0 ? (

No {activeTab.replace('_', ' ')} memory entries

) : ( entries.map((entry) => ( )) )}
{/* Memory Stats */} {memory && (
{MEMORY_TABS.map((tab) => { const count = tab.key === 'short_term' ? memory.shortTerm.length : tab.key === 'working' ? memory.working.length : tab.key === 'long_term' ? memory.longTerm.length : memory.shared.length; return (
{count}
{tab.label}
); })}
)}
); }; export default MemoryPanel;