Select Git revision
.gitattributes
-
SeeBasTStick authoredSeeBasTStick authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
index.js 3.82 KiB
import { sendMessage } from './modules/ui.js';
import { tokenizeText } from './modules/semanticSearch.js';
import { extractFAQfromHTML } from './modules/faqData.js';
import { loadEmbedding, removeOutdatedEntries } from './modules/embeddings.js'
import { handleWorker, processQuery } from './modules/workerInterface.js'
const worker = new Worker('./worker.js', { type: 'module' });
/** get the up to date FAQ from site */
const textData = await extractFAQfromHTML("https://www.heicad.hhu.de/lehre/masters-programme-ai-and-data-science/faq/");
/** import precompiled embeddings and check for missing entries */
let embeddingStack = await loadEmbedding('largeEmbedding', './embeddings/largeEmbedding.json');
let tokenEmbeddingStack = await loadEmbedding('smallEmbedding', './embeddings/smallEmbedding.json');
/** throw out embeddings for entries not present on site any more */
const checkFAQ = new Set(textData.map(faq => faq.qPlusA));
removeOutdatedEntries(embeddingStack, checkFAQ);
const checkTokensAnswer = new Set();
textData.forEach(faq => tokenizeText(faq.answer).forEach(token => checkTokensAnswer.add(token)));
removeOutdatedEntries(tokenEmbeddingStack, checkTokensAnswer);
/** load up to date embeddings into local browser storage */
localStorage.setItem('largeEmbedding', JSON.stringify(embeddingStack));
localStorage.setItem('smallEmbedding', JSON.stringify(tokenEmbeddingStack));
/** handeling results iframe */
const inputElement = document.getElementById('user-input');
const resultsIframe = parent.document.getElementById('resultsIframe');
inputElement.addEventListener('input', function (event) {
const query = event.target.value.trim();
const results = resultsIframe.contentDocument || resultsIframe.contentWindow.document;
const resultsContainer = results.getElementById('results');
/** hide results when no query is typed */
if (!query) {
resultsContainer.innerHTML = '';
setTimeout(() => {
resultsIframe.style.display = 'none';
}, 500);
return;
}
resultsIframe.style.display = 'block';
resultsContainer.innerHTML = '';
processQuery(query, worker, function (outputs) {
outputs.forEach(output => {
const resultLink = results.createElement('a');
resultLink.href = 'javascript:void(0);';
resultLink.className = 'result';
resultLink.style.display = 'block';
/** display question text in result iframe */
const questionDiv = results.createElement('div');
questionDiv.className = 'result-question';
questionDiv.innerHTML = `<strong>${output.question}</strong>`;
resultLink.appendChild(questionDiv);
/** display our most relevant token to question in result iframe */
const bestTokenDiv = results.createElement('div');
bestTokenDiv.className = 'result-token';
let tokenText = output.bestToken;
/** shorten our best token; only 100 chars displayed*/
if (tokenText.length > 100) {
tokenText = tokenText.substring(0, 100);
}
tokenText = '> ' + tokenText + ' ...';
bestTokenDiv.textContent = tokenText;
resultLink.appendChild(bestTokenDiv);
resultLink.onclick = function () {
linkToPanel(output.buttonId, output.akkordeonId, output.bestToken);
};
resultsContainer.appendChild(resultLink);
});
});
});
/** search for query on enter press and put it in chat */
document.getElementById('user-input').addEventListener('keypress', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
sendMessage(worker);
}
});
worker.onmessage = (events) => handleWorker(events);
/** show results in chat window if "save" is clicked */
function saveMessage(){
return sendMessage(worker);
}
window.saveMessage = saveMessage;
/** give worker work */
worker.postMessage({ act: 'initialize', textData, embeddingStack, tokenEmbeddingStack });