Update app.py
Browse files
app.py
CHANGED
@@ -9,11 +9,11 @@ from calendar_rag import (
|
|
9 |
create_default_config,
|
10 |
AcademicCalendarRAG,
|
11 |
PipelineConfig,
|
12 |
-
ModelConfig,
|
13 |
-
RetrieverConfig,
|
14 |
-
CacheConfig,
|
15 |
-
ProcessingConfig,
|
16 |
-
LocalizationConfig
|
17 |
)
|
18 |
# Custom CSS for enhanced styling
|
19 |
def load_custom_css():
|
@@ -93,28 +93,28 @@ def load_custom_css():
|
|
93 |
</style>
|
94 |
""", unsafe_allow_html=True)
|
95 |
|
96 |
-
|
97 |
def initialize_pipeline():
|
98 |
-
"""Initialize RAG pipeline with
|
99 |
try:
|
|
|
100 |
openai_api_key = os.getenv('OPENAI_API_KEY') or st.secrets['OPENAI_API_KEY']
|
101 |
|
102 |
-
# Create
|
103 |
config = create_default_config(openai_api_key)
|
104 |
|
105 |
-
#
|
106 |
-
config.model.embedder_model = "sentence-transformers/paraphrase-multilingual-mpnet-base-v2"
|
107 |
-
config.model.openai_model = "gpt-4o"
|
108 |
-
|
109 |
pipeline = AcademicCalendarRAG(config)
|
110 |
|
111 |
-
# Load
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
|
|
|
|
|
|
118 |
except Exception as e:
|
119 |
st.error(f"Error initializing pipeline: {str(e)}")
|
120 |
return None
|
@@ -293,35 +293,55 @@ def add_to_history(role: str, message: str):
|
|
293 |
add_to_qa_history(user_query, message)
|
294 |
|
295 |
def display_chat_history():
|
296 |
-
"""Display chat history with
|
297 |
-
for
|
298 |
if role == "user":
|
299 |
st.markdown(f"""
|
300 |
<div class="chat-message user-message">
|
301 |
<strong>🧑 คำถาม:</strong><br>
|
302 |
-
{
|
303 |
</div>
|
304 |
""", unsafe_allow_html=True)
|
305 |
else:
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
312 |
|
313 |
if 'context_memory' not in st.session_state:
|
314 |
st.session_state.context_memory = []
|
315 |
|
316 |
def handle_submit(user_query: str):
|
317 |
-
"""
|
318 |
if not user_query:
|
319 |
st.warning("⚠️ กรุณาระบุคำถาม")
|
320 |
return
|
321 |
|
322 |
user_query = user_query.strip()
|
323 |
|
324 |
-
# Prevent duplicate submissions
|
325 |
if not st.session_state.chat_history or st.session_state.chat_history[-1][1] != user_query:
|
326 |
try:
|
327 |
st.session_state.processing_query = True
|
@@ -329,35 +349,26 @@ def handle_submit(user_query: str):
|
|
329 |
# Add user message to chat history
|
330 |
st.session_state.chat_history.append(("user", user_query))
|
331 |
|
332 |
-
#
|
333 |
with st.spinner("🔍 กำลังค้นหาคำตอบ..."):
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
# Build query with context
|
339 |
-
query_with_context = "\n".join(
|
340 |
-
[f"Q: {qa['query']}\nA: {qa['answer']}" for qa in st.session_state.context_memory]
|
341 |
-
) + f"\nQ: {user_query}"
|
342 |
-
|
343 |
-
# Process query
|
344 |
-
result = st.session_state.pipeline.process_query(query_with_context)
|
345 |
|
346 |
-
# Create response
|
347 |
response_dict = {
|
348 |
"answer": result.get("answer", ""),
|
349 |
-
"documents": result.get("
|
350 |
}
|
351 |
|
352 |
# Update chat history and context
|
353 |
st.session_state.chat_history.append(("assistant", response_dict))
|
354 |
-
st.session_state.context_memory.append({"query": user_query, "answer": response_dict})
|
355 |
-
|
356 |
-
# Save to QA history
|
357 |
add_to_qa_history(user_query, response_dict)
|
358 |
|
359 |
except Exception as e:
|
360 |
-
|
|
|
361 |
st.error(f"Query processing error: {e}")
|
362 |
|
363 |
finally:
|
@@ -365,8 +376,7 @@ def handle_submit(user_query: str):
|
|
365 |
st.rerun()
|
366 |
|
367 |
def create_chat_input():
|
368 |
-
"""Create
|
369 |
-
# Create the form for chat input
|
370 |
with st.form(key="chat_form", clear_on_submit=True):
|
371 |
st.markdown("""
|
372 |
<label for="query_input" style="font-size: 1.2rem; font-weight: 600; margin-bottom: 1rem; display: block;">
|
@@ -376,18 +386,15 @@ def create_chat_input():
|
|
376 |
</label>
|
377 |
""", unsafe_allow_html=True)
|
378 |
|
379 |
-
# Text input
|
380 |
query = st.text_input(
|
381 |
"",
|
382 |
key="query_input",
|
383 |
-
placeholder="เช่น:
|
384 |
)
|
385 |
|
386 |
-
# Create two columns for buttons with a 7:3 ratio
|
387 |
col1, col2 = st.columns([7, 3])
|
388 |
|
389 |
with col1:
|
390 |
-
# Submit button in form
|
391 |
submitted = st.form_submit_button(
|
392 |
"📤 ส่งคำถาม",
|
393 |
type="primary",
|
@@ -395,7 +402,6 @@ def create_chat_input():
|
|
395 |
)
|
396 |
|
397 |
with col2:
|
398 |
-
# Clear history button inside the form
|
399 |
clear_button = st.form_submit_button(
|
400 |
"🗑️ ล้างประวัติ",
|
401 |
type="secondary",
|
@@ -435,12 +441,7 @@ def main():
|
|
435 |
if 'processing_query' not in st.session_state:
|
436 |
st.session_state.processing_query = False
|
437 |
|
438 |
-
#
|
439 |
-
if 'qa_history_loaded' not in st.session_state:
|
440 |
-
st.session_state.qa_history_loaded = True
|
441 |
-
load_qa_history()
|
442 |
-
|
443 |
-
# Initialize pipeline
|
444 |
if st.session_state.pipeline is None:
|
445 |
with st.spinner("กำลังเริ่มต้นระบบ..."):
|
446 |
st.session_state.pipeline = initialize_pipeline()
|
@@ -456,57 +457,25 @@ def main():
|
|
456 |
chat_col, info_col = st.columns([7, 3])
|
457 |
|
458 |
with chat_col:
|
459 |
-
|
460 |
-
for i, (role, content) in enumerate(st.session_state.chat_history):
|
461 |
-
if role == "user":
|
462 |
-
st.markdown(f"""
|
463 |
-
<div class="chat-message user-message">
|
464 |
-
<strong>🧑 คำถาม:</strong><br>
|
465 |
-
{content}
|
466 |
-
</div>
|
467 |
-
""", unsafe_allow_html=True)
|
468 |
-
else:
|
469 |
-
if isinstance(content, dict):
|
470 |
-
assistant_response = content.get('answer', '❌ ไม่มีข้อมูลคำตอบ')
|
471 |
-
else:
|
472 |
-
assistant_response = content
|
473 |
-
|
474 |
-
st.markdown(f"""
|
475 |
-
<div class="chat-message assistant-message">
|
476 |
-
<strong>🤖 คำตอบ:</strong><br>
|
477 |
-
{assistant_response}
|
478 |
-
</div>
|
479 |
-
""", unsafe_allow_html=True)
|
480 |
-
|
481 |
-
if isinstance(content, dict) and content.get('documents'):
|
482 |
-
with st.expander("📚 แสดงข้อมูลอ้างอิง", expanded=False):
|
483 |
-
for i, doc in enumerate(content['documents'], 1):
|
484 |
-
st.markdown(f"""
|
485 |
-
<div style="padding: 1rem; background-color: #000000; border-radius: 8px; margin: 0.5rem 0;">
|
486 |
-
<strong>เอกสารที่ {i}:</strong><br>
|
487 |
-
{doc.content}
|
488 |
-
</div>
|
489 |
-
""", unsafe_allow_html=True)
|
490 |
-
|
491 |
-
# Create chat input using the new implementation
|
492 |
create_chat_input()
|
493 |
|
494 |
-
#
|
495 |
with info_col:
|
496 |
st.markdown("""
|
497 |
<div style="background-color: #F9FAFB; padding: 1.5rem; border-radius: 12px; margin-bottom: 2rem;">
|
498 |
<h3 style="color: #1E3A8A;">ℹ️ เกี่ยวกับระบบ</h3>
|
499 |
<p style="color: #000000;">
|
500 |
ระบบนี้ใช้เทคโนโลยี <strong>RAG (Retrieval-Augmented Generation)</strong>
|
501 |
-
|
502 |
</p>
|
503 |
<h4 style="color: #1E3A8A; margin-top: 1rem;">สามารถสอบถามข้อมูลเกี่ยวกับ:</h4>
|
504 |
<ul style="list-style-type: none; padding-left: 0;">
|
505 |
-
<li style="color: #000000; margin-bottom: 0.5rem;"
|
506 |
-
<li style="color: #000000; margin-bottom: 0.5rem;">🎯 วันสำคัญและกิจกรรม</li>
|
507 |
<li style="color: #000000; margin-bottom: 0.5rem;">📝 การลงทะเบียนเรียน</li>
|
508 |
-
<li style="color: #000000; margin-bottom: 0.5rem;"
|
509 |
-
<li style="color: #000000; margin-bottom: 0.5rem;"
|
|
|
510 |
</ul>
|
511 |
</div>
|
512 |
""", unsafe_allow_html=True)
|
|
|
9 |
create_default_config,
|
10 |
AcademicCalendarRAG,
|
11 |
PipelineConfig,
|
12 |
+
ModelConfig,
|
13 |
+
RetrieverConfig,
|
14 |
+
CacheConfig,
|
15 |
+
ProcessingConfig,
|
16 |
+
LocalizationConfig
|
17 |
)
|
18 |
# Custom CSS for enhanced styling
|
19 |
def load_custom_css():
|
|
|
93 |
</style>
|
94 |
""", unsafe_allow_html=True)
|
95 |
|
|
|
96 |
def initialize_pipeline():
|
97 |
+
"""Initialize RAG pipeline with same configuration as main()"""
|
98 |
try:
|
99 |
+
# Get API key from environment or secrets
|
100 |
openai_api_key = os.getenv('OPENAI_API_KEY') or st.secrets['OPENAI_API_KEY']
|
101 |
|
102 |
+
# Create config with same settings as main()
|
103 |
config = create_default_config(openai_api_key)
|
104 |
|
105 |
+
# Create pipeline
|
|
|
|
|
|
|
106 |
pipeline = AcademicCalendarRAG(config)
|
107 |
|
108 |
+
# Load raw data instead of calendar.json
|
109 |
+
try:
|
110 |
+
with open("calendar.json", "r", encoding="utf-8") as f:
|
111 |
+
raw_data = json.load(f)
|
112 |
+
pipeline.load_data(raw_data)
|
113 |
+
return pipeline
|
114 |
+
except FileNotFoundError:
|
115 |
+
st.error("calendar.json not found. Please ensure the file exists in the same directory.")
|
116 |
+
return None
|
117 |
+
|
118 |
except Exception as e:
|
119 |
st.error(f"Error initializing pipeline: {str(e)}")
|
120 |
return None
|
|
|
293 |
add_to_qa_history(user_query, message)
|
294 |
|
295 |
def display_chat_history():
|
296 |
+
"""Display chat history with improved document display"""
|
297 |
+
for role, content in st.session_state.chat_history:
|
298 |
if role == "user":
|
299 |
st.markdown(f"""
|
300 |
<div class="chat-message user-message">
|
301 |
<strong>🧑 คำถาม:</strong><br>
|
302 |
+
{content}
|
303 |
</div>
|
304 |
""", unsafe_allow_html=True)
|
305 |
else:
|
306 |
+
if isinstance(content, dict):
|
307 |
+
assistant_response = content.get('answer', '❌ ไม่มีข้อมูลคำตอบ')
|
308 |
+
st.markdown(f"""
|
309 |
+
<div class="chat-message assistant-message">
|
310 |
+
<strong>🤖 คำตอบ:</strong><br>
|
311 |
+
{assistant_response}
|
312 |
+
</div>
|
313 |
+
""", unsafe_allow_html=True)
|
314 |
+
|
315 |
+
# Show reference documents like in main()
|
316 |
+
if content.get('documents'):
|
317 |
+
with st.expander("📚 ข้อมูลอ้างอิง", expanded=False):
|
318 |
+
for i, doc in enumerate(content['documents'], 1):
|
319 |
+
st.markdown(f"""
|
320 |
+
<div style="padding: 1rem; background-color: #000000; border-radius: 8px; margin: 0.5rem 0;">
|
321 |
+
<strong>เอกสารที่ {i}:</strong><br>
|
322 |
+
{doc.content}
|
323 |
+
</div>
|
324 |
+
""", unsafe_allow_html=True)
|
325 |
+
else:
|
326 |
+
st.markdown(f"""
|
327 |
+
<div class="chat-message assistant-message">
|
328 |
+
<strong>🤖 คำตอบ:</strong><br>
|
329 |
+
{content}
|
330 |
+
</div>
|
331 |
+
""", unsafe_allow_html=True)
|
332 |
|
333 |
if 'context_memory' not in st.session_state:
|
334 |
st.session_state.context_memory = []
|
335 |
|
336 |
def handle_submit(user_query: str):
|
337 |
+
"""Enhanced query handling matching main() functionality"""
|
338 |
if not user_query:
|
339 |
st.warning("⚠️ กรุณาระบุคำถาม")
|
340 |
return
|
341 |
|
342 |
user_query = user_query.strip()
|
343 |
|
344 |
+
# Prevent duplicate submissions
|
345 |
if not st.session_state.chat_history or st.session_state.chat_history[-1][1] != user_query:
|
346 |
try:
|
347 |
st.session_state.processing_query = True
|
|
|
349 |
# Add user message to chat history
|
350 |
st.session_state.chat_history.append(("user", user_query))
|
351 |
|
352 |
+
# Process query with semantic weight 0.3 (matching main())
|
353 |
with st.spinner("🔍 กำลังค้นหาคำตอบ..."):
|
354 |
+
result = st.session_state.pipeline.process_query(
|
355 |
+
query=user_query,
|
356 |
+
weight_semantic=0.3 # Match main() configuration
|
357 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
|
359 |
+
# Create response with same structure as main()
|
360 |
response_dict = {
|
361 |
"answer": result.get("answer", ""),
|
362 |
+
"documents": result.get("relevant_docs", [])
|
363 |
}
|
364 |
|
365 |
# Update chat history and context
|
366 |
st.session_state.chat_history.append(("assistant", response_dict))
|
|
|
|
|
|
|
367 |
add_to_qa_history(user_query, response_dict)
|
368 |
|
369 |
except Exception as e:
|
370 |
+
error_msg = f"❌ เกิดข้อผิดพลาด: {str(e)}"
|
371 |
+
st.session_state.chat_history.append(("assistant", error_msg))
|
372 |
st.error(f"Query processing error: {e}")
|
373 |
|
374 |
finally:
|
|
|
376 |
st.rerun()
|
377 |
|
378 |
def create_chat_input():
|
379 |
+
"""Create chat input with enhanced configuration"""
|
|
|
380 |
with st.form(key="chat_form", clear_on_submit=True):
|
381 |
st.markdown("""
|
382 |
<label for="query_input" style="font-size: 1.2rem; font-weight: 600; margin-bottom: 1rem; display: block;">
|
|
|
386 |
</label>
|
387 |
""", unsafe_allow_html=True)
|
388 |
|
|
|
389 |
query = st.text_input(
|
390 |
"",
|
391 |
key="query_input",
|
392 |
+
placeholder="เช่น: วิชาเลือกมีอะไรบ้าง?"
|
393 |
)
|
394 |
|
|
|
395 |
col1, col2 = st.columns([7, 3])
|
396 |
|
397 |
with col1:
|
|
|
398 |
submitted = st.form_submit_button(
|
399 |
"📤 ส่งคำถาม",
|
400 |
type="primary",
|
|
|
402 |
)
|
403 |
|
404 |
with col2:
|
|
|
405 |
clear_button = st.form_submit_button(
|
406 |
"🗑️ ล้างประวัติ",
|
407 |
type="secondary",
|
|
|
441 |
if 'processing_query' not in st.session_state:
|
442 |
st.session_state.processing_query = False
|
443 |
|
444 |
+
# Initialize pipeline with enhanced configuration
|
|
|
|
|
|
|
|
|
|
|
445 |
if st.session_state.pipeline is None:
|
446 |
with st.spinner("กำลังเริ่มต้นระบบ..."):
|
447 |
st.session_state.pipeline = initialize_pipeline()
|
|
|
457 |
chat_col, info_col = st.columns([7, 3])
|
458 |
|
459 |
with chat_col:
|
460 |
+
display_chat_history()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
461 |
create_chat_input()
|
462 |
|
463 |
+
# Info column
|
464 |
with info_col:
|
465 |
st.markdown("""
|
466 |
<div style="background-color: #F9FAFB; padding: 1.5rem; border-radius: 12px; margin-bottom: 2rem;">
|
467 |
<h3 style="color: #1E3A8A;">ℹ️ เกี่ยวกับระบบ</h3>
|
468 |
<p style="color: #000000;">
|
469 |
ระบบนี้ใช้เทคโนโลยี <strong>RAG (Retrieval-Augmented Generation)</strong>
|
470 |
+
ในการค้นหาและตอบคำถามเกี่ยวกับหลักสูตรและปฏิทินการศึกษา
|
471 |
</p>
|
472 |
<h4 style="color: #1E3A8A; margin-top: 1rem;">สามารถสอบถามข้อมูลเกี่ยวกับ:</h4>
|
473 |
<ul style="list-style-type: none; padding-left: 0;">
|
474 |
+
<li style="color: #000000; margin-bottom: 0.5rem;">📚 รายวิชาในหลักสูตร</li>
|
|
|
475 |
<li style="color: #000000; margin-bottom: 0.5rem;">📝 การลงทะเบียนเรียน</li>
|
476 |
+
<li style="color: #000000; margin-bottom: 0.5rem;">📅 กำหนดการต่างๆ</li>
|
477 |
+
<li style="color: #000000; margin-bottom: 0.5rem;">💰 ค่าธรรมเนียมการศึกษา</li>
|
478 |
+
<li style="color: #000000; margin-bottom: 0.5rem;">📋 ขั้นตอนการสมัคร</li>
|
479 |
</ul>
|
480 |
</div>
|
481 |
""", unsafe_allow_html=True)
|