feat(assistant): срок жизни диалога — 7 дней без общения
saveChat пишет метку времени, loadChat сбрасывает диалог, если с последней реплики прошло больше CHAT_TTL (7 дней). Обратная совместимость со старым форматом-массивом. Сноска обновлена. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -546,10 +546,22 @@
|
||||
var SUGGESTIONS = ['Как вырезать кусок учебника?', 'Как создать карточки?', 'Как начать тест?', 'Объясни теорему Пифагора', 'Где мои домашние задания?', 'Как включить тёмную тему?'];
|
||||
var TEACHER_SUGGESTIONS = ['Как создать класс и выдать задание?', 'Идеи заданий по теме…', 'Составь план урока по теме…', 'Как работает журнал и аналитика?', 'Как провести онлайн-урок?'];
|
||||
var _chat = []; // многоходовой диалог: [{role:'user'|'assistant', content}]
|
||||
// Диалог переживает обновление/переходы (localStorage, per-user), пока ученик сам не нажмёт «Очистить».
|
||||
// Диалог переживает обновление/переходы (localStorage, per-user), пока ученик сам не нажмёт «Очистить»
|
||||
// или пока не пройдёт CHAT_TTL без новых сообщений (срок жизни от последней реплики).
|
||||
var CHAT_TTL = 7 * 24 * 3600 * 1000; // 7 дней
|
||||
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 saveChat() { var k = _chatKey(); if (k) lsSet(k, JSON.stringify({ t: Date.now(), c: _chat.slice(-30) })); }
|
||||
function loadChat() {
|
||||
var k = _chatKey(); if (!k) return;
|
||||
try {
|
||||
var raw = JSON.parse(lsGet(k) || 'null'), arr, ts = null;
|
||||
if (Array.isArray(raw)) arr = raw; // старый формат (без метки времени)
|
||||
else if (raw && Array.isArray(raw.c)) { arr = raw.c; ts = raw.t; }
|
||||
else return;
|
||||
if (ts && (Date.now() - ts) > CHAT_TTL) { clearChatStore(); return; } // протух — забываем
|
||||
_chat = arr.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) {
|
||||
@@ -598,7 +610,7 @@
|
||||
'<div class="asst-ask-row"><input class="asst-ask-in" type="text" placeholder="' + MODE_PH.answer + '" maxlength="500" />' +
|
||||
'<button class="asst-send" type="button" title="Отправить" aria-label="Отправить"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 2 11 13"/><path d="M22 2 15 22l-4-9-9-4 20-7z"/></svg></button></div>' +
|
||||
'<div class="asst-memnote">' + _svg('<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/><path d="M12 7v5l4 2"/>') +
|
||||
'<span>Держу в голове ход беседы — последние <b>~14 сообщений</b>. Диалог сохраняется между заходами и обновлениями страницы, пока ты сам не нажмёшь «Очистить».</span></div>', {});
|
||||
'<span>Держу в голове ход беседы — последние <b>~14 сообщений</b>. Диалог сохраняется между заходами, пока ты сам не нажмёшь «Очистить» или пока не пройдёт неделя без общения.</span></div>', {});
|
||||
var inp = bubble.querySelector('.asst-ask-in');
|
||||
var chatEl = bubble.querySelector('.asst-chat');
|
||||
var chipsEl = bubble.querySelector('.asst-chips');
|
||||
|
||||
Reference in New Issue
Block a user