Spaces:
Sleeping
Sleeping
| document.addEventListener('DOMContentLoaded', function() { | |
| const searchInput = document.getElementById('keyword-input'); | |
| const apiKey = document.getElementById('apikey-input'); | |
| const limitInput = document.getElementById("limit-input"); | |
| const searchButton = document.getElementById('search-button'); | |
| const researchButton = document.getElementById('plan-button'); | |
| const limitCheckbox = document.getElementById("limit-check"); | |
| const popupText = document.querySelector(".scrollable-text"); | |
| const popupTitle = document.getElementById("popup-title"); | |
| const body = document.body; | |
| const resultsContainer = document.getElementById('results-container'); | |
| async function performResearch() { | |
| const keyword = searchInput.value.trim(); | |
| let limit = limitInput.value.trim(); | |
| if (!keyword) { | |
| resultsContainer.innerHTML = '<div class="error-message">Please enter a search keyword.</div>'; | |
| return; | |
| } | |
| if (!limit){ | |
| limit = 15; | |
| } | |
| // Show loading indicator | |
| resultsContainer.innerHTML = '<div class="loading">Generating research plan about "' + keyword + '"...</div>'; | |
| try { | |
| const response = await fetch('/search/plan', { | |
| method: 'POST', | |
| headers: { | |
| 'Accept': 'application/json', | |
| 'Content-Type': 'application/json', | |
| "GROQ_TOKEN": apiKey.value | |
| }, | |
| body: JSON.stringify({ | |
| model: "llama-3.3-70b-versatile", | |
| user: keyword, | |
| }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| if (data.error) { | |
| resultsContainer.innerHTML = `<div class="error-message">Error: ${data.message}</div>`; | |
| return; | |
| } | |
| displayPlan(data.message.plan); | |
| } catch (error) { | |
| console.error('Search error:', error); | |
| resultsContainer.innerHTML = `<div class="error-message">Error performing generation: ${error.message}</div>`; | |
| } | |
| } | |
| async function performSearch() { | |
| const keyword = searchInput.value.trim(); | |
| let limit = limitInput.value.trim(); | |
| if (!keyword) { | |
| resultsContainer.innerHTML = '<div class="error-message">Please enter a search keyword.</div>'; | |
| return; | |
| } | |
| if (!limit){ | |
| limit = 15; | |
| } | |
| // Show loading indicator | |
| resultsContainer.innerHTML = '<div class="loading">Searching for ' + limit.toString() + ' papers about "' + keyword + '"...</div>'; | |
| try { | |
| const response = await fetch('/search', { | |
| method: 'POST', | |
| headers: { | |
| 'Accept': 'application/json', | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| keyword: keyword, | |
| limit: limit | |
| }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| if (data.error) { | |
| resultsContainer.innerHTML = `<div class="error-message">Search error: ${data.message}</div>`; | |
| return; | |
| } | |
| displayResults(data.message); | |
| } catch (error) { | |
| console.error('Search error:', error); | |
| resultsContainer.innerHTML = `<div class="error-message">Error performing search: ${error.message}</div>`; | |
| } | |
| } | |
| function handleCustomLimit(){ | |
| if(limitCheckbox.checked){ | |
| limitInput.removeAttribute("disabled") | |
| } else { | |
| limitInput.value = 15; | |
| limitInput.setAttribute("disabled", "") | |
| } | |
| } | |
| function displayPlan(results) { | |
| console.log(results); | |
| resultsContainer.innerHTML = ''; | |
| if (!results || Object.keys(results).length === 0) { | |
| resultsContainer.innerHTML = '<div class="error-message">Try again !</div>'; | |
| return; | |
| } | |
| const resultsCount = Object.keys(results).length; | |
| const resultsHeader = document.createElement('h2'); | |
| resultsHeader.textContent = `Got ${resultsCount} steps to follow`; | |
| resultsContainer.appendChild(resultsHeader); | |
| Object.entries(results).forEach(([id, step]) => { | |
| const stepElement = document.createElement('div'); | |
| stepElement.classList.add('paper-result'); | |
| stepElement.innerHTML = ` | |
| <div class="paper-title">Step no. ${step.step_index}</div> | |
| <div class="paper-abstract">${step.step_text}</div> | |
| <div class="paper-id">Keywords: ${step.keywords}</div> | |
| `; | |
| resultsContainer.appendChild(stepElement); | |
| }) | |
| } | |
| function displayResults(results) { | |
| resultsContainer.innerHTML = ''; | |
| if (!results || Object.keys(results).length === 0) { | |
| resultsContainer.innerHTML = '<div class="error-message">No results found. Try a different keyword.</div>'; | |
| return; | |
| } | |
| const resultsCount = Object.keys(results).length; | |
| const resultsHeader = document.createElement('h2'); | |
| resultsHeader.textContent = `Found ${resultsCount} paper${resultsCount > 1 ? 's' : ''}`; | |
| resultsContainer.appendChild(resultsHeader); | |
| Object.entries(results).forEach(([id, paper]) => { | |
| const paperElement = document.createElement('div'); | |
| paperElement.classList.add('paper-result'); | |
| // Format the abstract to preserve line breaks | |
| const formattedAbstract = paper.abstract; | |
| paperElement.innerHTML = ` | |
| <div class="paper-title">${paper.title}</div> | |
| <div class="paper-authors">${paper.authors}</div> | |
| <div class="paper-date">Published: ${paper.date}</div> | |
| <div class="paper-abstract">${formattedAbstract}</div> | |
| <div class="paper-id">ArXiv ID: ${id}</div> | |
| <a type="button" class="btn btn-primary" role="button" href="${paper.pdf}">Show PDF</a> | |
| <input type="button" value="Extract Text" doc="${id}" class="extractText btn btn-success"/> | |
| `; | |
| resultsContainer.appendChild(paperElement); | |
| }); | |
| document.querySelectorAll(".extractText").forEach(btn => { | |
| btn.addEventListener("click", async function () { | |
| let id_doc = btn.getAttribute("doc"); | |
| popupTitle.textContent = `PDF extraction - Document no ${id_doc}`; | |
| try { | |
| const response = await fetch('/extract_pdf/arxiv_id', { | |
| method: 'POST', | |
| headers: { | |
| 'Accept': 'application/json', | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| doc_id: id_doc | |
| }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| if (data.error) { | |
| popupText.innerHTML = `<div class="error-message">Search error: ${data.message}</div>`; | |
| return; | |
| } | |
| text = ""; | |
| popupText.textContent = data.message.text; | |
| } catch (error) { | |
| console.error('Search error:', error); | |
| popupText.innerHTML = `<div class="error-message">Error performing search: ${error.message}</div>`; | |
| } | |
| document.getElementById("popup").style.display = "flex"; | |
| body.classList.add("no-scroll") | |
| }); | |
| }) | |
| } | |
| // Add event listeners | |
| document.querySelector(".close").addEventListener("click", () => { | |
| document.getElementById("popup").style.display = "none"; | |
| body.classList.remove("no-scroll"); | |
| }) | |
| window.addEventListener("click", function (event) { | |
| if (event.target === popup) { | |
| popup.style.display = "none"; | |
| body.classList.remove("no-scroll"); | |
| } | |
| }); | |
| searchButton.addEventListener('click', performSearch); | |
| researchButton.addEventListener('click', performResearch); | |
| limitCheckbox.addEventListener("change", handleCustomLimit); | |
| searchInput.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') performSearch(); | |
| }); | |
| }); |