diff --git a/frontend/js/assistant.js b/frontend/js/assistant.js index e03a65f..2caa739 100644 --- a/frontend/js/assistant.js +++ b/frontend/js/assistant.js @@ -546,6 +546,11 @@ var SUGGESTIONS = ['Как вырезать кусок учебника?', 'Как создать карточки?', 'Как начать тест?', 'Объясни теорему Пифагора', 'Где мои домашние задания?', 'Как включить тёмную тему?']; var TEACHER_SUGGESTIONS = ['Как создать класс и выдать задание?', 'Идеи заданий по теме…', 'Составь план урока по теме…', 'Как работает журнал и аналитика?', 'Как провести онлайн-урок?']; var _chat = []; // многоходовой диалог: [{role:'user'|'assistant', content}] + // Диалог переживает обновление/переходы (localStorage, per-user), пока ученик сам не нажмёт «Очистить». + function _chatKey() { try { var u = LS.getUser && LS.getUser(); return u && u.id ? 'asst_chat_' + u.id : null; } catch (e) { return null; } } + function saveChat() { var k = _chatKey(); if (k) lsSet(k, JSON.stringify(_chat.slice(-30))); } + function loadChat() { var k = _chatKey(); if (!k) return; try { var a = JSON.parse(lsGet(k) || '[]'); if (Array.isArray(a)) _chat = a.filter(function (m) { return m && (m.role === 'user' || m.role === 'assistant') && typeof m.content === 'string'; }); } catch (e) {} } + function clearChatStore() { var k = _chatKey(); if (k) try { localStorage.removeItem(k); } catch (e) {} } function msgEl(role) { var d = document.createElement('div'); d.className = 'asst-msg asst-msg-' + role; return d; } function renderChat(chatEl) { chatEl.innerHTML = ''; @@ -593,7 +598,7 @@ '
' + '
' + '
' + _svg('') + - 'Держу в голове ход беседы — последние ~14 сообщений. Что обсуждали раньше — учту, давнее плавно забывается. «Очистить» — начать с чистого листа.
', {}); + 'Держу в голове ход беседы — последние ~14 сообщений. Диалог сохраняется между заходами и обновлениями страницы, пока ты сам не нажмёшь «Очистить».', {}); var inp = bubble.querySelector('.asst-ask-in'); var chatEl = bubble.querySelector('.asst-chat'); var chipsEl = bubble.querySelector('.asst-chips'); @@ -622,7 +627,7 @@ }); }); var clr = bubble.querySelector('[data-a="clear"]'); - if (clr) clr.onclick = function () { _chat = []; openAsk(); }; + if (clr) clr.onclick = function () { _chat = []; clearChatStore(); openAsk(); }; var memBtn = bubble.querySelector('[data-a="mem"]'); if (memBtn) memBtn.onclick = openMemory; if (prefill && prefill.q) go(prefill.q, prefill.context, prefill.mode); @@ -671,7 +676,7 @@ LS.imageGen(prompt).then(function (r) { ph.remove(); var d = msgEl('assistant'); - if (r && r.url) { d.innerHTML = ''; _chat.push({ role: 'assistant', content: '[картинка]', img: r.url }); setNameFace('ecstatic'); } + if (r && r.url) { d.innerHTML = ''; _chat.push({ role: 'assistant', content: '[картинка]', img: r.url }); saveChat(); setNameFace('ecstatic'); } else { d.textContent = 'Не получилось нарисовать.'; setNameFace('sad'); } chatEl.appendChild(d); chatEl.scrollTop = chatEl.scrollHeight; }).catch(function (err) { @@ -722,7 +727,7 @@ var sources = done.sources || meta.sources || []; var content = isModel ? (full || done.answer) : ((ansArr[0] && (ansArr[0].q + '\n' + ansArr[0].a)) || 'Не нашёл точного ответа. Попробуй переформулировать или поищи (Ctrl+K).'); ensureMsg(); richEl.classList.remove('asst-streaming'); - _chat.push({ role: 'assistant', content: content }); + _chat.push({ role: 'assistant', content: content }); saveChat(); renderRich(richEl, content); if (isModel && sources.length) { var sc = document.createElement('div'); sc.className = 'asst-src'; @@ -786,7 +791,7 @@ var sources = r0.sources || []; var found = (res[1] && res[1].results) || []; var content = model || (ans[0] && (ans[0].q + '\n' + ans[0].a)) || 'Не нашёл точного ответа. Попробуй переформулировать или поищи (Ctrl+K).'; - _chat.push({ role: 'assistant', content: content }); + _chat.push({ role: 'assistant', content: content }); saveChat(); var d = msgEl('assistant'); d.innerHTML = '
'; chatEl.appendChild(d); renderRich(d.querySelector('.asst-rich'), content); // источники (RAG) @@ -1058,6 +1063,7 @@ SRV = ctx || {}; _role = (SRV && SRV.role) || 'student'; if (SRV.enabled === false) return; // выключено пользователем + loadChat(); // восстановить диалог прошлой сессии (per-user) return (LS.api ? LS.api('/api/pet') : Promise.resolve(null)).then(function (pet) { PET = pet || null; ensurePet(mount);