""" Hugging Face Spaces Entry Point for CSRC Car Manual RAG System This is the entry point for Hugging Face Spaces deployment Note: For local development, use main.py instead. """ import os import sys from pathlib import Path # Detect if running in Hugging Face Spaces IS_SPACES = os.getenv("SPACE_ID") is not None or os.getenv("HF_SPACE") is not None # Add the current directory to Python path for Spaces environment sys.path.insert(0, str(Path(__file__).parent)) from openai import OpenAI from src.config import Config from src.vector_store import VectorStoreManager from src.rag_query import RAGQueryEngine from src.question_generator import QuestionGenerator from src.knowledge_graph import KnowledgeGraphGenerator from src.gradio_interface import GradioInterfaceBuilder # Import personalized learning if available try: from modules.personalized_learning import UserProfilingSystem, LearningPathGenerator, AdaptiveLearningEngine PERSONALIZED_LEARNING_AVAILABLE = True except ImportError: PERSONALIZED_LEARNING_AVAILABLE = False print("⚠️ Personalized learning modules not available") # Import proactive learning if available try: from modules.proactive_learning import ProactiveLearningEngine PROACTIVE_LEARNING_AVAILABLE = True except ImportError: PROACTIVE_LEARNING_AVAILABLE = False print("⚠️ Proactive learning modules not available") # Import scenario contextualization if available try: from modules.scenario_contextualization.database.scenario_database import ScenarioDatabase from modules.scenario_contextualization.integration.feature_extractor import ADASFeatureExtractor from modules.scenario_contextualization.retrieval.scenario_retriever import ScenarioRetriever from modules.scenario_contextualization.formatting.constructive_formatter import ConstructiveFormatter from modules.scenario_contextualization.integration.enhanced_rag_engine import EnhancedRAGEngine SCENARIO_CONTEXTUALIZATION_AVAILABLE = True except ImportError as e: SCENARIO_CONTEXTUALIZATION_AVAILABLE = False print(f"⚠️ Scenario contextualization modules not available: {e}") def initialize_system(config: Config) -> dict: """Initialize the RAG system components""" # Initialize OpenAI client if not config.openai_api_key: raise ValueError( "OPENAI_API_KEY not found! Please set it in Hugging Face Spaces Secrets. " "Go to Settings > Secrets and add OPENAI_API_KEY" ) client = OpenAI(api_key=config.openai_api_key) # Initialize vector store manager vector_store_manager = VectorStoreManager(client) # Get or create vector store vector_store_id = config.get_vector_store_id() if not vector_store_id: print("📦 Creating new vector store...") pdf_files = config.get_pdf_files() if not pdf_files: raise ValueError(f"No PDF files found in {config.car_manual_dir}") vector_store_details = vector_store_manager.create_vector_store(config.vector_store_name) if not vector_store_details: raise RuntimeError("Failed to create vector store") vector_store_id = vector_store_details["id"] config.save_vector_store_id(vector_store_id, config.vector_store_name) # Upload files upload_stats = vector_store_manager.upload_pdf_files(pdf_files, vector_store_id) if upload_stats["successful_uploads"] == 0: raise RuntimeError("Failed to upload any files") else: print(f"✅ Using existing vector store: {vector_store_id}") # Initialize RAG query engine rag_engine = RAGQueryEngine(client, vector_store_id, config.model) # Initialize question generator question_generator = QuestionGenerator(client, rag_engine) # Initialize knowledge graph generator knowledge_graph = KnowledgeGraphGenerator(client, vector_store_id, str(config.output_dir)) # Initialize personalized learning (if available) user_profiling = None learning_path_generator = None adaptive_engine = None if PERSONALIZED_LEARNING_AVAILABLE: try: user_profiling = UserProfilingSystem() learning_path_generator = LearningPathGenerator(user_profiling, config.available_topics) adaptive_engine = AdaptiveLearningEngine(user_profiling, learning_path_generator) print("✅ Personalized Learning System initialized!") except Exception as e: print(f"⚠️ Error initializing Personalized Learning System: {e}") # Initialize proactive learning (if available) proactive_engine = None if PROACTIVE_LEARNING_AVAILABLE and user_profiling: try: proactive_engine = ProactiveLearningEngine( client, rag_engine, user_profiling, adaptive_engine, config.available_topics ) print("✅ Proactive Learning Assistance initialized!") except Exception as e: print(f"⚠️ Error initializing Proactive Learning Assistance: {e}") # Initialize scenario contextualization (if available) enhanced_rag_engine = None if SCENARIO_CONTEXTUALIZATION_AVAILABLE: try: scenario_database = ScenarioDatabase() feature_extractor = ADASFeatureExtractor(use_llm=False, client=client) scenario_retriever = ScenarioRetriever( scenario_database=scenario_database, scenario_vector_store_id=None, client=client ) formatter = ConstructiveFormatter() enhanced_rag_engine = EnhancedRAGEngine( base_rag_engine=rag_engine, scenario_retriever=scenario_retriever, feature_extractor=feature_extractor, formatter=formatter ) print("✅ Scenario Contextualization initialized!") except Exception as e: print(f"⚠️ Error initializing Scenario Contextualization: {e}") import traceback traceback.print_exc() return { "client": client, "vector_store_manager": vector_store_manager, "rag_engine": rag_engine, "question_generator": question_generator, "knowledge_graph": knowledge_graph, "user_profiling": user_profiling, "learning_path_generator": learning_path_generator, "adaptive_engine": adaptive_engine, "proactive_engine": proactive_engine, "enhanced_rag_engine": enhanced_rag_engine, "config": config } def create_app(): """Create and return the Gradio app for Hugging Face Spaces""" print("=" * 60) print("🚗 CSRC Car Manual RAG System - Hugging Face Spaces") print("=" * 60) # Load configuration config = Config() # Initialize system try: components = initialize_system(config) except Exception as e: print(f"❌ Error initializing system: {e}") import gradio as gr # Create error interface error_msg = f""" # ❌ Initialization Error **Error:** {str(e)} **Possible solutions:** 1. Check if OPENAI_API_KEY is set in Spaces Secrets (Settings > Secrets) 2. Ensure PDF files are in the `car_manual/` directory 3. Check the logs for more details """ def error_display(): return error_msg error_interface = gr.Interface( fn=error_display, inputs=None, outputs=gr.Markdown(), title="CSRC Car Manual RAG System", description="An error occurred during initialization. Please check the logs." ) return error_interface # Build Gradio interface print("\n🌐 Building Gradio interface...") try: interface_builder = GradioInterfaceBuilder( rag_engine=components["rag_engine"], question_generator=components["question_generator"], knowledge_graph=components["knowledge_graph"], config=components["config"], user_profiling=components["user_profiling"], adaptive_engine=components["adaptive_engine"], proactive_engine=components["proactive_engine"] ) # Create interface print("Creating Gradio Blocks...") demo = interface_builder.create_interface() print("✅ Gradio interface created successfully!") return demo except Exception as e: print(f"❌ Error building Gradio interface: {e}") import traceback traceback.print_exc() # Return a simple error interface import gradio as gr error_demo = gr.Interface( fn=lambda: f"Error building interface: {str(e)}", inputs=None, outputs="text", title="CSRC Car Manual RAG System - Interface Error" ) return error_demo # Create the app for Hugging Face Spaces # Spaces will automatically detect Gradio and run this # The demo variable must be exposed at module level for Spaces to detect it # Initialize demo to None first demo = None # Only initialize once (prevent duplicate initialization) if demo is None: try: print("🔄 Starting app initialization...") demo = create_app() print("✅ App created successfully!") print(f"✅ Demo type: {type(demo)}") print(f"✅ Demo object: {demo}") # Verify demo is a valid Gradio Blocks object if demo is None: raise ValueError("Demo object is None after creation") if not hasattr(demo, 'launch'): raise ValueError("Demo object does not have launch method") except Exception as e: print(f"❌ Fatal error creating app: {e}") import traceback traceback.print_exc() # Create a minimal error interface import gradio as gr def show_error(): return f""" # ❌ Application Error **Fatal Error:** {str(e)} Please check: 1. OPENAI_API_KEY is set in Spaces Secrets 2. All required files are uploaded 3. Check the logs for detailed error information **Traceback:** ``` {traceback.format_exc()} ``` """ demo = gr.Interface( fn=show_error, inputs=None, outputs=gr.Markdown(), title="CSRC Car Manual RAG System - Error", description="An error occurred. Please check the logs." ) # Final verification if demo is None: import gradio as gr demo = gr.Interface( fn=lambda: "Application failed to initialize. Please check the logs.", inputs=None, outputs="text", title="CSRC Car Manual RAG System - Initialization Failed" ) # Note: Do NOT call demo.launch() here # Hugging Face Spaces will automatically detect and launch the demo # The demo variable is exposed at module level, which is what Spaces expects