arnel8888's picture
Added project files
cc8152f verified
Raw
History Blame Contribute Delete
4.47 kB
# PDF Explainer Chatbot - Upload PDFs and ask questions about their content
import gradio as gr
from typing import List, Generator, Dict, Any, Tuple
from llm import chat_with_assistant_rag, SYSTEM_MESSAGE
from retrieval import access_chroma_collection, parse_pdf, add_documents
# Global collection name
COLLECTION_NAME = "pdf_collection"
def handle_pdf_upload(files: List[Any]) -> str:
"""
Process uploaded PDF files and add them to the Chroma collection.
Args:
files (List[Any]): List of uploaded file objects
Returns:
str: Status message about the upload process
"""
if not files:
return "No files uploaded."
try:
processed_files = []
for file in files:
# Parse the PDF
pages = parse_pdf(file.name)
if pages:
# Add documents to collection
add_documents(COLLECTION_NAME, pages)
processed_files.append(file.name.split('/')[-1]) # Get filename only
if processed_files:
file_list = ", ".join(processed_files)
return f"βœ… Successfully processed and indexed: {file_list}. The documents are now available for questions!"
else:
return "❌ Failed to process the uploaded files. Please check the file format."
except Exception as e:
return f"❌ Error processing files: {str(e)}"
def respond(message: str, history: List[Dict[str, Any]]) -> Generator[str, None, None]:
"""
Handle user messages and return streaming responses with RAG.
Args:
message (str): User message
history (List[Dict[str, Any]]): Conversation history
Yields:
str: Streaming response chunks
"""
if not message.strip():
yield "Please enter a message."
return
# Get the streaming generator and yield each response
for partial_response in chat_with_assistant_rag(message, history, COLLECTION_NAME):
yield partial_response
# Create the chatbot interface with file upload
with gr.Blocks(title = "PDF Explainer Chatbot") as demo:
gr.Markdown("# πŸ“„ PDF Explainer Chatbot")
gr.Markdown("""
**I'm an AI assistant that can help you with general questions and analyze PDF documents you upload.**
- πŸ’¬ **Chat normally**: Ask me anything, even without uploading PDFs
- πŸ“€ **Upload PDFs**: Add documents anytime to get document-specific answers
- πŸ”„ **Multiple uploads**: You can upload more PDFs during our conversation
- 🎯 **Smart retrieval**: I'll automatically find relevant content from your PDFs when answering questions
""")
# File upload component
with gr.Row():
file_upload = gr.File(
label = "πŸ“„ Upload PDF Documents (Optional)",
file_count = "multiple",
file_types = [".pdf"],
type = "filepath",
height = 100
)
upload_button = gr.Button("πŸš€ Process PDFs", variant = "primary", size = "sm")
# Upload status
upload_status = gr.Textbox(label = "Upload Status", interactive = False, visible = False)
# Chat interface
chatbot = gr.ChatInterface(
fn = respond,
type = "messages",
title = "πŸ’¬ Chat",
description = "Ask me anything! If you've uploaded PDFs, I'll use them to provide more accurate answers."
)
# Handle file upload
def show_status_and_process(files: List[Any]) -> tuple[str, Dict[str, Any]]:
"""
Process files and show status.
Args:
files (List[Any]): List of uploaded file objects
Returns:
tuple[str, Dict[str, Any]]: Status message and visibility update
"""
result = handle_pdf_upload(files)
return result, gr.update(visible = True)
upload_button.click(
fn = show_status_and_process,
inputs = [file_upload],
outputs = [upload_status, upload_status]
)
if __name__ == "__main__":
# Initialize the Chroma collection
collection = access_chroma_collection(COLLECTION_NAME)
print(f"βœ… Initialized collection: {COLLECTION_NAME}")
# Enable queuing for streaming support
demo.queue().launch(server_name = "0.0.0.0", server_port = 7860)