feat(assistant): контекст урока/страницы для Квантика (фича 2/6)
Квантик теперь знает, где находится ученик: - pageHint() — лёгкий ситуативный контекст («ученик на странице учебник: «Физика 7, §12»») подмешивается к ЛЮБОМУ свободному вопросу автоматически - getPageContext() расширен с учебника на уроки (theory/course/lesson): «Объяснить этот урок / Конспект урока / Флешкарты из урока» - метки чипов адаптируются (параграф/урок) Бэкенд уже принимал context (pageCtx) — правок не потребовалось. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -480,12 +480,35 @@
|
||||
var h = sec.querySelector('.sec-h');
|
||||
var title = (h && h.textContent.trim()) || (document.title || 'Параграф').split('·')[0].trim();
|
||||
var text = (sec.textContent || '').replace(/\s+/g, ' ').trim().slice(0, 3500);
|
||||
if (text.length > 40) return { title: title, text: text };
|
||||
if (text.length > 40) return { title: title, text: text, kind: 'textbook' };
|
||||
}
|
||||
}
|
||||
if (PAGE === 'theory') {
|
||||
var c = document.querySelector('.lesson-content, .lsn-content, .lesson-body, #lesson-content, article.lesson, .course-lesson, .lesson-view');
|
||||
if (c) {
|
||||
var lt = document.querySelector('h1, .lsn-title, .lesson-title');
|
||||
var ltitle = (lt && lt.textContent.trim()) || (document.title || 'Урок').split('·')[0].trim();
|
||||
var ltext = (c.textContent || '').replace(/\s+/g, ' ').trim().slice(0, 3500);
|
||||
if (ltext.length > 60) return { title: ltitle, text: ltext, kind: 'lesson' };
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
return null;
|
||||
}
|
||||
// Лёгкий ситуативный контекст для ЛЮБОГО вопроса — где сейчас ученик (заголовок+раздел).
|
||||
var PAGE_LABEL = { textbook: 'учебник', theory: 'урок/курс', exam: 'экзамен или тест', flashcards: 'флешкарты',
|
||||
lab: 'лаборатория', homework: 'домашние задания', dashboard: 'главная', knowledge: 'карта знаний',
|
||||
library: 'библиотека', analytics: 'аналитика', gradebook: 'журнал', qbank: 'банк вопросов' };
|
||||
function pageHint() {
|
||||
try {
|
||||
var label = PAGE_LABEL[PAGE] || '';
|
||||
var hEl = document.querySelector('.sec.active .sec-h, h1, .lsn-title, .lesson-title, .page-title');
|
||||
var title = (hEl && hEl.textContent.trim()) || (document.title || '').split('·')[0].split('|')[0].trim();
|
||||
title = title.replace(/\s+/g, ' ').slice(0, 120);
|
||||
if (!title && !label) return '';
|
||||
return 'Ученик сейчас на странице платформы' + (label ? ' («' + label + '»)' : '') + (title ? ': «' + title + '»' : '') + '. Учитывай это, если вопрос относится к материалу страницы.';
|
||||
} catch (e) { return ''; }
|
||||
}
|
||||
|
||||
/* ── «Спроси Квантика» ───────────────────────────────────────────────── */
|
||||
var SUGGESTIONS = ['Как вырезать кусок учебника?', 'Как создать карточки?', 'Как начать тест?', 'Объясни теорему Пифагора', 'Где мои домашние задания?', 'Как включить тёмную тему?'];
|
||||
@@ -508,11 +531,13 @@
|
||||
var MODE_PH = { answer: 'Спроси что угодно: «объясни…», «как…»', hint: 'Задача, по которой нужна подсказка…', check: 'Вставь своё решение — проверю…', draw: 'Опиши картинку: «кот-учёный, плоская иллюстрация»' };
|
||||
function openAsk(prefill) {
|
||||
var sel = _lastSel, pc = getPageContext();
|
||||
var noun = pc && pc.kind === 'lesson' ? 'этот урок' : 'этот параграф';
|
||||
var noun2 = pc && pc.kind === 'lesson' ? 'урока' : 'параграфа';
|
||||
var ctxBtns = '';
|
||||
if (sel) ctxBtns += '<button class="asst-chip asst-chip-ctx" data-ctx="sel" type="button">Объяснить выделенное</button>';
|
||||
if (pc) ctxBtns += '<button class="asst-chip asst-chip-ctx" data-ctx="sec" type="button">Объяснить этот параграф</button>' +
|
||||
'<button class="asst-chip asst-chip-ctx" data-ctx="sum" type="button">Конспект параграфа</button>' +
|
||||
'<button class="asst-chip asst-chip-ctx" data-ctx="cards" type="button">Флешкарты из параграфа</button>';
|
||||
if (pc) ctxBtns += '<button class="asst-chip asst-chip-ctx" data-ctx="sec" type="button">Объяснить ' + noun + '</button>' +
|
||||
'<button class="asst-chip asst-chip-ctx" data-ctx="sum" type="button">Конспект ' + noun2 + '</button>' +
|
||||
'<button class="asst-chip asst-chip-ctx" data-ctx="cards" type="button">Флешкарты из ' + noun2 + '</button>';
|
||||
var sug = (_role === 'teacher' || _role === 'admin') ? TEACHER_SUGGESTIONS : SUGGESTIONS;
|
||||
var chips = '<div class="asst-chips">' + ctxBtns +
|
||||
sug.map(function (q) { return '<button class="asst-chip" type="button">' + esc(q) + '</button>'; }).join('') + '</div>';
|
||||
@@ -534,7 +559,8 @@
|
||||
var mode = 'answer';
|
||||
renderChat(chatEl);
|
||||
if (_chat.length) chipsEl.style.display = 'none';
|
||||
function go(q, context, m) { if (chipsEl) chipsEl.style.display = 'none'; inp.value = ''; send(q, context, chatEl, m || mode); }
|
||||
// свободный вопрос (context не задан явно) → подмешиваем лёгкий ситуативный контекст страницы
|
||||
function go(q, context, m) { if (chipsEl) chipsEl.style.display = 'none'; inp.value = ''; if (context == null) context = pageHint() || undefined; send(q, context, chatEl, m || mode); }
|
||||
inp.addEventListener('keydown', function (e) { if (e.key === 'Enter') go(inp.value); });
|
||||
bubble.querySelectorAll('.asst-mode').forEach(function (b) {
|
||||
b.addEventListener('click', function () {
|
||||
|
||||
Reference in New Issue
Block a user