abdull4h commited on
Commit
f76da15
Β·
verified Β·
1 Parent(s): f609ae7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +502 -118
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
- # Build the Gradio interface
335
- with gr.Blocks(title="Vision 2030 Assistant") as demo:
336
- gr.Markdown("# Vision 2030 Assistant")
337
- gr.Markdown("Ask questions about Saudi Vision 2030 in English or Arabic")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
- with gr.Tab("Chat"):
340
- chatbot = gr.Chatbot()
341
- msg = gr.Textbox(label="Your question", placeholder="Ask about Vision 2030...")
342
- clear = gr.Button("Clear History")
343
-
344
- @spaces.GPU
345
- def respond(message, history):
346
- if not message:
347
- return history, ""
348
-
349
- response, sources = service.answer_question(message)
350
- sources_text = ", ".join(sources) if sources else "No specific sources"
351
-
352
- # Format the response to include sources
353
- full_response = f"{response}\n\nSources: {sources_text}"
354
-
355
- return history + [[message, full_response]], ""
356
-
357
- def reset_chat():
358
- service.reset_conversation()
359
- return [], "Conversation history has been reset."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
 
361
- msg.submit(respond, [msg, chatbot], [chatbot, msg])
362
- clear.click(reset_chat, None, [chatbot, msg])
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
- try:
430
- import langchain
431
- result.append(f"βœ“ LangChain: {langchain.__version__}")
432
- except ImportError:
433
- result.append("βœ— LangChain: Not installed")
434
-
435
- try:
436
- import langchain_community
437
- result.append(f"βœ“ LangChain Community: {langchain_community.__version__}")
438
- except ImportError:
439
- result.append("βœ— LangChain Community: Not installed")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
 
441
- return "\n".join(result)
442
-
443
- sys_btn.click(check_dependencies, None, sys_status)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
 
445
- with gr.Tab("Sample Questions"):
446
- gr.Markdown("### Sample Questions to Try")
447
-
448
- sample_questions = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
 
450
- for item in comprehensive_evaluation_data:
451
- sample_questions.append(item["query"])
452
 
453
- questions_md = "\n".join([f"- {q}" for q in sample_questions])
454
- gr.Markdown(questions_md)
455
 
456
- # Add a button to auto-initialize the system when viewing sample questions
457
- auto_init_btn = gr.Button("Initialize System First")
458
- auto_init_status = gr.Textbox(label="Initialization Status")
459
 
460
- auto_init_btn.click(initialize_system, None, auto_init_status)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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