feat(assistant): источники в ответах, режим-наставник, оценки, утренний бриф
- Источники: RAG возвращает sources (slug/§/ref), под ответом ссылка «по учебнику X, §N» на параграф (миграция 064: section_ref в textbook_chunks; headless-индексатор его заполняет). Статический индексатор теперь не затирает headless-данные. - Режим-наставник: переключатель Ответ/Подсказка/Проверить решение в «Спроси» (mode в ask + промпт); на карточке экзамена кнопка «Подсказка» (mode hint). - Оценка ответов: лайк/дизлайк под ответом (assistant_feedback) + сводка в админке. - Утренний бриф на дашборде: «занимался N из 5 дн + план на сегодня». Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -900,9 +900,15 @@ function getAssistant(_req, res) {
|
||||
const s = db.prepare("SELECT COALESCE(SUM(model_calls),0) model_calls, COALESCE(SUM(cache_hits),0) cache_hits, COALESCE(SUM(faq),0) faq FROM assistant_usage WHERE day > date('now','-30 days')").get();
|
||||
if (s) usage30 = s;
|
||||
} catch (e) {}
|
||||
let feedback = { up: 0, down: 0, recent: [] };
|
||||
try {
|
||||
const f = db.prepare("SELECT COALESCE(SUM(CASE WHEN rating=1 THEN 1 ELSE 0 END),0) up, COALESCE(SUM(CASE WHEN rating=-1 THEN 1 ELSE 0 END),0) down FROM assistant_feedback WHERE created_at > date('now','-30 days')").get();
|
||||
if (f) { feedback.up = f.up; feedback.down = f.down; }
|
||||
feedback.recent = db.prepare("SELECT q, created_at FROM assistant_feedback WHERE rating=-1 AND q IS NOT NULL AND q <> '' ORDER BY id DESC LIMIT 5").all();
|
||||
} catch (e) {}
|
||||
res.json({
|
||||
url, model, hasKey, keyFromEnv: !dbKey && !!process.env.ASSISTANT_LLM_KEY, active: !!(hasKey || local),
|
||||
rag: _aset('assistant_rag') !== '0', chunks, usage, usage30, presets: ASSISTANT_PRESETS,
|
||||
rag: _aset('assistant_rag') !== '0', chunks, usage, usage30, feedback, presets: ASSISTANT_PRESETS,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user