import { useState, useEffect, memo } from "react"; import { X, Database, BarChart2, AlertTriangle, Trash2, History, User, Zap } from "lucide-react"; import { agentMemory, MemoryEntry } from "@/lib/agentMemory"; import { getOutcomeStats } from "@/lib/selfLearning"; import { getAllSessions, deleteSession, clearAllSessions, getLongTermPrefs, SessionEntry } from "@/lib/sessionMemory"; import { getPatterns, clearPatterns, SkillPattern } from "@/lib/skillPersistence"; import { isAutoFixRunning } from "@/lib/errorAutoFix"; import { Z_INDEX } from "@/lib/zindex"; interface MemoryPanelProps { onClose: () => void; } type Tab = "memory" | "sessions" | "reflection" | "skills"; const MemoryPanel = memo(function MemoryPanel({ onClose }: MemoryPanelProps) { const [tab, setTab] = useState("memory"); const [entries, setEntries] = useState([]); const [sessions, setSessions] = useState([]); const [patterns, setPatterns] = useState([]); const [autoFixOn, setAutoFixOn] = useState(false); const [adding, setAdding] = useState(false); const [search, setSearch] = useState(""); const [form, setForm] = useState({ key: "", value: "", category: "general" }); const [stats, setStats] = useState(() => getOutcomeStats()); const reload = () => { setEntries(agentMemory.list()); setStats(getOutcomeStats()); setSessions(getAllSessions()); setPatterns(getPatterns()); setAutoFixOn(isAutoFixRunning()); }; useEffect(() => { reload(); const unsub = agentMemory.subscribe(reload); return unsub; }, []); const save = () => { if (!form.key.trim() || !form.value.trim()) return; agentMemory.set(form.key.trim(), form.value.trim(), form.category || "general"); setAdding(false); setForm({ key: "", value: "", category: "general" }); reload(); }; const q = search.toLowerCase().trim(); const filtered = q ? entries.filter(e => e.key.toLowerCase().includes(q) || e.value.toLowerCase().includes(q) || (e.category ?? "").toLowerCase().includes(q) ) : entries; const inputStyle = { width: "100%", background: "rgba(255,255,255,0.05)", border: "1px solid #2a2a40", borderRadius: 8, padding: "0.38rem 0.6rem", color: "#e2e2f0", fontSize: "0.8rem", outline: "none", }; const prefs = getLongTermPrefs(); const confColor = (c: number) => c >= 0.75 ? "#4ade80" : c >= 0.5 ? "#fbbf24" : "#f87171"; const tabBtn = (t: Tab, label: string, Icon: React.ElementType) => ( ); return (
e.stopPropagation()}> {/* Header */}
Memoria Agente
{tab === "memory" ? (q ? `${filtered.length} / ${entries.length} ricordi` : `${entries.length} ${entries.length === 1 ? "ricordo" : "ricordi"} salvati`) : tab === "skills" ? `${patterns.length} pattern appresi · Auto-Fix ${autoFixOn ? "attivo" : "inattivo"}` : `${stats.total} task analizzati · ${Math.round(stats.successRate * 100)}% successo`}
{tab === "memory" && entries.length > 0 && ( )}
{/* Tabs */}
{tabBtn("memory", "Ricordi", Database)} {tabBtn("sessions", "Sessioni", History)} {tabBtn("reflection", "Riflessioni", BarChart2)} {tabBtn("skills", "Skills", Zap)}
{/* Search (memory tab only) */} {tab === "memory" && entries.length > 2 && (
setSearch(e.target.value)} placeholder="Cerca nei ricordi…" style={{ ...inputStyle, background: "rgba(255,255,255,0.04)", border: "1px solid #1e1e2e", fontSize: "0.82rem", paddingLeft: "0.5rem" }} autoFocus={false} />
)} {/* Body */}
{/* MEMORY TAB */} {tab === "memory" && (<> {entries.length === 0 && !adding && (
Nessun ricordo. L'agente salva informazioni con il tool remember.
)} {q && filtered.length === 0 && entries.length > 0 && (
Nessun ricordo corrisponde a "{search}".
)} {filtered.map(e => (
{e.key} {e.category !== "general" && ( {e.category} )}
{e.value}
))} {adding ? (
{([{ key: "key", label: "Chiave", placeholder: "nome_info" }, { key: "value", label: "Valore", placeholder: "contenuto da ricordare" }, { key: "category", label: "Categoria", placeholder: "general" }] as Array<{ key: string; label: string; placeholder: string }>).map(({ key, label, placeholder }) => (
{label}
{key === "value" ? (