// The memory bank panel: the entries retrieval can pull into a prompt. import { useCallback, useEffect, useState } from 'react' import { api } from '../../../api' import { AutoTextarea } from '../../../components' function MemoryRow({ memory, onChange, onDelete }) { const [editText, setEditText] = useState(null) const save = () => { const text = editText.trim() setEditText(null) if (text && text !== memory.text) onChange({ text }) } return (
{editText !== null ? (
setEditText(e.target.value)} />
) : ( <>
{memory.text}
{memory.pinned && 📌 pinned} {memory.forgotten && forgotten} {!memory.embedded && !memory.forgotten && ( not embedded yet )} {memory.source_start != null && ( actions {memory.source_start}–{memory.source_end} )} used {memory.use_count}× {memory.forgotten && ( )}
)}
) } function MemoryPanel({ adventure, setAdventure, refreshKey }) { const [memories, setMemories] = useState(null) const [newText, setNewText] = useState('') const load = useCallback(() => { api.listMemories(adventure.id).then(setMemories).catch(() => setMemories([])) }, [adventure.id]) // Summarization runs in the background after a turn, so also refresh shortly after. useEffect(() => { load() const timer = setTimeout(load, 4000) return () => clearTimeout(timer) }, [load, refreshKey]) const setFlag = async (field, value) => { setAdventure({ ...adventure, [field]: value }) await api.updateAdventure(adventure.id, { [field]: value }) } const change = async (memory, data) => { const updated = await api.updateMemory(adventure.id, memory.id, data) setMemories((prev) => prev.map((m) => (m.id === memory.id ? updated : m))) } const remove = async (memory) => { await api.deleteMemory(adventure.id, memory.id) setMemories((prev) => prev.filter((m) => m.id !== memory.id)) } const add = async () => { const text = newText.trim() if (!text) return setNewText('') const memory = await api.createMemory(adventure.id, text) setMemories((prev) => [...prev, memory]) } const active = memories?.filter((m) => !m.forgotten) ?? [] const forgotten = memories?.filter((m) => m.forgotten) ?? [] return (

Memories {memories && `(${active.length})`}

{!memories &&
Loading…
} {memories && active.length === 0 && (
No memories yet. They are generated automatically as you play (from action 12 onward), or add one below.
)} {active.map((m) => ( change(m, data)} onDelete={() => remove(m)} /> ))}
setNewText(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') add() }} />
{forgotten.length > 0 && ( <>

Forgotten ({forgotten.length})

{forgotten.map((m) => ( change(m, data)} onDelete={() => remove(m)} /> ))} )}
) } export { MemoryPanel }