datbkpro commited on
Commit
f0c67cd
·
verified ·
1 Parent(s): 47284c1

Update ui/tabs.py

Browse files
Files changed (1) hide show
  1. ui/tabs.py +495 -191
ui/tabs.py CHANGED
@@ -64,6 +64,310 @@ def create_all_tabs(audio_service: AudioService, chat_service: ChatService,
64
  create_language_info_tab(rag_system.multilingual_manager)
65
  with gr.Tab("Stream Object Detection"):
66
  create_streaming_object_detection()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  def create_gemini_realtime_tab():
68
  """Tạo tab cho Gemini Realtime API với Audio Streaming"""
69
 
@@ -283,204 +587,204 @@ def create_gemini_realtime_tab():
283
 
284
  return gemini_tab
285
 
286
- # FastAPI routes cho Gemini (tùy chọn)
287
- def create_cag_tab(rag_system: EnhancedRAGSystem, multilingual_manager: MultilingualManager):
288
- """Tạo tab CAG (Conversational Agent Grounding)"""
289
 
290
- # Khởi tạo conversational agent
291
- conversational_agent = ConversationalAgent(rag_system, multilingual_manager)
292
 
293
- with gr.Blocks() as cag_tab:
294
- gr.Markdown("## 🤖 Chatbot với Tri thức (CAG)")
295
- gr.Markdown("Chatbot thông minh sử dụng thông tin từ cơ sở tri thức RAG để trả lời chính xác")
296
-
297
- with gr.Row():
298
- with gr.Column(scale=2):
299
- # Chat interface
300
- chatbot = gr.Chatbot(
301
- label="🤖 CAG Chatbot",
302
- height=400,
303
- show_copy_button=True,
304
- bubble_full_width=False,
305
- avatar_images=(
306
- "https://cdn-icons-png.flaticon.com/512/1077/1077114.png", # User
307
- "https://cdn-icons-png.flaticon.com/512/4712/4712027.png" # Assistant
308
- )
309
- )
310
-
311
- with gr.Row():
312
- msg = gr.Textbox(
313
- label="Nhập câu hỏi",
314
- placeholder="Hỏi tôi về bất kỳ điều gì trong cơ sở tri thức...",
315
- scale=4,
316
- container=False
317
- )
318
- submit_btn = gr.Button("Gửi", variant="primary", scale=1)
319
- clear_btn = gr.Button("Xóa", variant="secondary", scale=1)
320
-
321
- # Additional info
322
- with gr.Row():
323
- lang_display = gr.Textbox(
324
- label="🌐 Ngôn ngữ phát hiện",
325
- interactive=False,
326
- scale=2
327
- )
328
- conv_stats_btn = gr.Button("📊 Thống kê", variant="secondary", scale=1)
329
-
330
- # Knowledge base stats
331
- with gr.Accordion("📊 Cơ sở tri thức", open=False):
332
- kb_stats = gr.Textbox(
333
- label="Thống kê",
334
- interactive=False,
335
- lines=4
336
- )
337
- refresh_kb_btn = gr.Button("🔄 Cập nhật", variant="secondary", size="sm")
338
 
339
- with gr.Column(scale=1):
340
- gr.Markdown("### 📚 Nguồn thông tin")
341
-
342
- # Knowledge sources from RAG
343
- sources_display = gr.JSON(
344
- label="Kết quả tìm kiếm từ RAG",
345
- show_label=True,
346
- container=True
347
- )
348
-
349
- # Conversation statistics
350
- conv_stats_display = gr.JSON(
351
- label="📈 Thống kê hội thoại",
352
- show_label=True,
353
- container=True
354
- )
355
-
356
- # Language info
357
- with gr.Accordion("🌐 Thông tin ngôn ngữ", open=False):
358
- lang_info_btn = gr.Button("ℹ️ Xem ngôn ngữ", variant="secondary", size="sm")
359
- lang_info_display = gr.JSON(
360
- label="Ngôn ngữ hỗ trợ",
361
- container=True
362
- )
363
-
364
- # Instructions
365
- with gr.Accordion("ℹ️ Hướng dẫn", open=False):
366
- gr.Markdown("""
367
- **Cách sử dụng CAG:**
368
- 1. Nhập câu hỏi vào ô chat
369
- 2. Bot tự động tìm trong cơ sở tri thức
370
- 3. Trả lời dựa trên thông tin tìm thấy
371
- 4. Xem nguồn thông tin bên phải
372
 
373
- **Đặc điểm:**
374
- - 🤖 Grounding từ RAG
375
- - 🔍 Tự động tìm kiếm
376
- - 🌐 Đa ngôn ngữ
377
- - 📊 Theo dõi nguồn
378
- """)
379
-
380
- def respond(message: str, chat_history: List[Tuple[str, str]]) -> Tuple[str, List, List, str]:
381
- """Xử lý phản hồi chatbot"""
382
- if not message.strip():
383
- return "", chat_history, [], "⏳ Chờ câu hỏi..."
384
 
385
- try:
386
- # Gọi conversational agent
387
- response, search_results = conversational_agent.process_query(message, chat_history)
388
-
389
- # Cập nhật chat history
390
- chat_history.append((message, response))
391
-
392
- # Phát hiện ngôn ngữ
393
- language = multilingual_manager.detect_language(message)
394
- lang_info = multilingual_manager.get_language_info(language)
395
- lang_name = lang_info.get('name', language)
396
-
397
- return "", chat_history, search_results, f"🌐 {lang_name}"
398
-
399
- except Exception as e:
400
- error_response = f"Xin lỗi, đã xảy ra lỗi: {str(e)}"
401
- chat_history.append((message, error_response))
402
- return "", chat_history, [{"error": str(e)}], "❌ Lỗi"
403
-
404
- def get_conversation_stats():
405
- """Lấy thống kê hội thoại"""
406
- return conversational_agent.get_conversation_stats()
407
-
408
- def get_kb_stats():
409
- """Lấy thống kê knowledge base"""
410
- stats = rag_system.get_collection_stats()
411
- lang_dist = stats['language_distribution']
412
- lang_dist_str = ", ".join([f"{k}: {v}" for k, v in lang_dist.items()])
413
 
414
- return f"""
415
- 📊 THỐNG KÊ CƠ SỞ TRI THỨC:
416
- • 📄 Tổng documents: {stats['total_documents']}
417
- • 🔤 Embeddings: {stats['embedding_count']}
418
- • 🌐 Ngôn ngữ: {lang_dist_str}
419
- • 📐 Dimension: {stats['embedding_dimension']}
420
- • 🏷️ Trạng thái: {stats['status']}
421
- """
422
-
423
- def get_language_info():
424
- """Lấy thông tin ngôn ngữ hỗ trợ"""
425
- return multilingual_manager.get_supported_languages()
426
-
427
- def clear_chat():
428
- """Xóa chat"""
429
- conversational_agent.clear_conversation_history()
430
- return [], [], "🧹 Đã xóa"
431
-
432
- def refresh_all():
433
- """Làm mới tất cả"""
434
- kb_stats_text = get_kb_stats()
435
- conv_stats = get_conversation_stats()
436
- lang_info = get_language_info()
437
- return kb_stats_text, conv_stats, lang_info
438
-
439
- # Event handlers
440
- submit_btn.click(
441
- respond,
442
- inputs=[msg, chatbot],
443
- outputs=[msg, chatbot, sources_display, lang_display]
444
- )
445
-
446
- msg.submit(
447
- respond,
448
- inputs=[msg, chatbot],
449
- outputs=[msg, chatbot, sources_display, lang_display]
450
- )
451
-
452
- clear_btn.click(
453
- clear_chat,
454
- inputs=[],
455
- outputs=[chatbot, sources_display, lang_display]
456
- )
457
-
458
- conv_stats_btn.click(
459
- get_conversation_stats,
460
- inputs=[],
461
- outputs=[conv_stats_display]
462
- )
463
-
464
- refresh_kb_btn.click(
465
- get_kb_stats,
466
- inputs=[],
467
- outputs=[kb_stats]
468
- )
469
-
470
- lang_info_btn.click(
471
- get_language_info,
472
- inputs=[],
473
- outputs=[lang_info_display]
474
- )
475
-
476
- # Initialize on load
477
- cag_tab.load(
478
- refresh_all,
479
- inputs=[],
480
- outputs=[kb_stats, conv_stats_display, lang_info_display]
481
- )
482
 
483
- return cag_tab
484
  def setup_gemini_routes(app):
485
  """Thiết lập routes FastAPI cho Gemini"""
486
 
 
64
  create_language_info_tab(rag_system.multilingual_manager)
65
  with gr.Tab("Stream Object Detection"):
66
  create_streaming_object_detection()
67
+ def create_cag_tab(rag_system, multilingual_manager):
68
+ """Tạo tab Cache-Augmented Generation"""
69
+
70
+ # Import CAG service
71
+ from services.cag_service import CAGService
72
+
73
+ # Initialize CAG service
74
+ cag_service = CAGService(rag_system, multilingual_manager)
75
+
76
+ with gr.Blocks() as cag_tab:
77
+ gr.Markdown("# 🔄 Cache-Augmented Generation (CAG)")
78
+ gr.Markdown("""
79
+ **CAG** tối ưu hóa RAG bằng caching thông minh:
80
+ - 🚀 **Tăng tốc độ** 10-100x với cache hit
81
+ - 💰 **Giảm chi phí** LLM API calls
82
+ - 🔍 **Semantic cache** cho queries tương tự
83
+ - 📊 **Performance tracking** chi tiết
84
+ """)
85
+
86
+ with gr.Row():
87
+ with gr.Column(scale=2):
88
+ # Query section
89
+ gr.Markdown("### 🔍 Tìm kiếm với Cache")
90
+
91
+ cag_query = gr.Textbox(
92
+ label="Nhập truy vấn",
93
+ placeholder="Ví dụ: thông tin về Hà Nội hoặc cách cải thiện sức khỏe...",
94
+ lines=2
95
+ )
96
+
97
+ with gr.Row():
98
+ search_btn = gr.Button("🔍 Tìm kiếm (với Cache)", variant="primary")
99
+ batch_btn = gr.Button("📊 Batch Search", variant="secondary")
100
+ clear_cache_btn = gr.Button("🗑️ Clear Cache", variant="stop")
101
+
102
+ # Configuration
103
+ with gr.Accordion("⚙️ Cấu hình Cache", open=False):
104
+ with gr.Row():
105
+ use_cache = gr.Checkbox(label="Sử dụng Cache", value=True)
106
+ top_k_slider = gr.Slider(1, 10, value=5, step=1, label="Số kết quả (Top K)")
107
+
108
+ with gr.Row():
109
+ semantic_cache = gr.Checkbox(label="Semantic Cache", value=True)
110
+ cache_ttl = gr.Slider(300, 86400, value=3600, step=300,
111
+ label="Cache TTL (giây)")
112
+
113
+ with gr.Column(scale=1):
114
+ # Stats section
115
+ gr.Markdown("### 📊 Thống kê Hiệu suất")
116
+ stats_btn = gr.Button("🔄 Cập nhật Thống kê", variant="secondary")
117
+ stats_output = gr.JSON(label="Thống kê Cache", show_label=True)
118
+
119
+ # Results display
120
+ with gr.Tab("📝 Kết quả Tìm kiếm"):
121
+ search_results = gr.JSON(label="Kết quả với Cache Info", show_label=True)
122
+
123
+ with gr.Tab("📈 Performance Analysis"):
124
+ with gr.Row():
125
+ response_time_chart = gr.Plot(label="Thời gian Phản hồi")
126
+ hit_rate_chart = gr.Plot(label="Cache Hit Rate")
127
+
128
+ performance_table = gr.Dataframe(
129
+ headers=["Query", "Cache Hit", "Response Time", "Language"],
130
+ label="Performance Log",
131
+ interactive=False
132
+ )
133
+
134
+ # Batch search section
135
+ with gr.Accordion("📊 Batch Search Mode", open=False):
136
+ batch_input = gr.Textbox(
137
+ label="Nhập nhiều queries (mỗi dòng một query)",
138
+ placeholder="Query 1\nQuery 2\nQuery 3\n...",
139
+ lines=6
140
+ )
141
+ batch_output = gr.JSON(label="Kết quả Batch")
142
+
143
+ # Cache management
144
+ with gr.Accordion("🛠️ Quản lý Cache", open=False):
145
+ with gr.Row():
146
+ cache_type = gr.Radio(
147
+ choices=["all", "memory", "semantic", "disk"],
148
+ value="memory",
149
+ label="Loại Cache cần xóa"
150
+ )
151
+ preload_btn = gr.Button("🔥 Pre-load Frequent Queries", variant="secondary")
152
+
153
+ cache_status = gr.Textbox(label="Trạng thái Cache", interactive=False)
154
+
155
+ # Performance tracking
156
+ performance_log = gr.State([])
157
+
158
+ # Event handlers
159
+ def perform_cag_search(query, use_cache_flag, top_k):
160
+ """Thực hiện tìm kiếm với CAG"""
161
+ if not query.strip():
162
+ return {"error": "Vui lòng nhập truy vấn"}
163
+
164
+ # Update cache config
165
+ cag_service.config.SEMANTIC_SIMILARITY_THRESHOLD = 0.85 if semantic_cache.value else 1.0
166
+
167
+ start_time = time.time()
168
+ result = cag_service.search_with_cache(
169
+ query=query,
170
+ top_k=top_k,
171
+ use_cache=use_cache_flag
172
+ )
173
+ elapsed_time = time.time() - start_time
174
+
175
+ # Update performance log
176
+ if 'performance_log' not in locals():
177
+ performance_log = []
178
+
179
+ performance_log.append({
180
+ "query": query[:50],
181
+ "cache_hit": result["cache_hit"],
182
+ "hit_type": result["hit_type"],
183
+ "response_time": result["response_time_ms"],
184
+ "language": result.get("language", "vi"),
185
+ "timestamp": time.strftime("%H:%M:%S")
186
+ })
187
+
188
+ # Keep only last 20 entries
189
+ if len(performance_log) > 20:
190
+ performance_log.pop(0)
191
+
192
+ return result, performance_log[-10:] # Return last 10 entries
193
+
194
+ def update_cache_stats():
195
+ """Cập nhật thống kê cache"""
196
+ stats = cag_service.get_cache_stats()
197
+
198
+ # Format nicely
199
+ formatted_stats = {
200
+ "📊 Tổng quan": {
201
+ "Tổng queries": stats["total_queries"],
202
+ "Cache hits": stats["cache_hits"],
203
+ "Cache misses": stats["cache_misses"],
204
+ "Hit rate": f"{stats['hit_rate']}%",
205
+ "Tiết kiệm ước tính": f"${stats['estimated_cost_savings_usd']}"
206
+ },
207
+ "⚡ Hiệu suất": {
208
+ "Thời gian phản hồi TB": f"{stats['avg_response_time_ms']}ms",
209
+ "P95 response time": f"{stats['p95_response_time_ms']}ms",
210
+ "Exact hits": stats["exact_hits"],
211
+ "Semantic hits": stats["semantic_hits"]
212
+ },
213
+ "💾 Cache Storage": {
214
+ "Memory cache size": stats["memory_cache_size"],
215
+ "Semantic cache size": stats["semantic_cache_size"]
216
+ }
217
+ }
218
+
219
+ return formatted_stats
220
+
221
+ def clear_cag_cache(cache_type_str):
222
+ """Xóa cache"""
223
+ try:
224
+ cag_service.clear_cache(cache_type_str)
225
+ return f"✅ Đã xóa {cache_type_str} cache!"
226
+ except Exception as e:
227
+ return f"❌ Lỗi: {str(e)}"
228
+
229
+ def batch_cag_search(queries_text, use_cache_flag):
230
+ """Batch search với CAG"""
231
+ if not queries_text.strip():
232
+ return {"error": "Vui lòng nhập queries"}
233
+
234
+ queries = [q.strip() for q in queries_text.split('\n') if q.strip()]
235
+ if len(queries) > 20:
236
+ return {"error": "Tối đa 20 queries mỗi lần"}
237
+
238
+ results = cag_service.batch_search_with_cache(queries, top_k=3)
239
+
240
+ # Format results
241
+ formatted_results = []
242
+ cache_hits = 0
243
+
244
+ for result in results:
245
+ formatted_result = {
246
+ "query": result["query"],
247
+ "cache_hit": result["cache_hit"],
248
+ "hit_type": result.get("hit_type", "none"),
249
+ "result_count": len(result.get("results", []))
250
+ }
251
+
252
+ if result["cache_hit"]:
253
+ cache_hits += 1
254
+
255
+ formatted_results.append(formatted_result)
256
+
257
+ summary = {
258
+ "total_queries": len(queries),
259
+ "cache_hits": cache_hits,
260
+ "cache_miss": len(queries) - cache_hits,
261
+ "hit_rate": f"{(cache_hits/len(queries))*100:.1f}%"
262
+ }
263
+
264
+ return {
265
+ "summary": summary,
266
+ "results": formatted_results
267
+ }
268
+
269
+ def preload_frequent_queries():
270
+ """Pre-load các queries phổ biến"""
271
+ frequent_queries = [
272
+ "Hà Nội thủ đô Việt Nam",
273
+ "cách cải thiện sức khỏe",
274
+ "ăn uống lành mạnh",
275
+ "tập thể dục đúng cách",
276
+ "vitamin và khoáng chất",
277
+ "du lịch Việt Nam",
278
+ "học tiếng Anh hiệu quả"
279
+ ]
280
+
281
+ for query in frequent_queries:
282
+ cag_service.search_with_cache(query, top_k=3, use_cache=False)
283
+
284
+ return f"✅ Đã pre-load {len(frequent_queries)} queries thường dùng"
285
+
286
+ def create_performance_charts(performance_data):
287
+ """Tạo biểu đồ performance"""
288
+ import matplotlib.pyplot as plt
289
+ import matplotlib
290
+ matplotlib.use('Agg')
291
+
292
+ if not performance_data:
293
+ return None, None
294
+
295
+ # Prepare data
296
+ queries = [p["query"] for p in performance_data]
297
+ response_times = [p["response_time"] for p in performance_data]
298
+ cache_hits = [1 if p["cache_hit"] else 0 for p in performance_data]
299
+
300
+ # Create response time chart
301
+ fig1, ax1 = plt.subplots(figsize=(10, 4))
302
+ bars = ax1.bar(queries, response_times,
303
+ color=['green' if hit else 'red' for hit in cache_hits])
304
+ ax1.set_xlabel('Query')
305
+ ax1.set_ylabel('Response Time (ms)')
306
+ ax1.set_title('Response Time with Cache Hits')
307
+ ax1.set_xticklabels(queries, rotation=45, ha='right')
308
+
309
+ # Add value labels
310
+ for bar, time_val in zip(bars, response_times):
311
+ ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 5,
312
+ f'{time_val:.0f}ms', ha='center', va='bottom', fontsize=8)
313
+
314
+ plt.tight_layout()
315
+
316
+ # Create hit rate chart
317
+ fig2, ax2 = plt.subplots(figsize=(6, 4))
318
+ hit_rate = sum(cache_hits) / len(cache_hits) * 100 if cache_hits else 0
319
+
320
+ labels = ['Cache Hits', 'Cache Misses']
321
+ sizes = [hit_rate, 100 - hit_rate]
322
+ colors = ['lightgreen', 'lightcoral']
323
+
324
+ ax2.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
325
+ ax2.axis('equal')
326
+ ax2.set_title(f'Cache Hit Rate: {hit_rate:.1f}%')
327
+
328
+ plt.tight_layout()
329
+
330
+ return fig1, fig2
331
+
332
+ # Connect events
333
+ search_btn.click(
334
+ fn=perform_cag_search,
335
+ inputs=[cag_query, use_cache, top_k_slider],
336
+ outputs=[search_results, performance_table]
337
+ )
338
+
339
+ stats_btn.click(
340
+ fn=update_cache_stats,
341
+ inputs=[],
342
+ outputs=[stats_output]
343
+ )
344
+
345
+ clear_cache_btn.click(
346
+ fn=clear_cag_cache,
347
+ inputs=[cache_type],
348
+ outputs=[cache_status]
349
+ )
350
+
351
+ batch_btn.click(
352
+ fn=batch_cag_search,
353
+ inputs=[batch_input, use_cache],
354
+ outputs=[batch_output]
355
+ )
356
+
357
+ preload_btn.click(
358
+ fn=preload_frequent_queries,
359
+ inputs=[],
360
+ outputs=[cache_status]
361
+ )
362
+
363
+ # Auto-update charts when performance data changes
364
+ performance_table.change(
365
+ fn=create_performance_charts,
366
+ inputs=[performance_table],
367
+ outputs=[response_time_chart, hit_rate_chart]
368
+ )
369
+
370
+ return cag_tab
371
  def create_gemini_realtime_tab():
372
  """Tạo tab cho Gemini Realtime API với Audio Streaming"""
373
 
 
587
 
588
  return gemini_tab
589
 
590
+ # # FastAPI routes cho Gemini (tùy chọn)
591
+ # def create_cag_tab(rag_system: EnhancedRAGSystem, multilingual_manager: MultilingualManager):
592
+ # """Tạo tab CAG (Conversational Agent Grounding)"""
593
 
594
+ # # Khởi tạo conversational agent
595
+ # conversational_agent = ConversationalAgent(rag_system, multilingual_manager)
596
 
597
+ # with gr.Blocks() as cag_tab:
598
+ # gr.Markdown("## 🤖 Chatbot với Tri thức (CAG)")
599
+ # gr.Markdown("Chatbot thông minh sử dụng thông tin từ cơ sở tri thức RAG để trả lời chính xác")
600
+
601
+ # with gr.Row():
602
+ # with gr.Column(scale=2):
603
+ # # Chat interface
604
+ # chatbot = gr.Chatbot(
605
+ # label="🤖 CAG Chatbot",
606
+ # height=400,
607
+ # show_copy_button=True,
608
+ # bubble_full_width=False,
609
+ # avatar_images=(
610
+ # "https://cdn-icons-png.flaticon.com/512/1077/1077114.png", # User
611
+ # "https://cdn-icons-png.flaticon.com/512/4712/4712027.png" # Assistant
612
+ # )
613
+ # )
614
+
615
+ # with gr.Row():
616
+ # msg = gr.Textbox(
617
+ # label="Nhập câu hỏi",
618
+ # placeholder="Hỏi tôi về bất kỳ điều gì trong cơ sở tri thức...",
619
+ # scale=4,
620
+ # container=False
621
+ # )
622
+ # submit_btn = gr.Button("Gửi", variant="primary", scale=1)
623
+ # clear_btn = gr.Button("Xóa", variant="secondary", scale=1)
624
+
625
+ # # Additional info
626
+ # with gr.Row():
627
+ # lang_display = gr.Textbox(
628
+ # label="🌐 Ngôn ngữ phát hiện",
629
+ # interactive=False,
630
+ # scale=2
631
+ # )
632
+ # conv_stats_btn = gr.Button("📊 Thống kê", variant="secondary", scale=1)
633
+
634
+ # # Knowledge base stats
635
+ # with gr.Accordion("📊 Cơ sở tri thức", open=False):
636
+ # kb_stats = gr.Textbox(
637
+ # label="Thống kê",
638
+ # interactive=False,
639
+ # lines=4
640
+ # )
641
+ # refresh_kb_btn = gr.Button("🔄 Cập nhật", variant="secondary", size="sm")
642
 
643
+ # with gr.Column(scale=1):
644
+ # gr.Markdown("### 📚 Nguồn thông tin")
645
+
646
+ # # Knowledge sources from RAG
647
+ # sources_display = gr.JSON(
648
+ # label="Kết quả tìm kiếm từ RAG",
649
+ # show_label=True,
650
+ # container=True
651
+ # )
652
+
653
+ # # Conversation statistics
654
+ # conv_stats_display = gr.JSON(
655
+ # label="📈 Thống kê hội thoại",
656
+ # show_label=True,
657
+ # container=True
658
+ # )
659
+
660
+ # # Language info
661
+ # with gr.Accordion("🌐 Thông tin ngôn ngữ", open=False):
662
+ # lang_info_btn = gr.Button("ℹ️ Xem ngôn ngữ", variant="secondary", size="sm")
663
+ # lang_info_display = gr.JSON(
664
+ # label="Ngôn ngữ hỗ trợ",
665
+ # container=True
666
+ # )
667
+
668
+ # # Instructions
669
+ # with gr.Accordion("ℹ️ Hướng dẫn", open=False):
670
+ # gr.Markdown("""
671
+ # **Cách sử dụng CAG:**
672
+ # 1. Nhập câu hỏi vào ô chat
673
+ # 2. Bot tự động tìm trong cơ sở tri thức
674
+ # 3. Trả lời dựa trên thông tin tìm thấy
675
+ # 4. Xem nguồn thông tin bên phải
676
 
677
+ # **Đặc điểm:**
678
+ # - 🤖 Grounding từ RAG
679
+ # - 🔍 Tự động tìm kiếm
680
+ # - 🌐 Đa ngôn ngữ
681
+ # - 📊 Theo dõi nguồn
682
+ # """)
683
+
684
+ # def respond(message: str, chat_history: List[Tuple[str, str]]) -> Tuple[str, List, List, str]:
685
+ # """Xử lý phản hồi chatbot"""
686
+ # if not message.strip():
687
+ # return "", chat_history, [], "⏳ Chờ câu hỏi..."
688
 
689
+ # try:
690
+ # # Gọi conversational agent
691
+ # response, search_results = conversational_agent.process_query(message, chat_history)
692
+
693
+ # # Cập nhật chat history
694
+ # chat_history.append((message, response))
695
+
696
+ # # Phát hiện ngôn ngữ
697
+ # language = multilingual_manager.detect_language(message)
698
+ # lang_info = multilingual_manager.get_language_info(language)
699
+ # lang_name = lang_info.get('name', language)
700
+
701
+ # return "", chat_history, search_results, f"🌐 {lang_name}"
702
+
703
+ # except Exception as e:
704
+ # error_response = f"Xin lỗi, đã xảy ra lỗi: {str(e)}"
705
+ # chat_history.append((message, error_response))
706
+ # return "", chat_history, [{"error": str(e)}], "❌ Lỗi"
707
+
708
+ # def get_conversation_stats():
709
+ # """Lấy thống kê hội thoại"""
710
+ # return conversational_agent.get_conversation_stats()
711
+
712
+ # def get_kb_stats():
713
+ # """Lấy thống kê knowledge base"""
714
+ # stats = rag_system.get_collection_stats()
715
+ # lang_dist = stats['language_distribution']
716
+ # lang_dist_str = ", ".join([f"{k}: {v}" for k, v in lang_dist.items()])
717
 
718
+ # return f"""
719
+ # 📊 THỐNG KÊ CƠ SỞ TRI THỨC:
720
+ # • 📄 Tổng documents: {stats['total_documents']}
721
+ # • 🔤 Embeddings: {stats['embedding_count']}
722
+ # • 🌐 Ngôn ngữ: {lang_dist_str}
723
+ # • 📐 Dimension: {stats['embedding_dimension']}
724
+ # • 🏷️ Trạng thái: {stats['status']}
725
+ # """
726
+
727
+ # def get_language_info():
728
+ # """Lấy thông tin ngôn ngữ hỗ trợ"""
729
+ # return multilingual_manager.get_supported_languages()
730
+
731
+ # def clear_chat():
732
+ # """Xóa chat"""
733
+ # conversational_agent.clear_conversation_history()
734
+ # return [], [], "🧹 Đã xóa"
735
+
736
+ # def refresh_all():
737
+ # """Làm mới tất cả"""
738
+ # kb_stats_text = get_kb_stats()
739
+ # conv_stats = get_conversation_stats()
740
+ # lang_info = get_language_info()
741
+ # return kb_stats_text, conv_stats, lang_info
742
+
743
+ # # Event handlers
744
+ # submit_btn.click(
745
+ # respond,
746
+ # inputs=[msg, chatbot],
747
+ # outputs=[msg, chatbot, sources_display, lang_display]
748
+ # )
749
+
750
+ # msg.submit(
751
+ # respond,
752
+ # inputs=[msg, chatbot],
753
+ # outputs=[msg, chatbot, sources_display, lang_display]
754
+ # )
755
+
756
+ # clear_btn.click(
757
+ # clear_chat,
758
+ # inputs=[],
759
+ # outputs=[chatbot, sources_display, lang_display]
760
+ # )
761
+
762
+ # conv_stats_btn.click(
763
+ # get_conversation_stats,
764
+ # inputs=[],
765
+ # outputs=[conv_stats_display]
766
+ # )
767
+
768
+ # refresh_kb_btn.click(
769
+ # get_kb_stats,
770
+ # inputs=[],
771
+ # outputs=[kb_stats]
772
+ # )
773
+
774
+ # lang_info_btn.click(
775
+ # get_language_info,
776
+ # inputs=[],
777
+ # outputs=[lang_info_display]
778
+ # )
779
+
780
+ # # Initialize on load
781
+ # cag_tab.load(
782
+ # refresh_all,
783
+ # inputs=[],
784
+ # outputs=[kb_stats, conv_stats_display, lang_info_display]
785
+ # )
786
 
787
+ # return cag_tab
788
  def setup_gemini_routes(app):
789
  """Thiết lập routes FastAPI cho Gemini"""
790