feat(assistant): индексация системы из админки — Квантик знает актуальные модули

Кнопка «Сохранить и проиндексировать систему» в /admin#assistant собирает снимок:
- статус модулей по фича-флагам (что ВКЛЮЧЕНО/ВЫКЛЮЧЕНО сейчас) + каталог разделов;
- редактируемое «Описание системы» админа.
Снимок кладётся в app_settings.assistant_system_kb и подмешивается в ответы:
systemContext(q) ищет по знаниям (стем-префикс под русскую морфологию) и
добавляет в контекст — Квантик опирается на актуальное состояние и не предлагает
отключённое.

Бэкенд: MODULE_CATALOG + buildSystemKb + indexSystem (POST /admin/assistant/index-system),
saveAssistant(+systemDoc), getAssistant(+systemDoc/Count/At), systemContext в ask и askStream.
Клиент: LS.adminAssistantIndexSystem. Без миграции (хранение в app_settings).
Проверено: логика снимка/поиска 5/5, node --check всех файлов.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-24 21:27:53 +03:00
parent 64ea552cf8
commit 08da26afca
5 changed files with 108 additions and 2 deletions
+2 -1
View File
@@ -1186,7 +1186,7 @@ window.LS = {
assistantContext, assistantSeen, assistantDismiss, assistantSettings, assistantAsk, assistantAskStream, assistantFlashcards, assistantQuestions, assistantFeedback, assistantMemory, assistantMemoryClear, imageGen, imageGenStatus,
adminGetAssistant, adminSaveAssistant, adminTestAssistant, adminReindexTextbooks,
adminSaveProvider, adminDeleteProvider, adminSetActiveProvider, adminAssistantModels,
adminAssistantScan, adminAssistantProbe, adminAssistantApplyModels, adminAssistantHealth,
adminAssistantScan, adminAssistantProbe, adminAssistantApplyModels, adminAssistantHealth, adminAssistantIndexSystem,
fcListDecks, fcCreateDeck, fcAddCard, fcStudySession, fcReview,
prepListTracks, prepMyTracks, prepStudentTracks, prepSetStudent, prepUnsetStudent, prepClassStatus, prepSetClass,
escapeHtml, esc,
@@ -1477,6 +1477,7 @@ async function adminAssistantScan(id) { return req('POST', '/admin/assista
async function adminAssistantProbe(id, model) { return req('POST', '/admin/assistant/probe', { id, model }); }
async function adminAssistantApplyModels(models, reset) { return req('POST', '/admin/assistant/models/apply', reset ? { reset: true } : { models }); }
async function adminAssistantHealth() { return req('POST', '/admin/assistant/health', {}); }
async function adminAssistantIndexSystem() { return req('POST', '/admin/assistant/index-system', {}); }
async function fcListDecks() { return req('GET', '/flashcards/decks'); }
async function fcCreateDeck(d) { return req('POST', '/flashcards/decks', d); }
async function fcAddCard(deckId, d) { return req('POST', `/flashcards/decks/${deckId}/cards`, d); }