Spaces:
Runtime error
Runtime error
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>PDF Chatbot</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="icon" href="favicon.ico" type="image/x-icon"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" | |
| referrerpolicy="no-referrer"> | |
| </head> | |
| <body class="m-0 bg-white"> | |
| <div class="bg-gradient-to-b from-indigo-200 via-white to-indigo-100"> | |
| <div class="bg-gradient-to-b from-indigo-50 via-white to-indigo-100"> | |
| <!-- Header --> | |
| <header class="fixed inset-x-0 top-0 z-50 bg-white/70 backdrop-blur-md shadow-sm"> | |
| <div class="max-w-7xl mx-auto px-6 py-3 flex items-center justify-between"> | |
| <a href="/" class="text-xl sm:text-2xl font-bold tracking-tight text-indigo-600"> | |
| AskBot.AI | |
| </a> | |
| <nav class="hidden sm:flex items-center space-x-6 text-sm font-medium"> | |
| <a href="#chat" class="text-gray-600 hover:text-indigo-600 transition">Chat</a> | |
| <a href="#features" class="text-gray-600 hover:text-indigo-600 transition">Features</a> | |
| <a href="#tech" class="text-gray-600 hover:text-indigo-600 transition">Tech</a> | |
| <a href="#connect" class="text-gray-600 hover:text-indigo-600 transition">Connect</a> | |
| </nav> | |
| <button class="sm:hidden inline-flex items-center justify-center h-8 w-8 text-gray-600 hover:text-indigo-600"> | |
| <svg fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> | |
| </svg> | |
| </button> | |
| </div> | |
| </header> | |
| <!-- /Header --> | |
| <!-- <main class=""> --> | |
| <section> | |
| <div class="bg-white"> | |
| <!-- <div class="relative isolate overflow-hidden bg-gradient-to-b from-gray-200/50"> --> | |
| <div class="mx-auto max-w-7xl pb-16 pt-4 sm:pb-24 lg:grid lg:grid-cols-2 lg:gap-x-8 lg:px-8 lg:py-10"> | |
| <div class="px-6 lg:px-0 lg:pt-4"> | |
| <div class="mx-auto max-w-2xl"> | |
| <div class="max-w-lg"> | |
| <h1 class="mt-10 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl">Upload PDFs, <br> | |
| Research Papers & <br> Ask me Anything!!!</h1> | |
| <p class="mt-6 text-lg leading-8 text-gray-600">My chatbot reads your research paper | |
| or any PDFs and answers questions using AI model.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-20 lg:mt-0 flex justify-center items-center"> | |
| <img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751450446/giphy_sab0e8.webp" | |
| class="drop-shadow-2xl" height="350" width="550" alt="chatbot image"> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Chat Section --> | |
| <section id="chat" class="py-20"> | |
| <div class="max-w-6xl mx-auto px-6"> | |
| <div class="text-center mb-10"> | |
| <h2 class="text-3xl font-bold text-gray-800">Chat With Your PDF</h2> | |
| <p class="mt-2 text-gray-600 text-sm">Upload a research paper and ask any question. Powered by AI.</p> | |
| </div> | |
| <div id="uploadChatCard" class="bg-white shadow-xl border border-gray-200 rounded-xl p-6 space-y-6"> | |
| <div id="uploader" class="space-y-4 text-center"> | |
| <div class="flex items-center justify-center gap-4 flex-col sm:flex-row"> | |
| <label for="pdfFile" | |
| class="cursor-pointer bg-indigo-500 hover:bg-indigo-600 text-white px-6 py-2 rounded shadow text-sm transition"> | |
| Choose PDF | |
| </label> | |
| <span id="fileNameDisplayText" class="text-sm text-gray-600 italic">No file chosen</span> | |
| <input id="pdfFile" type="file" accept=".pdf" class="hidden"> | |
| </div> | |
| <button id="btnUpload" disabled class="bg-indigo-500 hover:bg-indigo-600 text-white px-6 py-2 rounded"> | |
| Upload PDF | |
| </button> | |
| </div> | |
| <!-- Chat Interface --> | |
| <div id="chatInterface" class="hidden space-y-4"> | |
| <div class="flex justify-between items-center max-w-3xl mx-auto"> | |
| <div id="fileNameDisplay" class="text-sm text-gray-600 font-medium italic"></div> | |
| <button id="reuploadBtn" class="text-sm text-indigo-600 hover:underline"> | |
| Upload Another PDF | |
| </button> | |
| </div> | |
| <!-- Summarize Section --> | |
| <div class="mt-6"> | |
| <div class="mt-2 flex items-start gap-3"> | |
| <button id="btnSummarize" | |
| class="bg-indigo-500 hover:bg-indigo-600 text-white px-4 py-2 rounded disabled:opacity-50" disabled> | |
| Summarize PDF | |
| </button> | |
| <div id="summaryBox" | |
| class="flex-1 max-h-64 overflow-y-auto text-sm text-gray-700 p-3 border rounded bg-gray-50 hidden"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Chat Box --> | |
| <div id="chatBox" | |
| class="space-y-3 max-w-3xl max-h-96 overflow-y-auto px-4 py-4 border rounded-lg bg-white shadow-inner mx-auto"> | |
| </div> | |
| <form id="chatForm" class="flex max-w-3xl mx-auto"> | |
| <input id="msgInput" autocomplete="off" placeholder="Ask a question..." | |
| class="flex-1 rounded-l-lg border-gray-300 px-4 py-3 shadow" /> | |
| <button class="bg-indigo-500 hover:bg-indigo-600 text-white px-6 rounded-r-lg"> | |
| Send | |
| </button> | |
| </form> | |
| </div> | |
| </div> | |
| <!-- Result --> | |
| {% if results %} | |
| <div class="mt-6 bg-white p-6 rounded-lg shadow border border-gray-200"> | |
| <h2 class="text-lg font-semibold text-gray-800 mb-2">Answer:</h2> | |
| <p class="text-gray-700 whitespace-pre-wrap">{{ results }}</p> | |
| </div> | |
| {% endif %} | |
| </div> | |
| </section> | |
| <!-- Features Section --> | |
| <section id="features" class="py-20"> | |
| <div class="max-w-7xl mx-auto px-6"> | |
| <div class="text-center mb-12"> | |
| <h2 class="text-3xl font-bold text-gray-800">Features</h2> | |
| <p class="mt-2 text-gray-600 text-sm">What makes our PDF Chatbot stand out</p> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-8"> | |
| <!-- Instant PDF Reading --> | |
| <div | |
| class="bg-white bg-opacity-80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751357240/feature_img_1_nhlopv.jpg" | |
| alt="Feature 1" class="mx-auto h-28 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">Instant PDF Understanding</h3> | |
| <p class="text-sm text-gray-600">Ask any question and get accurate responses | |
| based on the uploaded PDF content in seconds.</p> | |
| </div> | |
| <!-- Multiple File-Type Support --> | |
| <div | |
| class="bg-white bg-opacity-80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751357240/feature_img_2_b8feaa.jpg" | |
| alt="Feature 2" class="mx-auto h-28 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">Multiple File-Type Support</h3> | |
| <p class="text-sm text-gray-600">Upload research papers, eBooks, or reports — | |
| the chatbot can handle various types of academic PDFs.</p> | |
| </div> | |
| <!-- AI-Powered Accuracy --> | |
| <div | |
| class="bg-white bg-opacity-80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751357580/feature_img_3_qeecda.jpg" | |
| alt="Feature 3" class="mx-auto h-28 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">AI-Powered Accuracy</h3> | |
| <p class="text-sm text-gray-600">Built with powerful AI models to understand complex contexts, summaries, | |
| and | |
| in-depth queries.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ========== Tech Stack & AI Models ========== --> | |
| <!-- <section id="tech" class="py-20"> | |
| <div class="max-w-7xl mx-auto px-6"> | |
| <div class="text-center mb-12"> | |
| <h2 class="text-3xl font-bold text-gray-800">Tech Stack & AI Models</h2> | |
| <p class="mt-2 text-gray-600 text-sm"> | |
| The key Technologies and AI models that power this chatbot | |
| </p> | |
| </div> --> | |
| <!-- Python and Flask --> | |
| <!-- <div class="grid grid-cols-1 md:grid-cols-3 gap-8"> | |
| <div | |
| class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://cdn-icons-png.flaticon.com/512/5968/5968350.png" alt="Python Flask" | |
| class="mx-auto h-20 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">Python & Flask</h3> | |
| <p class="text-sm text-gray-600">Handles backend, file uploads & AI Responses.</p> | |
| </div> --> | |
| <!-- LangChain --> | |
| <!-- <div | |
| class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751439498/download_wabh02.png" alt="LangChain" | |
| class="mx-auto h-20 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">LangChain</h3> | |
| <p class="text-sm text-gray-600">LangChain manages PDF processing & LLM calls.</p> | |
| </div> --> | |
| <!-- Embeddings --> | |
| <!-- <div | |
| class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" alt="MiniLM Embeddings" | |
| class="mx-auto h-20 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">Embedding Model: all-MiniLM-L6-v2 </h3> | |
| <p class="text-sm text-gray-600">Converts Text into Numerical Vectors.</p> | |
| </div> --> | |
| <!-- FAISS --> | |
| <!-- <div | |
| class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751439632/download_so6va6.png" alt="FAISS" | |
| class="mx-auto h-20 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">FAISS Vector Store</h3> | |
| <p class="text-sm text-gray-600">Enables Fast Similarity Search of vectors in PDFs.</p> | |
| </div> --> | |
| <!-- LLM --> | |
| <!-- <div | |
| class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751520819/download_cbh1yx.jpg" alt="Mixtral LLM" | |
| class="mx-auto h-20 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">LLM: llama-3.1-8b-instant</h3> | |
| <p class="text-sm text-gray-600">Generates correct answers from extracted PDF chunks.</p> | |
| </div> --> | |
| <!-- Tailwind CSS --> | |
| <!-- <div | |
| class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl"> | |
| <img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751439818/download_qgtwpn.png" | |
| alt="Tailwind CSS" class="mx-auto h-20 mb-4 object-contain" /> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-2">Tailwind CSS</h3> | |
| <p class="text-sm text-gray-600">Stylish and fully responsive frontend.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> --> | |
| <!-- </main> --> | |
| </div> | |
| <!-- ========== Connect / Footer Section ========== --> | |
| <footer id="connect" class="w-full bg-gray-900 text-gray-300"> | |
| <div class="max-w-7xl mx-auto px-6 py-8 text-center"> | |
| <h2 class="text-3xl font-bold text-white mb-2">Connect With Me</h2> | |
| <p class="text-gray-400 mb-8">Feel free to reach out on any platform!</p> | |
| <div class="flex justify-center space-x-8 text-2xl"> | |
| <!-- LinkedIn --> | |
| <a href="https://www.linkedin.com/in/om-more-b802b2281/" target="_blank" rel="noopener noreferrer" | |
| class="hover:text-blue-400 transition"> | |
| <i class="fa-brands fa-linkedin"></i> | |
| </a> | |
| <!-- GitHub --> | |
| <a href="https://github.com/ommore86/" target="_blank" rel="noopener noreferrer" | |
| class="hover:text-white transition"> | |
| <i class="fa-brands fa-github"></i> | |
| </a> | |
| <!-- Email --> | |
| <a href="mailto:omgmore2005@gmail.com" class="hover:text-red-400 transition"> | |
| <i class="fa-solid fa-envelope"></i> | |
| </a> | |
| </div> | |
| <div class="mt-10 border-t border-gray-700 pt-6 text-sm text-gray-500"> | |
| © 2025 Om More | All rights reserved | |
| </div> | |
| </footer> | |
| <script> | |
| let fileId = null; | |
| const pdfInput = document.getElementById("pdfFile"); | |
| const btnUpload = document.getElementById("btnUpload"); | |
| pdfInput.onchange = () => { | |
| const file = pdfInput.files[0]; | |
| if (file) { | |
| document.getElementById("fileNameDisplayText").textContent = file.name; | |
| btnUpload.disabled = false; | |
| } else { | |
| document.getElementById("fileNameDisplayText").textContent = "No file chosen"; | |
| btnUpload.disabled = true; | |
| } | |
| }; | |
| btnUpload.onclick = async () => { | |
| const file = pdfInput.files[0]; | |
| const formData = new FormData(); | |
| formData.append("file", file); | |
| btnUpload.disabled = true; | |
| btnUpload.textContent = "Uploading…"; | |
| const res = await fetch("/upload", { method: "POST", body: formData }); | |
| const data = await res.json(); | |
| if (res.ok) { | |
| fileId = data.file_id; | |
| document.getElementById("fileNameDisplay").textContent = pdfInput.files[0].name; | |
| document.getElementById("uploader").classList.add("hidden"); | |
| document.getElementById("chatInterface").classList.remove("hidden"); | |
| document.getElementById("fileNameDisplay").textContent = `📄 ${file.name}`; | |
| } else { | |
| alert(data.error || "Upload failed"); | |
| btnUpload.disabled = false; | |
| btnUpload.textContent = "Upload PDF"; | |
| } | |
| }; | |
| // Chat logic | |
| const chatBox = document.getElementById("chatBox"); | |
| const chatForm = document.getElementById("chatForm"); | |
| const msgInput = document.getElementById("msgInput"); | |
| chatForm.addEventListener("submit", async e => { | |
| e.preventDefault(); | |
| const q = msgInput.value.trim(); | |
| if (!q) return; | |
| appendBubble(q, "user"); | |
| msgInput.value = ""; | |
| // Showing bubble while waiting | |
| const thinkingBubble = addThinkingBubble(); | |
| let answerText = ""; | |
| try { | |
| const res = await fetch("/ask", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ question: q, file_id: fileId }), | |
| }); | |
| const data = await res.json(); | |
| answerText = data.answer || data.error; | |
| } catch (err) { | |
| answerText = "Error fetching answer."; | |
| } | |
| // Replacing placeholder text | |
| thinkingBubble.textContent = answerText; | |
| }); | |
| function appendBubble(text, who) { | |
| const bubble = document.createElement("div"); | |
| bubble.className = `w-fit rounded-2xl px-5 py-3 shadow break-words | |
| ${who === "user" | |
| ? "ml-auto bg-indigo-500 text-white" | |
| : "mr-auto bg-gray-200 text-gray-900"}`; | |
| bubble.textContent = text; | |
| chatBox.appendChild(bubble); | |
| chatBox.scrollTop = chatBox.scrollHeight; | |
| return bubble; | |
| } | |
| function addThinkingBubble() { | |
| const bubble = document.createElement("div"); | |
| bubble.className = "w-fit rounded-2xl px-5 py-3 shadow mr-auto bg-gray-200 text-gray-900"; | |
| bubble.innerHTML = `<span class="animate-pulse">Thinking…</span>`; | |
| chatBox.appendChild(bubble); | |
| chatBox.scrollTop = chatBox.scrollHeight; | |
| return bubble; | |
| } | |
| document.getElementById("reuploadBtn").onclick = () => { | |
| fileId = null; | |
| pdfInput.value = ""; | |
| document.getElementById("uploader").classList.remove("hidden"); | |
| document.getElementById("chatInterface").classList.add("hidden"); | |
| document.getElementById("fileNameDisplay").textContent = ""; | |
| document.getElementById("chatBox").innerHTML = ""; | |
| btnUpload.disabled = true; | |
| btnUpload.textContent = "Upload PDF"; | |
| }; | |
| // Sidebar toggle | |
| const sidebar = document.getElementById("sidebar"); | |
| const sidebarToggle = document.getElementById("sidebarToggle"); | |
| const sidebarFileName = document.getElementById("sidebarFileName"); | |
| const btnSummarize = document.getElementById("btnSummarize"); | |
| const summaryBox = document.getElementById("summaryBox"); | |
| sidebarToggle.onclick = () => { | |
| sidebar.classList.toggle("-translate-x-full"); | |
| }; | |
| // Update sidebar filename when file is uploaded | |
| btnUpload.onclick = async () => { | |
| const file = pdfInput.files[0]; | |
| const formData = new FormData(); | |
| formData.append("file", file); | |
| btnUpload.disabled = true; | |
| btnUpload.textContent = "Uploading…"; | |
| const res = await fetch("/upload", { method: "POST", body: formData }); | |
| const data = await res.json(); | |
| if (res.ok) { | |
| fileId = data.file_id; | |
| document.getElementById("fileNameDisplay").textContent = `📄 ${file.name}`; | |
| sidebarFileName.textContent = file.name; | |
| btnSummarize.disabled = false; | |
| document.getElementById("uploader").classList.add("hidden"); | |
| document.getElementById("chatInterface").classList.remove("hidden"); | |
| } else { | |
| alert(data.error || "Upload failed"); | |
| btnUpload.disabled = false; | |
| btnUpload.textContent = "Upload PDF"; | |
| } | |
| }; | |
| // Summarize logic | |
| btnSummarize.onclick = async () => { | |
| if (!window.currentFileId) { | |
| summaryBox.textContent = "⚠️ Please upload a PDF first."; | |
| summaryBox.classList.remove("hidden"); | |
| return; | |
| } | |
| btnSummarize.disabled = true; | |
| btnSummarize.textContent = "Summarizing…"; | |
| summaryBox.textContent = "⏳ Generating summary..."; | |
| summaryBox.classList.remove("hidden"); | |
| try { | |
| const res = await fetch("/summarize", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ file_id: window.currentFileId }), | |
| }); | |
| const data = await res.json(); | |
| if (res.ok) { | |
| summaryBox.textContent = data.summary || "No summary available."; | |
| } else { | |
| summaryBox.textContent = "❌ " + (data.error || "Summarization failed."); | |
| } | |
| } catch (err) { | |
| summaryBox.textContent = "❌ Error summarizing file."; | |
| } | |
| btnSummarize.disabled = false; | |
| btnSummarize.textContent = "Summarize PDF"; | |
| }; | |
| </script> | |
| </body> | |
| </html> |