File size: 11,290 Bytes
e0b680e
 
 
 
 
505874e
e0b680e
 
505874e
e0b680e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505874e
e0b680e
6b12097
e0b680e
 
6b12097
e0b680e
 
6b12097
e0b680e
 
 
505874e
e0b680e
 
505874e
e0b680e
 
 
505874e
e0b680e
 
 
 
 
 
 
6b12097
e0b680e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505874e
e0b680e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505874e
aa52203
e0b680e
 
 
 
 
6b12097
e0b680e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6b12097
e0b680e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f54ef0b
e0b680e
7964505
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f54ef0b
7964505
 
f54ef0b
7964505
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f54ef0b
7964505
 
 
 
 
 
 
 
 
 
 
f54ef0b
7964505
f54ef0b
7964505
 
f54ef0b
505874e
94b470f
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
"""
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