| | |
| | """HuggingFace Spaces app for HPMOR Q&A System - Cloud deployment version.""" |
| |
|
| | import os |
| | import sys |
| | import gradio as gr |
| | from typing import List, Tuple |
| | from pathlib import Path |
| |
|
| | |
| | sys.path.insert(0, str(Path(__file__).parent)) |
| |
|
| | from src.config import config |
| | from src.document_processor import HPMORProcessor |
| | from src.vector_store import VectorStoreManager |
| | from src.rag_engine import RAGEngine |
| |
|
| | |
| | os.environ["FORCE_GROQ_ONLY"] = "1" |
| |
|
| |
|
| | class HFChatInterface: |
| | """Simplified chat interface for HuggingFace Spaces.""" |
| |
|
| | def __init__(self): |
| | """Initialize the chat interface.""" |
| | print("Initializing HPMOR Q&A Chat Interface for HuggingFace Spaces...") |
| |
|
| | |
| | processed_docs = config.processed_data_dir / "documents.json" |
| | if not processed_docs.exists(): |
| | print("Setting up system for first time...") |
| | self.setup_system() |
| |
|
| | |
| | self.engine = RAGEngine(force_recreate=False) |
| | print("System ready!") |
| |
|
| | def setup_system(self): |
| | """Set up the HPMOR Q&A system.""" |
| | print("Processing HPMOR document...") |
| | processor = HPMORProcessor() |
| | documents = processor.process(force_reprocess=False) |
| | print(f"Processed {len(documents)} chunks") |
| |
|
| | print("Creating vector index...") |
| | vector_store = VectorStoreManager() |
| | vector_store.get_or_create_index(documents, force_recreate=False) |
| | print("Setup complete!") |
| |
|
| | def format_sources(self, sources: List[dict]) -> str: |
| | """Format sources for display.""" |
| | if not sources: |
| | return "" |
| |
|
| | formatted = [] |
| | for i, source in enumerate(sources[:3], 1): |
| | formatted.append( |
| | f"**Source {i}** - Chapter {source['chapter_number']}: {source['chapter_title']}\n" |
| | f"Relevance: {source['score']:.2f}\n" |
| | f"*{source['text_preview'][:100]}...*" |
| | ) |
| | return "\n\n".join(formatted) |
| |
|
| | def process_message( |
| | self, |
| | message: str, |
| | history: List[List[str]], |
| | show_sources: bool |
| | ) -> Tuple[str, str]: |
| | """Process a chat message and return response.""" |
| | if not message: |
| | return "", "Please enter a question." |
| |
|
| | |
| | messages = [] |
| | for user_msg, assistant_msg in history: |
| | if user_msg: |
| | messages.append({"role": "user", "content": user_msg}) |
| | if assistant_msg: |
| | messages.append({"role": "assistant", "content": assistant_msg}) |
| | messages.append({"role": "user", "content": message}) |
| |
|
| | try: |
| | |
| | response = self.engine.chat(messages, stream=False) |
| |
|
| | |
| | if isinstance(response.get("answer"), str): |
| | answer = response["answer"] |
| | else: |
| | answer = str(response.get("answer", "No response generated")) |
| |
|
| | |
| | sources_text = "" |
| | if show_sources and response.get("sources"): |
| | sources_text = "\n\n---\n\n**π Sources from HPMOR:**\n\n" + self.format_sources(response["sources"]) |
| | answer = answer + sources_text |
| |
|
| | return answer, "" |
| |
|
| | except Exception as e: |
| | error_msg = f"I apologize, but I encountered an error: {str(e)}\n\nPlease make sure the Groq API key is properly configured." |
| | return error_msg, "" |
| |
|
| |
|
| | def create_interface() -> gr.Blocks: |
| | """Create the Gradio interface.""" |
| |
|
| | |
| | chat_interface = HFChatInterface() |
| |
|
| | with gr.Blocks(title="Chat with Harry Potter-Evans-Verres", theme=gr.themes.Soft()) as interface: |
| | gr.Markdown( |
| | """ |
| | # π§ββοΈ Chat with Harry James Potter-Evans-Verres |
| | |
| | Hello! I'm Harry Potter-Evans-Verres from "Harry Potter and the Methods of Rationality." |
| | Ask me anything about my adventures, experiments with magic, or my thoughts on rationality and science. |
| | I'll respond based on my experiences and the scientific method, of course! |
| | |
| | *Powered by RAG with ChromaDB and Groq API (llama-3.3-70b-versatile)* |
| | """ |
| | ) |
| |
|
| | with gr.Row(): |
| | with gr.Column(scale=3): |
| | chatbot = gr.Chatbot( |
| | label="Chat", |
| | height=500, |
| | show_copy_button=True, |
| | avatar_images=(None, "π§ββοΈ") |
| | ) |
| |
|
| | with gr.Row(): |
| | msg_input = gr.Textbox( |
| | label="Your Question", |
| | placeholder="Ask me anything... For example: 'What do you think about magic?' or 'Tell me about your experiments'", |
| | lines=2, |
| | scale=4 |
| | ) |
| | submit_btn = gr.Button("Send π¨", variant="primary", scale=1) |
| |
|
| | with gr.Column(scale=1): |
| | gr.Markdown("### βοΈ Settings") |
| |
|
| | show_sources = gr.Checkbox( |
| | value=True, |
| | label="Show Sources from Book" |
| | ) |
| |
|
| | gr.Markdown( |
| | """ |
| | ### π‘ Tips |
| | - Ask about Harry's experiments |
| | - Inquire about his views on magic |
| | - Ask about other characters |
| | - Request explanations of events |
| | """ |
| | ) |
| |
|
| | |
| | gr.Examples( |
| | examples=[ |
| | "Harry, how did you first react when you learned magic was real?", |
| | "What's your opinion on the way Hogwarts teaches magic?", |
| | "Can you explain your scientific experiments with magic?", |
| | "What do you think about Hermione?", |
| | "How do you apply rationality to magical problems?", |
| | "What's your relationship with Professor Quirrell like?", |
| | ], |
| | inputs=msg_input, |
| | label="π¬ Example Questions" |
| | ) |
| |
|
| | |
| | def respond(message, history, sources): |
| | """Handle message submission.""" |
| | answer, _ = chat_interface.process_message(message, history, sources) |
| | history.append([message, answer]) |
| | return "", history |
| |
|
| | msg_input.submit( |
| | respond, |
| | inputs=[msg_input, chatbot, show_sources], |
| | outputs=[msg_input, chatbot] |
| | ) |
| |
|
| | submit_btn.click( |
| | respond, |
| | inputs=[msg_input, chatbot, show_sources], |
| | outputs=[msg_input, chatbot] |
| | ) |
| |
|
| | gr.Markdown( |
| | """ |
| | --- |
| | |
| | **About:** This chatbot uses Retrieval-Augmented Generation (RAG) to answer questions |
| | based on "Harry Potter and the Methods of Rationality" by Eliezer Yudkowsky. |
| | |
| | **Note:** Requires a Groq API key. Get one free at [console.groq.com](https://console.groq.com/) |
| | """ |
| | ) |
| |
|
| | return interface |
| |
|
| |
|
| | if __name__ == "__main__": |
| | |
| | if not os.getenv("GROQ_API_KEY"): |
| | print("WARNING: GROQ_API_KEY not found in environment variables!") |
| | print("Please set it in your HuggingFace Space secrets.") |
| |
|
| | |
| | interface = create_interface() |
| | interface.launch( |
| | server_name="0.0.0.0", |
| | server_port=7860, |
| | share=False |
| | ) |
| |
|