import { useState, useMemo, memo } from 'react'; import { Brain, User, Library, History, Cpu, Globe, Star, Package, RefreshCw, X, ChevronDown, ChevronRight, Plus, Pencil, Trash2, Check, } from 'lucide-react'; import type { MemorySummary, Command } from '../../types/protocol'; /* ── types ────────────────────────────────────────────── */ interface MemoryPanelProps { memories: MemorySummary[]; onRefresh: () => void; onClose?: () => void; onCreateMemory: (ns: string, key: string, content: string) => Command; onUpdateMemory: (id: string, content: string) => Command; onDeleteMemory: (id: string) => Command; sendCommand: (cmd: Command) => void; } interface NamespaceConfig { label: string; icon: typeof Brain; accent: string; accentBorder: string; } const NS: Record = { user: { label: '用户记忆', icon: User, accent: 'text-[var(--accent-cyan)]', accentBorder: 'border-[var(--accent-cyan)]/40', }, semantic: { label: '语义记忆', icon: Library, accent: 'text-[var(--accent-amber)]', accentBorder: 'border-[var(--accent-amber)]/40', }, episodic: { label: '情景记忆', icon: History, accent: 'text-[var(--accent-purple)]', accentBorder: 'border-[var(--accent-purple)]/40', }, skill: { label: '技能记忆', icon: Cpu, accent: 'text-[var(--accent-green)]', accentBorder: 'border-[var(--accent-green)]/40', }, environment: { label: '环境记忆', icon: Globe, accent: 'text-[var(--accent-blue)]', accentBorder: 'border-[var(--accent-blue)]/40', }, reflection: { label: '反思记忆', icon: Star, accent: 'text-[rgb(242,90,90)]', accentBorder: 'border-[rgb(242,90,90)]/40', }, other: { label: '其他', icon: Package, accent: 'text-[var(--text-muted)]', accentBorder: 'border-[var(--border-color)]', }, }; function cfg(ns: string): NamespaceConfig { return ( NS[ns] ?? { label: ns, icon: Package, accent: 'text-[var(--text-secondary)]', accentBorder: 'border-[var(--border-color)]', } ); } function fmtKey(k: string) { return k.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()); } const NS_OPTIONS = Object.entries(NS); /* ── Memory card with edit/delete ──────────────────────── */ function MemoryCard({ memory, config, onUpdate, onDelete, }: { memory: MemorySummary; config: NamespaceConfig; onUpdate: (id: string, content: string) => void; onDelete: (id: string) => void; }) { const [editing, setEditing] = useState(false); const [editContent, setEditContent] = useState(memory.content); const [confirmDelete, setConfirmDelete] = useState(false); const handleSave = () => { if (editContent.trim() && editContent !== memory.content) { onUpdate(memory.id, editContent.trim()); } setEditing(false); }; const handleDelete = () => { if (confirmDelete) { onDelete(memory.id); } else { setConfirmDelete(true); setTimeout(() => setConfirmDelete(false), 3000); } }; return (
{/* header row */}
{fmtKey(memory.memory_key)} {/* action buttons — visible on hover */}
{/* content */} {editing ? (