// 记忆 modal:只读两栏 master-detail。左栏列 Core(常驻)+ Extended 各条(带 description), // 右栏渲染选中项原文(markdown)。左侧 rail 底部「记忆」按钮触发。 // **只读** —— 改记忆全走对话(agent 自管,见 core/memory.py 的 _CONTRACT)。 // GUI 当"眼睛"不当"手":看全貌靠直接读 FS(便宜、是地面真相),改靠模型(DESIGN §3.7)。 // 后端:GET /v1/memory(全貌)、GET /v1/memory/extended/{filename}(单篇原文)。 import { $ } from "./dom.js"; import { api } from "./api.js"; import { escapeHtml } from "./format.js"; import { renderMd, highlightIn } from "./markdown.js"; const PLACEHOLDER = '
← 选 Core 或某条专题查看
'; let _cache = null; // 本次打开的 {core, extended} 快照;渲染右栏 Core 复用,免二次请求 function openMemoryModal() { $("memory-modal").classList.add("show"); $("mem-detail").innerHTML = PLACEHOLDER; renderList(); } export function closeMemoryModal() { $("memory-modal").classList.remove("show"); } async function renderList() { const list = $("mem-list"); list.innerHTML = '
加载中…
'; let data; try { data = await api("GET", "/v1/memory"); } catch (e) { list.innerHTML = `
加载失败: ${escapeHtml(e.message)}
`; return; } _cache = data; const ext = data.extended || []; const coreEmpty = !data.core || !data.core.trim(); let html = '
常驻 (Core)
'; html += `
core.md${coreEmpty ? ' ' : ""}
每轮注入,跨任务高频事实
`; html += `
专题 (Extended ${ext.length})
`; html += ext.length ? ext .map( (e) => `
${escapeHtml(e.filename)}
${escapeHtml(e.description || "")}
` ) .join("") : '
还没有。在对话里让我「记住某专题」即可。
'; list.innerHTML = html; } function highlightSel(itemEl) { $("mem-list").querySelectorAll(".sk-item.active").forEach((el) => el.classList.remove("active")); if (itemEl) itemEl.classList.add("active"); } function showCore(itemEl) { highlightSel(itemEl); const detail = $("mem-detail"); const core = (_cache && _cache.core) || ""; detail.innerHTML = core.trim() ? '
core.md常驻
' + `
${renderMd(core)}
` : '
core.md 还是空的。在对话里跟我说你的偏好 / 项目约定,我会记进来。
'; highlightIn(detail); } async function showExt(filename, itemEl) { highlightSel(itemEl); const detail = $("mem-detail"); detail.innerHTML = '
加载中…
'; let data; try { data = await api("GET", "/v1/memory/extended/" + encodeURIComponent(filename)); } catch (e) { detail.innerHTML = `
加载失败: ${escapeHtml(e.message)}
`; return; } detail.innerHTML = `
${escapeHtml(filename)}按需
` + `
${renderMd(data.content)}
`; highlightIn(detail); } // ───── 顶层绑定 ───── $("hd-memory").onclick = openMemoryModal; $("mem-close").onclick = closeMemoryModal; $("memory-modal").addEventListener("click", (e) => { if (e.target.id === "memory-modal") closeMemoryModal(); // 点遮罩关闭 }); $("mem-list").addEventListener("click", (e) => { const item = e.target.closest(".sk-item"); if (!item) return; if (item.getAttribute("data-kind") === "core") showCore(item); else showExt(item.getAttribute("data-file"), item); });