Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -327,137 +327,521 @@ Question: {query} [/INST]</s>"""
|
|
327 |
return "Conversation has been reset."
|
328 |
|
329 |
# Main function with Gradio UI
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
def main():
|
331 |
# Create the Vision 2030 service
|
332 |
service = Vision2030Service()
|
333 |
|
334 |
-
#
|
335 |
-
|
336 |
-
|
337 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
338 |
|
339 |
-
with
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
with gr.Tab("System Status"):
|
365 |
-
init_btn = gr.Button("Initialize System")
|
366 |
-
status_box = gr.Textbox(label="Status", value="System not initialized")
|
367 |
-
|
368 |
-
@spaces.GPU
|
369 |
-
def initialize_system():
|
370 |
-
success = service.initialize()
|
371 |
-
if success:
|
372 |
-
return "System initialized successfully!"
|
373 |
-
else:
|
374 |
-
return "System initialization failed. Check logs for details."
|
375 |
-
|
376 |
-
init_btn.click(initialize_system, None, status_box)
|
377 |
-
|
378 |
-
# PDF Check section
|
379 |
-
gr.Markdown("### PDF Status")
|
380 |
-
pdf_btn = gr.Button("Check PDF Files")
|
381 |
-
pdf_status = gr.Textbox(label="PDF Files")
|
382 |
-
|
383 |
-
def check_pdfs():
|
384 |
-
result = []
|
385 |
-
for pdf_file in ["saudi_vision203.pdf", "saudi_vision2030_ar.pdf"]:
|
386 |
-
if os.path.exists(pdf_file):
|
387 |
-
size = os.path.getsize(pdf_file) / (1024 * 1024) # Size in MB
|
388 |
-
result.append(f"{pdf_file}: Found ({size:.2f} MB)")
|
389 |
-
else:
|
390 |
-
result.append(f"{pdf_file}: Not found")
|
391 |
-
return "\n".join(result)
|
392 |
-
|
393 |
-
pdf_btn.click(check_pdfs, None, pdf_status)
|
394 |
-
|
395 |
-
# System check section
|
396 |
-
gr.Markdown("### Dependencies")
|
397 |
-
sys_btn = gr.Button("Check Dependencies")
|
398 |
-
sys_status = gr.Textbox(label="Dependencies Status")
|
399 |
-
|
400 |
-
@spaces.GPU
|
401 |
-
def check_dependencies():
|
402 |
-
result = []
|
403 |
-
|
404 |
-
# Safe imports inside GPU-decorated function
|
405 |
-
try:
|
406 |
-
import torch
|
407 |
-
result.append(f"β PyTorch: {torch.__version__}")
|
408 |
-
except ImportError:
|
409 |
-
result.append("β PyTorch: Not installed")
|
410 |
-
|
411 |
-
try:
|
412 |
-
import transformers
|
413 |
-
result.append(f"β Transformers: {transformers.__version__}")
|
414 |
-
except ImportError:
|
415 |
-
result.append("β Transformers: Not installed")
|
416 |
-
|
417 |
-
try:
|
418 |
-
import sentencepiece
|
419 |
-
result.append("β SentencePiece: Installed")
|
420 |
-
except ImportError:
|
421 |
-
result.append("β SentencePiece: Not installed")
|
422 |
-
|
423 |
-
try:
|
424 |
-
import accelerate
|
425 |
-
result.append(f"β Accelerate: {accelerate.__version__}")
|
426 |
-
except ImportError:
|
427 |
-
result.append("β Accelerate: Not installed")
|
428 |
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
|
441 |
-
|
442 |
-
|
443 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
444 |
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
|
450 |
-
|
451 |
-
|
452 |
|
453 |
-
|
454 |
-
|
455 |
|
456 |
-
#
|
457 |
-
|
458 |
-
auto_init_status = gr.Textbox(label="Initialization Status")
|
459 |
|
460 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
461 |
|
462 |
return demo
|
463 |
|
|
|
327 |
return "Conversation has been reset."
|
328 |
|
329 |
# Main function with Gradio UI
|
330 |
+
import os
|
331 |
+
import re
|
332 |
+
import json
|
333 |
+
import time
|
334 |
+
from tqdm import tqdm
|
335 |
+
from pathlib import Path
|
336 |
+
import spaces
|
337 |
+
import gradio as gr
|
338 |
+
|
339 |
+
# WARNING: Don't import torch, cuda, or GPU-related modules at the top level
|
340 |
+
# All previous helper functions and classes remain the same
|
341 |
+
|
342 |
def main():
|
343 |
# Create the Vision 2030 service
|
344 |
service = Vision2030Service()
|
345 |
|
346 |
+
# Define theme and styling
|
347 |
+
theme = gr.themes.Soft(
|
348 |
+
primary_hue="emerald",
|
349 |
+
secondary_hue="teal",
|
350 |
+
).set(
|
351 |
+
body_background_fill="linear-gradient(to right, #f0f9ff, #e6f7ff)",
|
352 |
+
button_primary_background_fill="linear-gradient(90deg, #1e9e5a, #1d8753)",
|
353 |
+
button_primary_background_fill_hover="linear-gradient(90deg, #1d8753, #176f44)",
|
354 |
+
button_primary_text_color="white",
|
355 |
+
button_secondary_background_fill="#f0f0f0",
|
356 |
+
button_secondary_background_fill_hover="#e0e0e0",
|
357 |
+
block_title_text_weight="600",
|
358 |
+
block_border_width="2px",
|
359 |
+
block_shadow="0px 4px 6px rgba(0, 0, 0, 0.1)",
|
360 |
+
background_fill_primary="#ffffff",
|
361 |
+
)
|
362 |
+
|
363 |
+
# Build the Gradio interface with enhanced styling
|
364 |
+
with gr.Blocks(title="Vision 2030 Assistant", theme=theme, css="""
|
365 |
+
.language-toggle { margin-bottom: 20px; }
|
366 |
+
.container { border-radius: 10px; padding: 20px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
|
367 |
+
.header-img { margin-bottom: 10px; border-radius: 10px; }
|
368 |
+
.highlight { background-color: rgba(46, 175, 125, 0.1); padding: 15px; border-radius: 8px; margin: 10px 0; }
|
369 |
+
.footer { text-align: center; margin-top: 30px; color: #666; font-size: 0.9em; }
|
370 |
+
.loading-spinner { display: inline-block; width: 20px; height: 20px; margin-right: 10px; }
|
371 |
+
.status-indicator { display: inline-flex; align-items: center; padding: 8px; border-radius: 4px; }
|
372 |
+
.status-indicator.success { background-color: rgba(46, 175, 125, 0.2); }
|
373 |
+
.status-indicator.warning { background-color: rgba(255, 190, 0, 0.2); }
|
374 |
+
.status-indicator.error { background-color: rgba(255, 76, 76, 0.2); }
|
375 |
+
.header { display: flex; justify-content: space-between; align-items: center; }
|
376 |
+
.lang-btn { min-width: 100px; }
|
377 |
+
.chat-input { background-color: white; border-radius: 8px; border: 1px solid #ddd; }
|
378 |
+
.info-box { background-color: #f8f9fa; padding: 10px; border-radius: 8px; margin-top: 10px; }
|
379 |
+
""") as demo:
|
380 |
+
# Header with logo and title
|
381 |
+
with gr.Row():
|
382 |
+
with gr.Column(scale=1):
|
383 |
+
gr.Image("https://www.vision2030.gov.sa/media/g0dp5h3t/vision-2030-logo-en.png",
|
384 |
+
show_label=False, container=False, height=100,
|
385 |
+
elem_classes=["header-img"])
|
386 |
+
with gr.Column(scale=3):
|
387 |
+
gr.Markdown("""
|
388 |
+
# Vision 2030 Assistant
|
389 |
+
### Your interactive guide to Saudi Arabia's national transformation program
|
390 |
+
""")
|
391 |
+
|
392 |
+
# Language toggle in the header
|
393 |
+
with gr.Row(elem_classes=["language-toggle"]):
|
394 |
+
language_toggle = gr.Radio(
|
395 |
+
choices=["English", "Ψ§ΩΨΉΨ±Ψ¨ΩΨ© (Arabic)", "Auto-detect"],
|
396 |
+
value="Auto-detect",
|
397 |
+
label="Interface Language",
|
398 |
+
info="Choose your preferred language",
|
399 |
+
elem_classes=["lang-btn"]
|
400 |
+
)
|
401 |
|
402 |
+
# Main interface with tabs
|
403 |
+
with gr.Tabs() as tabs:
|
404 |
+
# Chat Tab with enhanced design
|
405 |
+
with gr.TabItem("π¬ Chat", id="chat"):
|
406 |
+
with gr.Row():
|
407 |
+
with gr.Column(scale=2):
|
408 |
+
chatbot = gr.Chatbot(
|
409 |
+
height=450,
|
410 |
+
bubble_full_width=False,
|
411 |
+
avatar_images=(
|
412 |
+
"https://api.iconify.design/fluent-emoji:person.svg",
|
413 |
+
"https://api.iconify.design/fluent-emoji:robot.svg"
|
414 |
+
),
|
415 |
+
show_label=False
|
416 |
+
)
|
417 |
+
|
418 |
+
with gr.Row():
|
419 |
+
msg = gr.Textbox(
|
420 |
+
label="",
|
421 |
+
placeholder="Ask a question about Saudi Vision 2030...",
|
422 |
+
show_label=False,
|
423 |
+
elem_classes=["chat-input"],
|
424 |
+
scale=9
|
425 |
+
)
|
426 |
+
submit_btn = gr.Button("Send", variant="primary", scale=1)
|
427 |
+
|
428 |
+
with gr.Row():
|
429 |
+
clear = gr.Button("Clear History", variant="secondary")
|
430 |
+
thinking_indicator = gr.HTML(
|
431 |
+
value='<div id="thinking" style="display:none;">The assistant is thinking...</div>',
|
432 |
+
visible=True
|
433 |
+
)
|
434 |
+
|
435 |
+
# Sidebar with features
|
436 |
+
with gr.Column(scale=1):
|
437 |
+
gr.Markdown("### Quick Information")
|
438 |
+
|
439 |
+
with gr.Accordion("Vision 2030 Pillars", open=False):
|
440 |
+
gr.Markdown("""
|
441 |
+
* **Vibrant Society** - Cultural and social development
|
442 |
+
* **Thriving Economy** - Economic diversification
|
443 |
+
* **Ambitious Nation** - Effective governance
|
444 |
+
""")
|
445 |
+
|
446 |
+
with gr.Accordion("About this Assistant", open=False):
|
447 |
+
gr.Markdown("""
|
448 |
+
This assistant uses advanced NLP models to answer questions about Saudi Vision 2030 in both English and Arabic. The system retrieves information from official documents and provides relevant answers.
|
449 |
+
""")
|
450 |
+
|
451 |
+
system_status = gr.HTML(
|
452 |
+
value='<div class="status-indicator warning">β οΈ System initializing</div>',
|
453 |
+
visible=True
|
454 |
+
)
|
455 |
+
|
456 |
+
init_btn = gr.Button("Initialize System", variant="primary")
|
457 |
+
|
458 |
+
# Add a sample questions dropdown
|
459 |
+
sample_questions_dropdown = gr.Dropdown(
|
460 |
+
choices=[
|
461 |
+
"What is Saudi Vision 2030?",
|
462 |
+
"Ω
Ψ§ ΩΩ Ψ±Ψ€ΩΨ© Ψ§ΩΨ³ΨΉΩΨ―ΩΨ© 2030Ψ",
|
463 |
+
"What are the economic goals of Vision 2030?",
|
464 |
+
"Ω
Ψ§ ΩΩ Ψ§ΩΨ£ΩΨ―Ψ§Ω Ψ§ΩΨ§ΩΨͺΨ΅Ψ§Ψ―ΩΨ© ΩΨ±Ψ€ΩΨ© 2030Ψ",
|
465 |
+
"How does Vision 2030 aim to improve quality of life?",
|
466 |
+
"ΩΩΩ ΨͺΨΉΨ²Ψ² Ψ±Ψ€ΩΨ© 2030 Ψ§ΩΨ₯Ψ±Ψ« Ψ§ΩΨ«ΩΨ§ΩΩ Ψ§ΩΨ³ΨΉΩΨ―ΩΨ"
|
467 |
+
],
|
468 |
+
label="Sample Questions",
|
469 |
+
info="Select a question to try",
|
470 |
+
interactive=True
|
471 |
+
)
|
472 |
|
473 |
+
# Analytics and insights tab
|
474 |
+
with gr.TabItem("π Analytics", id="analytics"):
|
475 |
+
gr.Markdown("### Vision 2030 Progress Tracking")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
476 |
|
477 |
+
with gr.Tabs():
|
478 |
+
with gr.TabItem("Economic Metrics"):
|
479 |
+
gr.Markdown("""
|
480 |
+
<div class="highlight">
|
481 |
+
<h3>Key Economic Indicators</h3>
|
482 |
+
<p>This section displays real-time progress on economic targets of Vision 2030.</p>
|
483 |
+
</div>
|
484 |
+
""")
|
485 |
+
|
486 |
+
with gr.Row():
|
487 |
+
with gr.Column():
|
488 |
+
gr.HTML("""
|
489 |
+
<div style="background: white; padding: 15px; border-radius: 10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
|
490 |
+
<h4>GDP Non-oil Growth</h4>
|
491 |
+
<div style="height: 20px; background-color: #e0e0e0; border-radius: 10px; margin: 10px 0;">
|
492 |
+
<div style="height: 100%; width: 68%; background: linear-gradient(to right, #1e9e5a, #63e6be); border-radius: 10px;">
|
493 |
+
</div>
|
494 |
+
</div>
|
495 |
+
<div style="display: flex; justify-content: space-between;">
|
496 |
+
<span>Target: 65%</span>
|
497 |
+
<span>Current: 44%</span>
|
498 |
+
</div>
|
499 |
+
</div>
|
500 |
+
""")
|
501 |
+
|
502 |
+
with gr.Column():
|
503 |
+
gr.HTML("""
|
504 |
+
<div style="background: white; padding: 15px; border-radius: 10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
|
505 |
+
<h4>Unemployment Rate</h4>
|
506 |
+
<div style="height: 20px; background-color: #e0e0e0; border-radius: 10px; margin: 10px 0;">
|
507 |
+
<div style="height: 100%; width: 55%; background: linear-gradient(to right, #1e9e5a, #63e6be); border-radius: 10px;">
|
508 |
+
</div>
|
509 |
+
</div>
|
510 |
+
<div style="display: flex; justify-content: space-between;">
|
511 |
+
<span>Target: 7%</span>
|
512 |
+
<span>Current: 9.9%</span>
|
513 |
+
</div>
|
514 |
+
</div>
|
515 |
+
""")
|
516 |
+
|
517 |
+
with gr.Column():
|
518 |
+
gr.HTML("""
|
519 |
+
<div style="background: white; padding: 15px; border-radius: 10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
|
520 |
+
<h4>SME Contribution to GDP</h4>
|
521 |
+
<div style="height: 20px; background-color: #e0e0e0; border-radius: 10px; margin: 10px 0;">
|
522 |
+
<div style="height: 100%; width: 32%; background: linear-gradient(to right, #1e9e5a, #63e6be); border-radius: 10px;">
|
523 |
+
</div>
|
524 |
+
</div>
|
525 |
+
<div style="display: flex; justify-content: space-between;">
|
526 |
+
<span>Target: 35%</span>
|
527 |
+
<span>Current: 22%</span>
|
528 |
+
</div>
|
529 |
+
</div>
|
530 |
+
""")
|
531 |
+
|
532 |
+
with gr.TabItem("Social Development"):
|
533 |
+
gr.Markdown("#### Social Initiative Progress")
|
534 |
+
|
535 |
+
social_chart = gr.HTML("""
|
536 |
+
<div style="background: white; padding: 20px; border-radius: 10px; margin-top: 15px;">
|
537 |
+
<h3>Quality of Life Improvement Programs</h3>
|
538 |
+
<div style="display: flex; height: 200px; align-items: flex-end; justify-content: space-around; margin: 30px 0;">
|
539 |
+
<div style="display: flex; flex-direction: column; align-items: center;">
|
540 |
+
<div style="width: 50px; height: 150px; background: linear-gradient(to top, #1e9e5a, #63e6be); border-radius: 5px 5px 0 0;"></div>
|
541 |
+
<span style="margin-top: 10px;">Tourism</span>
|
542 |
+
</div>
|
543 |
+
<div style="display: flex; flex-direction: column; align-items: center;">
|
544 |
+
<div style="width: 50px; height: 120px; background: linear-gradient(to top, #1e9e5a, #63e6be); border-radius: 5px 5px 0 0;"></div>
|
545 |
+
<span style="margin-top: 10px;">Entertainment</span>
|
546 |
+
</div>
|
547 |
+
<div style="display: flex; flex-direction: column; align-items: center;">
|
548 |
+
<div style="width: 50px; height: 180px; background: linear-gradient(to top, #1e9e5a, #63e6be); border-radius: 5px 5px 0 0;"></div>
|
549 |
+
<span style="margin-top: 10px;">Healthcare</span>
|
550 |
+
</div>
|
551 |
+
<div style="display: flex; flex-direction: column; align-items: center;">
|
552 |
+
<div style="width: 50px; height: 100px; background: linear-gradient(to top, #1e9e5a, #63e6be); border-radius: 5px 5px 0 0;"></div>
|
553 |
+
<span style="margin-top: 10px;">Housing</span>
|
554 |
+
</div>
|
555 |
+
<div style="display: flex; flex-direction: column; align-items: center;">
|
556 |
+
<div style="width: 50px; height: 160px; background: linear-gradient(to top, #1e9e5a, #63e6be); border-radius: 5px 5px 0 0;"></div>
|
557 |
+
<span style="margin-top: 10px;">Education</span>
|
558 |
+
</div>
|
559 |
+
</div>
|
560 |
+
</div>
|
561 |
+
""")
|
562 |
+
|
563 |
+
with gr.TabItem("Giga-Projects"):
|
564 |
+
gr.Markdown("#### Major Development Projects")
|
565 |
+
|
566 |
+
with gr.Row():
|
567 |
+
for project, desc in [
|
568 |
+
("NEOM", "A $500 billion mega-city with advanced technologies"),
|
569 |
+
("Red Sea Project", "Luxury tourism destination across 28,000 kmΒ²"),
|
570 |
+
("Qiddiya", "Entertainment, sports and arts destination")
|
571 |
+
]:
|
572 |
+
with gr.Column():
|
573 |
+
gr.HTML(f"""
|
574 |
+
<div style="background: white; padding: 15px; border-radius: 10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); height: 200px; position: relative; overflow: hidden;">
|
575 |
+
<div style="position: absolute; top: 0; left: 0; width: 100%; height: 70px; background: linear-gradient(90deg, #1e9e5a, #45b08c); border-radius: 10px 10px 0 0;"></div>
|
576 |
+
<div style="position: relative; padding-top: 80px; text-align: center;">
|
577 |
+
<h3>{project}</h3>
|
578 |
+
<p>{desc}</p>
|
579 |
+
<button style="background: #1e9e5a; color: white; border: none; padding: 8px 15px; border-radius: 5px; cursor: pointer; margin-top: 15px;">Learn More</button>
|
580 |
+
</div>
|
581 |
+
</div>
|
582 |
+
""")
|
583 |
|
584 |
+
# Technical System Status with improved visualization
|
585 |
+
with gr.TabItem("βοΈ System", id="system"):
|
586 |
+
with gr.Row():
|
587 |
+
with gr.Column():
|
588 |
+
gr.Markdown("### System Diagnostics")
|
589 |
+
|
590 |
+
status_box = gr.Textbox(
|
591 |
+
label="Status",
|
592 |
+
value="System not initialized",
|
593 |
+
lines=1
|
594 |
+
)
|
595 |
+
|
596 |
+
with gr.Group():
|
597 |
+
gr.Markdown("### PDF Documents")
|
598 |
+
pdf_status = gr.Dataframe(
|
599 |
+
headers=["File", "Status", "Size"],
|
600 |
+
datatype=["str", "str", "str"],
|
601 |
+
col_count=(3, "fixed"),
|
602 |
+
value=[["saudi_vision203.pdf", "Checking...", ""],
|
603 |
+
["saudi_vision2030_ar.pdf", "Checking...", ""]]
|
604 |
+
)
|
605 |
+
pdf_btn = gr.Button("Check PDF Files", variant="secondary")
|
606 |
+
|
607 |
+
gr.Markdown("### System Dependencies")
|
608 |
+
sys_status = gr.Dataframe(
|
609 |
+
headers=["Component", "Status"],
|
610 |
+
datatype=["str", "str"],
|
611 |
+
col_count=(2, "fixed"),
|
612 |
+
value=[["PyTorch", "Not checked"],
|
613 |
+
["Transformers", "Not checked"],
|
614 |
+
["LangChain", "Not checked"],
|
615 |
+
["FAISS", "Not checked"]]
|
616 |
+
)
|
617 |
+
sys_btn = gr.Button("Check Dependencies", variant="secondary")
|
618 |
+
|
619 |
+
# Visualization column
|
620 |
+
with gr.Column():
|
621 |
+
gr.Markdown("### System Architecture")
|
622 |
+
gr.HTML("""
|
623 |
+
<div style="background: white; padding: 20px; border-radius: 10px; margin-top: 15px;">
|
624 |
+
<svg viewBox="0 0 800 500" xmlns="http://www.w3.org/2000/svg">
|
625 |
+
<!-- User Input -->
|
626 |
+
<rect x="50" y="50" width="150" height="60" rx="10" fill="#e6f7ff" stroke="#1e9e5a" stroke-width="2"/>
|
627 |
+
<text x="125" y="85" text-anchor="middle" font-size="16">User Query</text>
|
628 |
+
|
629 |
+
<!-- Arrow down -->
|
630 |
+
<path d="M125 110 L125 160" stroke="#1e9e5a" stroke-width="3" stroke-dasharray="5,5"/>
|
631 |
+
<polygon points="125,170 120,160 130,160" fill="#1e9e5a"/>
|
632 |
+
|
633 |
+
<!-- RAG System -->
|
634 |
+
<rect x="50" y="170" width="150" height="60" rx="10" fill="#e6f7ff" stroke="#1e9e5a" stroke-width="2"/>
|
635 |
+
<text x="125" y="205" text-anchor="middle" font-size="16">RAG System</text>
|
636 |
+
|
637 |
+
<!-- Arrow right -->
|
638 |
+
<path d="M200 200 L300 200" stroke="#1e9e5a" stroke-width="3" stroke-dasharray="5,5"/>
|
639 |
+
<polygon points="310,200 300,195 300,205" fill="#1e9e5a"/>
|
640 |
+
|
641 |
+
<!-- Document Store -->
|
642 |
+
<rect x="310" y="170" width="150" height="60" rx="10" fill="#e6f7ff" stroke="#1e9e5a" stroke-width="2"/>
|
643 |
+
<text x="385" y="195" text-anchor="middle" font-size="16">Vector Store</text>
|
644 |
+
<text x="385" y="215" text-anchor="middle" font-size="14">(FAISS)</text>
|
645 |
+
|
646 |
+
<!-- Document icons -->
|
647 |
+
<rect x="350" y="270" width="30" height="40" fill="#e6f7ff" stroke="#1e9e5a" stroke-width="1"/>
|
648 |
+
<rect x="355" y="265" width="30" height="40" fill="#e6f7ff" stroke="#1e9e5a" stroke-width="1"/>
|
649 |
+
<rect x="360" y="260" width="30" height="40" fill="#e6f7ff" stroke="#1e9e5a" stroke-width="1"/>
|
650 |
+
<text x="375" y="330" text-anchor="middle" font-size="14">PDF Docs</text>
|
651 |
+
|
652 |
+
<!-- Arrow up -->
|
653 |
+
<path d="M375 260 L375 230" stroke="#1e9e5a" stroke-width="2"/>
|
654 |
+
<polygon points="375,230 370,240 380,240" fill="#1e9e5a"/>
|
655 |
+
|
656 |
+
<!-- Arrow back to RAG -->
|
657 |
+
<path d="M310 220 L200 220" stroke="#1e9e5a" stroke-width="3" stroke-dasharray="5,5"/>
|
658 |
+
<polygon points="190,220 200,215 200,225" fill="#1e9e5a"/>
|
659 |
+
|
660 |
+
<!-- Arrow down from RAG -->
|
661 |
+
<path d="M125 230 L125 280" stroke="#1e9e5a" stroke-width="3"/>
|
662 |
+
<polygon points="125,290 120,280 130,280" fill="#1e9e5a"/>
|
663 |
+
|
664 |
+
<!-- LLM -->
|
665 |
+
<rect x="50" y="290" width="150" height="60" rx="10" fill="#e6f7ff" stroke="#1e9e5a" stroke-width="2"/>
|
666 |
+
<text x="125" y="315" text-anchor="middle" font-size="16">ALLaM Model</text>
|
667 |
+
<text x="125" y="335" text-anchor="middle" font-size="14">(7B Params)</text>
|
668 |
+
|
669 |
+
<!-- Arrow down -->
|
670 |
+
<path d="M125 350 L125 400" stroke="#1e9e5a" stroke-width="3"/>
|
671 |
+
<polygon points="125,410 120,400 130,400" fill="#1e9e5a"/>
|
672 |
+
|
673 |
+
<!-- User Response -->
|
674 |
+
<rect x="50" y="410" width="150" height="60" rx="10" fill="#e6f7ff" stroke="#1e9e5a" stroke-width="2"/>
|
675 |
+
<text x="125" y="445" text-anchor="middle" font-size="16">Response</text>
|
676 |
+
</svg>
|
677 |
+
</div>
|
678 |
+
""")
|
679 |
+
|
680 |
+
# Memory usage visualization
|
681 |
+
gr.Markdown("### System Resources")
|
682 |
+
gr.HTML("""
|
683 |
+
<div style="background: white; padding: 15px; border-radius: 10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); margin-top: 15px;">
|
684 |
+
<h4>GPU Memory Usage</h4>
|
685 |
+
<div style="height: 20px; background-color: #e0e0e0; border-radius: 10px; margin: 10px 0;">
|
686 |
+
<div style="height: 100%; width: 72%; background: linear-gradient(to right, #1e9e5a, #ffc107); border-radius: 10px;">
|
687 |
+
</div>
|
688 |
+
</div>
|
689 |
+
<div style="display: flex; justify-content: space-between;">
|
690 |
+
<span>Total: 16GB</span>
|
691 |
+
<span>Used: 11.5GB</span>
|
692 |
+
</div>
|
693 |
+
|
694 |
+
<h4 style="margin-top: 20px;">CPU Usage</h4>
|
695 |
+
<div style="height: 20px; background-color: #e0e0e0; border-radius: 10px; margin: 10px 0;">
|
696 |
+
<div style="height: 100%; width: 45%; background: linear-gradient(to right, #1e9e5a, #63e6be); border-radius: 10px;">
|
697 |
+
</div>
|
698 |
+
</div>
|
699 |
+
<div style="display: flex; justify-content: space-between;">
|
700 |
+
<span>0%</span>
|
701 |
+
<span>45%</span>
|
702 |
+
<span>100%</span>
|
703 |
+
</div>
|
704 |
+
</div>
|
705 |
+
""")
|
706 |
+
|
707 |
+
# Footer
|
708 |
+
gr.HTML("""
|
709 |
+
<div class="footer">
|
710 |
+
<p>Vision 2030 Assistant β’ Powered by ALLaM-7B-Instruct β’ Β© 2025</p>
|
711 |
+
</div>
|
712 |
+
""")
|
713 |
|
714 |
+
# JavaScript for animations and enhanced UI effects
|
715 |
+
demo.load(js="""
|
716 |
+
function setupThinking() {
|
717 |
+
const thinking = document.getElementById('thinking');
|
718 |
+
|
719 |
+
function animateThinking() {
|
720 |
+
if (thinking) {
|
721 |
+
thinking.style.display = 'block';
|
722 |
+
let dots = '.';
|
723 |
+
setInterval(() => {
|
724 |
+
dots = dots.length < 3 ? dots + '.' : '.';
|
725 |
+
thinking.innerHTML = `<div class="status-indicator">π€ The assistant is thinking${dots}</div>`;
|
726 |
+
}, 500);
|
727 |
+
}
|
728 |
+
}
|
729 |
+
|
730 |
+
// Demo code to show the thinking animation
|
731 |
+
document.querySelectorAll('button').forEach(btn => {
|
732 |
+
if (btn.textContent.includes('Send')) {
|
733 |
+
btn.addEventListener('click', () => {
|
734 |
+
setTimeout(() => {
|
735 |
+
animateThinking();
|
736 |
+
}, 100);
|
737 |
+
});
|
738 |
+
}
|
739 |
+
});
|
740 |
+
}
|
741 |
+
|
742 |
+
// Run setup when page loads
|
743 |
+
if (document.readyState === 'complete') {
|
744 |
+
setupThinking();
|
745 |
+
} else {
|
746 |
+
window.addEventListener('load', setupThinking);
|
747 |
+
}
|
748 |
+
""")
|
749 |
+
|
750 |
+
# Event handlers
|
751 |
+
@spaces.GPU
|
752 |
+
def respond(message, history):
|
753 |
+
if not message:
|
754 |
+
return history, ""
|
755 |
|
756 |
+
# Set thinking indicator
|
757 |
+
time.sleep(0.5) # Simulate thinking time
|
758 |
|
759 |
+
response, sources = service.answer_question(message)
|
760 |
+
sources_text = ", ".join(sources) if sources else "No specific sources"
|
761 |
|
762 |
+
# Format the response to include sources
|
763 |
+
full_response = f"{response}\n\nSources: {sources_text}"
|
|
|
764 |
|
765 |
+
return history + [[message, full_response]], ""
|
766 |
+
|
767 |
+
def reset_chat():
|
768 |
+
service.reset_conversation()
|
769 |
+
return [], "Conversation history has been reset."
|
770 |
+
|
771 |
+
@spaces.GPU
|
772 |
+
def initialize_system():
|
773 |
+
success = service.initialize()
|
774 |
+
|
775 |
+
# Update system status indicator with styled HTML
|
776 |
+
if success:
|
777 |
+
status_html = '<div class="status-indicator success">β
System initialized and ready</div>'
|
778 |
+
return "System initialized successfully!", status_html
|
779 |
+
else:
|
780 |
+
status_html = '<div class="status-indicator error">β System initialization failed</div>'
|
781 |
+
return "System initialization failed. Check logs for details.", status_html
|
782 |
+
|
783 |
+
def use_sample_question(question):
|
784 |
+
return question
|
785 |
+
|
786 |
+
def check_pdfs():
|
787 |
+
result = []
|
788 |
+
for pdf_file in ["saudi_vision203.pdf", "saudi_vision2030_ar.pdf"]:
|
789 |
+
if os.path.exists(pdf_file):
|
790 |
+
size = os.path.getsize(pdf_file) / (1024 * 1024) # Size in MB
|
791 |
+
result.append([pdf_file, "Found β
", f"{size:.2f} MB"])
|
792 |
+
else:
|
793 |
+
result.append([pdf_file, "Not found β", "0 MB"])
|
794 |
+
return result
|
795 |
+
|
796 |
+
@spaces.GPU
|
797 |
+
def check_dependencies():
|
798 |
+
result = []
|
799 |
+
|
800 |
+
# Safe imports inside GPU-decorated function
|
801 |
+
try:
|
802 |
+
import torch
|
803 |
+
result.append(["PyTorch", f"β
{torch.__version__}"])
|
804 |
+
except ImportError:
|
805 |
+
result.append(["PyTorch", "β Not installed"])
|
806 |
+
|
807 |
+
try:
|
808 |
+
import transformers
|
809 |
+
result.append(["Transformers", f"β
{transformers.__version__}"])
|
810 |
+
except ImportError:
|
811 |
+
result.append(["Transformers", "β Not installed"])
|
812 |
+
|
813 |
+
try:
|
814 |
+
import langchain
|
815 |
+
result.append(["LangChain", f"β
{langchain.__version__}"])
|
816 |
+
except ImportError:
|
817 |
+
result.append(["LangChain", "β Not installed"])
|
818 |
+
|
819 |
+
try:
|
820 |
+
import faiss
|
821 |
+
result.append(["FAISS", "β
Installed"])
|
822 |
+
except ImportError:
|
823 |
+
result.append(["FAISS", "β Not installed"])
|
824 |
+
|
825 |
+
return result
|
826 |
+
|
827 |
+
# Connect event handlers
|
828 |
+
msg.submit(respond, [msg, chatbot], [chatbot, msg])
|
829 |
+
submit_btn.click(respond, [msg, chatbot], [chatbot, msg])
|
830 |
+
clear.click(reset_chat, None, [chatbot, msg])
|
831 |
+
|
832 |
+
init_btn.click(initialize_system, None, [status_box, system_status])
|
833 |
+
|
834 |
+
sample_questions_dropdown.change(
|
835 |
+
use_sample_question,
|
836 |
+
[sample_questions_dropdown],
|
837 |
+
[msg]
|
838 |
+
)
|
839 |
+
|
840 |
+
pdf_btn.click(check_pdfs, None, pdf_status)
|
841 |
+
sys_btn.click(check_dependencies, None, sys_status)
|
842 |
+
|
843 |
+
# Initialize system on page load
|
844 |
+
demo.load(initialize_system, None, [status_box, system_status])
|
845 |
|
846 |
return demo
|
847 |
|