asad9641 commited on
Commit
8e224e2
·
verified ·
1 Parent(s): e41889d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +458 -276
app.py CHANGED
@@ -1,14 +1,13 @@
1
- # app_beautiful_blue_purple_theme.py
2
  """
3
- Multi-Mode AI Assistant (Voice, PDF, Image) with Wow-Factor Features
4
- - Preserves original features
5
- - Adds snippet highlighting, cross-modal memory, styled PDF generation
6
- - Live waveform placeholder for voice input
7
- - Modular & Hugging Face safe
8
- - UI: Blue -> Purple Neon theme (colorful tabs, headers, buttons, chat bubbles)
9
- THIS FILE is functionally identical to the user's original app.py but with
10
- additional CSS/HTML inside the Gradio Blocks to provide a colorful UI.
11
  """
 
 
12
  import os
13
  import uuid
14
  import tempfile
@@ -21,7 +20,7 @@ from sentence_transformers import SentenceTransformer, util
21
  from fpdf import FPDF
22
  from datetime import datetime
23
 
24
- # ------------------ Load API Keys ------------------
25
  load_dotenv()
26
  GROQ_API_KEY = os.getenv("GROQ_API_KEY", "").strip()
27
  OCR_SPACE_API_KEY = os.getenv("OCR_SPACE_API_KEY", "").strip()
@@ -162,7 +161,6 @@ def handle_pdf_question(question, session_id):
162
  {"role": "user", "content": f"PDF chunk:\n{chunk}\n\nQuestion: {question}"}
163
  ]
164
  assistant_text = groq_chat_completion(messages)
165
- # Add snippet highlighting for wow factor
166
  assistant_text = f"**Snippet from PDF:**\n{chunk[:200]}...\n\n**Answer:**\n{assistant_text}"
167
  if session_id not in SESSION_HISTORY:
168
  SESSION_HISTORY[session_id] = []
@@ -285,335 +283,519 @@ def handle_text_image(question, session_id):
285
 
286
  # ------------------ Gradio UI ------------------
287
  with gr.Blocks() as demo:
288
- # --- THEME CSS: Blue -> Purple Neon ---
289
- gr.HTML(r"""
290
  <style>
291
- /* PAGE BACKGROUND */
292
- body { background: linear-gradient(180deg, #0f172a 0%, #071029 100%); }
293
- /* ---------------- Tabs ---------------- */
294
- /* Target Gradio tab buttons (data-testid may vary across versions) */
295
- div[data-testid="tab-list"] button,
296
- .tabs button {
297
- background: linear-gradient(90deg, #0ea5e9, #7c3aed);
298
- color: white !important;
299
- font-weight: 700;
300
- border-radius: 12px 12px 0 0;
301
- padding: 10px 18px;
302
- margin-right: 6px;
303
- border: none;
304
- box-shadow: 0 6px 18px rgba(124,58,237,0.18);
305
- transition: transform 0.18s ease, box-shadow 0.18s ease;
306
- }
307
- div[data-testid="tab-list"] button:hover,
308
- .tabs button:hover { transform: translateY(-3px); }
309
- /* Active tab style (selected) */
310
- div[data-testid="tab-list"] button[aria-selected="true"],
311
- .tabs button[aria-selected="true"] {
312
- background: linear-gradient(90deg, #60a5fa, #a78bfa);
313
- box-shadow: 0 8px 24px rgba(99,102,241,0.28);
314
- }
315
- /* ---------------- Global headers / markdown ---------------- */
316
- .gradio-container h2, .gradio-container h3, .gradio-container h4,
317
- .gradio-container .markdown { color: #e6eef8; }
318
- /* Custom title styling */
319
- .app-title {
320
- font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
321
- font-size: 22px;
322
- color: white;
323
- padding: 10px 14px;
324
- border-radius: 10px;
325
- background: linear-gradient(90deg, rgba(14,165,233,0.08), rgba(124,58,237,0.06));
326
- box-shadow: inset 0 -1px 0 rgba(255,255,255,0.02);
327
- display: inline-block;
328
- }
329
- /* ---------------- Buttons ---------------- */
330
- /* Generic Gradio buttons (use both .gr-button and button selectors for compat) */
331
- .gr-button, .gradio-button, button {
332
- background: linear-gradient(90deg, #06b6d4, #7c3aed) !important;
333
- color: white !important;
334
- border: none !important;
335
- box-shadow: 0 8px 20px rgba(124,58,237,0.18);
336
- border-radius: 10px !important;
337
- padding: 8px 14px !important;
338
- font-weight: 700 !important;
339
- transition: transform 0.12s ease, box-shadow 0.12s ease;
340
- }
341
- .gr-button:hover, .gradio-button:hover, button:hover { transform: translateY(-3px); }
342
- /* Small secondary buttons */
343
- .secondary-btn { background: linear-gradient(90deg, rgba(255,255,255,0.04), rgba(255,255,255,0.02)); color: #cfe8ff; box-shadow:none; }
344
- /* ---------------- Chat bubbles ---------------- */
345
- /* Gradio internals vary between versions; include multiple selectors for safety */
346
- .chatbot .message.user, .gr-chat .message.user, .chat-message.user {
347
- background: linear-gradient(90deg,#60a5fa,#38bdf8);
348
- color: #051025;
349
- border-radius: 16px 16px 16px 4px;
350
- padding: 10px 12px;
351
- max-width: 85%;
352
- }
353
- .chatbot .message.assistant, .gr-chat .message.assistant, .chat-message.assistant {
354
- background: linear-gradient(90deg,#7c3aed,#a78bfa);
355
- color: #fff;
356
- border-radius: 16px 16px 4px 16px;
357
- padding: 10px 12px;
358
- max-width: 85%;
359
- }
360
- /* Timestamp / small metadata inside chat */
361
- .chatbot .timestamp, .gr-chat .timestamp { color: rgba(230,238,248,0.6); font-size: 11px; }
362
- /* Adjust chat container look */
363
- .chatbot { background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)); border-radius: 12px; padding: 8px; }
364
- /* Inputs and boxes */
365
- .gradio-container textarea, .gradio-container input[type='text'], .gradio-container .textbox {
366
- background: rgba(255,255,255,0.03); color: #e6eef8; border-radius: 8px; border: 1px solid rgba(255,255,255,0.04);
367
- }
368
- /* Small responsive tweaks */
369
- @media (max-width: 768px) {
370
- div[data-testid="tab-list"] button { padding: 8px 10px; font-size: 14px; }
371
- }
372
-
373
- /* Fix mic icon visibility and remove dark backend */
374
- .light-fix {
375
- /* reset dark backgrounds in inputs */
376
  }
377
- #mic_box button svg, #mic_box svg {
378
- fill: #6d28d9 !important;
379
- stroke: #6d28d9 !important;
 
 
 
 
 
380
  }
381
- .gradio-container, body {
382
- background: linear-gradient(135deg, #eef2ff 0%, #f5e8ff 100%) !important;
 
 
 
 
 
 
 
383
  }
384
- /* Fix mic inner box styling */
385
- #mic_box {
386
- position: relative !important; /* for custom mic icon */
387
- background: #ffffff !important;
388
- border: 2px solid #d3c7ff !important;
389
- border-radius: 14px !important;
390
- padding: 10px !important;
391
- height: 220px !important;
392
-
393
 
 
 
 
 
 
 
 
 
 
 
394
 
395
-
 
 
 
396
  }
397
- #mic_box button, #mic_box .icon, #mic_box svg {
398
- background: transparent !important;
399
- fill: #6d28d9 !important;
400
- stroke: #6d28d9 !important;
401
- }
402
- /* Ensure all text is clearly readable */
403
- body, .gradio-container, .gr-box, .gr-input, label, .gr-text, .gr-markdown, .gr-form, .gr-button, .gr-chatbot {
404
- color: #2b2b2b !important;
405
- }
406
- /* Chatbot bubble fixes */
407
- .gr-chatbot .message.user {
408
- background: #e4e7ff !important;
409
- color: #1f1f1f !important;
410
- }
411
- .gr-chatbot .message.bot {
412
- background: #f1e4ff !important;
413
- color: #1f1f1f !important;
414
- }
415
- /* Input fields readable */
416
- input, textarea, .gr-textbox, .gr-textbox textarea {
417
- background: #ffffff !important;
418
- color: #1e1e1e !important;
419
- border: 1px solid #cfcfcf !important;
420
- }
421
- /* Buttons readable */
422
- .gr-button {
423
- color: #ffffff !important;
424
- font-weight: 600;
425
  }
426
- /* Clear & visible mic button redesign */
427
- #mic_box button {
428
- background: #6d28d9 !important; /* bright purple */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  border-radius: 50% !important;
430
- width: 60px !important;
431
- height: 60px !important;
432
  display: flex !important;
433
  align-items: center !important;
434
  justify-content: center !important;
435
- border: none !important;
436
- box-shadow: 0 0 10px rgba(109,40,217,0.4) !important;
437
- }
438
- /* Replace icon with clear mic symbol */
439
- #mic_box button svg {
440
- width: 28px !important;
441
- height: 28px !important;
442
- fill: #1f1f1f !important;
443
- stroke: #1f1f1f !important;
444
- }
445
- #mic_box button:hover {
446
- background: #8b5cf6 !important;
447
- box-shadow: 0 0 14px rgba(139,92,246,0.6) !important;
448
- }
449
- /* Add label under mic */
450
- #mic_box::after {
451
- content: "Tap to Record";
452
- display: block;
453
- text-align: center;
454
- font-size: 12px;
455
- margin-top: 6px;
456
- color: #4b4b4b;
457
  }
458
 
459
- #mic_box::part(label) {
 
 
 
460
  font-size: 12px !important;
461
- color: #6d28d9 !important;
462
- writing-mode: vertical-lr;
463
- text-align: center;
 
 
 
 
 
 
 
 
464
  }
465
 
466
- /* ---------------- Mic Box Customization ---------------- */
467
- /* Make mic box taller and center contents */
468
- #mic_box.gradio-audio,
469
- #mic_box.gradio-audio > div {
470
- height: 150px !important; /* total box height */
471
- min-height: 150px !important;
 
472
  display: flex !important;
473
- flex-direction: column !important;
474
- justify-content: center !important;
475
  align-items: center !important;
 
 
476
  }
477
 
478
- /* Make the mic button bigger */
479
- #mic_box button {
480
- width: 70px !important;
481
- height: 70px !important;
482
  }
483
 
484
- /* Adjust the label under the button */
485
- #mic_box::after {
486
- content: "Tap to Record" !important;
487
- display: block !important;
488
  text-align: center !important;
489
- font-size: 14px !important; /* larger label text */
490
- margin-top: 8px !important;
491
- color: #4b4b4b !important;
492
  }
493
 
494
- /* ---------------- Drop Audio Here Box ---------------- */
495
- /* Target the internal Gradio file/audio drop area */
496
- #mic_box .gr-file-dropzone {
497
- height: 120px !important; /* taller drop area */
498
  display: flex !important;
499
  align-items: center !important;
500
- justify-content: center !important;
501
- background-color: #f3f0ff !important; /* light purple background */
502
- border: 2px dashed #a78bfa !important; /* dashed purple border */
503
- border-radius: 14px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
  padding: 12px !important;
 
 
 
505
  }
 
 
506
 
507
- /* Make the text inside the drop area bigger and centered */
508
- #mic_box .gr-file-dropzone span {
509
- font-size: 14px !important; /* text size */
510
- color: #4b4b4b !important; /* text color */
511
- text-align: center !important;
512
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
513
  </style>
 
514
  """)
515
 
516
- # Title area with colorful headline
517
  gr.HTML("""
518
- <div style='display:flex;align-items:center;gap:14px'>
519
- <div class='app-title'>
520
- <strong>🛠 Multi-Mode AI Assistant</strong>
521
- <div style='font-size:12px;color:#1f1f1f'>Voice · PDF · Image — Blue·Purple Neon Theme</div>
522
- </div>
523
  </div>
524
  """)
525
 
 
 
 
526
  session_voice = gr.State(str(uuid.uuid4()))
527
  session_pdf = gr.State(str(uuid.uuid4()))
528
  session_image = gr.State(str(uuid.uuid4()))
529
 
 
530
  with gr.Tab("🎤 Voice Chat"):
531
- # Tab header content (small colored markdown)
532
- gr.HTML("""
533
- <div style='margin-bottom:6px;'>
534
- <h3 style='margin:0;padding:0;color:#1f1f1f'>🎤 Voice Chat — Speak naturally, get voice & text responses</h3>
535
- <p style='margin:2px 0 6px;color:#3a3a3a;font-size:13px'>Hold and speak, ask general or knowledge-document questions. Enable enhancer for richer answers.</p>
536
- </div>
537
- """)
538
-
539
- chat_voice = gr.Chatbot( height=320)
540
- with gr.Row():
541
- mic = gr.Audio(type="filepath",label="🎤 Record Voice (hold & speak)", elem_id="mic_box")
542
- audio_output = gr.Audio(label="Assistant Voice Output", type="filepath", interactive=False)
543
- tts_lang = gr.Dropdown(choices=["en", "ur"], value="en", label="TTS Language")
544
-
545
- with gr.Row():
546
- btn_general = gr.Button("⚡Ask General 🎯")
547
- btn_pdf = gr.Button("⚡Ask PDF 📄")
548
- btn_image = gr.Button("⚡Ask Image 🖼")
549
- enhancer_toggle = gr.Checkbox(label="Enable Response Enhancer", value=False, scale =1)
550
- tone_dropdown = gr.Dropdown(choices=["Helpful", "Formal", "Friendly"], value="Helpful", label="Enhancer Tone", scale =1)
551
- with gr.Row():
552
- btn_reset_logs = gr.Button("♻ Reset LOGs", elem_id='reset_logs')
553
- btn_download_logs = gr.Button("📥 Download Summary", elem_id='download_logs')
554
- Voice_summary_file = gr.File(label="📥Download Summary File", interactive=False)
555
-
556
- answer_voice = gr.Textbox(label="Assistant Answer (text)", lines=2, visible=False)
557
-
558
- btn_general.click(fn=handle_voice_general,
559
- inputs=[mic, session_voice, tts_lang, enhancer_toggle, tone_dropdown],
560
- outputs=[answer_voice, audio_output, chat_voice])
561
  btn_pdf.click(fn=handle_voice_pdf, inputs=[mic, session_pdf, tts_lang], outputs=[answer_voice, audio_output, chat_voice])
562
  btn_image.click(fn=handle_voice_image, inputs=[mic, session_image, tts_lang], outputs=[answer_voice, audio_output, chat_voice])
563
  btn_reset_logs.click(lambda: (str(uuid.uuid4()), [], None, None, ""), outputs=[session_voice, chat_voice, mic, audio_output, answer_voice])
564
  btn_download_logs.click(download_pdf_summary, inputs=[session_voice], outputs=[Voice_summary_file])
565
 
 
566
  with gr.Tab("📄 PDF Summarizer"):
567
- gr.HTML("""
568
- <div style='margin-bottom:6px;'>
569
- <h3 style='margin:0;padding:0;color:#1f1f1f'>📄 PDF Summarizer — Upload a PDF, ask questions</h3>
570
- <p style='margin:2px 0 6px;color:#3a3a3a;font-size:13px'>Uploads are chunked and embedded so you can ask targeted questions about the document.</p>
571
- </div>
572
- """)
573
-
574
- pdf_output = gr.Textbox(label="Answer (Text Only)", lines=5)
575
- with gr.Row():
576
- pdf_upload_btn = gr.File(label="Upload PDF", file_types=[".pdf"], scale=1 )
577
- pdf_question = gr.Textbox(label="Ask a question about PDF (text)", lines=3)
578
  pdf_upload_msg = gr.Textbox(label="Upload Status", interactive=False)
579
-
580
- with gr.Row():
581
- pdf_send_btn = gr.Button("Ask (Questions)")
582
- pdf_reset_btn = gr.Button("♻ Reset LOGs")
583
- with gr.Row():
584
- pdf_summary_file = gr.File(label="📥Download Summary File", interactive=False,scale =1)
585
- pdf_download_btn = gr.Button("📥 Download Summary")
586
 
587
  pdf_upload_btn.upload(handle_pdf_upload, inputs=[pdf_upload_btn, session_pdf], outputs=[pdf_upload_msg])
588
  pdf_send_btn.click(handle_text_pdf, inputs=[pdf_question, session_pdf], outputs=[pdf_output])
589
  pdf_reset_btn.click(lambda: (str(uuid.uuid4()), ""), outputs=[session_pdf, pdf_output])
590
  pdf_download_btn.click(download_pdf_summary, inputs=[session_pdf], outputs=[pdf_summary_file])
591
 
 
592
  with gr.Tab("🖼 Image OCR"):
593
- gr.HTML("""
594
- <div style='margin-bottom:6px;'>
595
- <h3 style='margin:0;padding:0;color:#1f1f1f'>🖼 Image OCR Extract text from images</h3>
596
- <p style='margin:2px 0 6px;color:#3a3a3a;font-size:13px'>Upload an image, OCR runs, then ask questions about the extracted text.</p>
597
- </div>
598
- """)
599
-
600
- image_output = gr.Textbox(label="Answer (Text Only)", lines=5)
601
- with gr.Row():
602
- image_upload_btn = gr.File(label="Upload Image", file_types=[".png", ".jpg", ".jpeg"], scale =1 )
603
  image_question = gr.Textbox(label="Ask question about Image", lines=3)
604
  image_upload_msg = gr.Textbox(label="Upload Status", interactive=False)
605
-
606
- with gr.Row():
607
- image_send_btn = gr.Button("Ask (Questions)")
608
- image_reset_btn = gr.Button("♻ Reset LOGs")
609
- with gr.Row():
610
- image_summary_file = gr.File(label="📥Download Summary File", interactive=False,scale =1)
611
- image_download_btn = gr.Button("📥 Download Summary")
612
 
613
  image_upload_btn.upload(handle_image_upload, inputs=[image_upload_btn, session_image], outputs=[image_upload_msg, image_output])
614
  image_send_btn.click(handle_text_image, inputs=[image_question, session_image], outputs=[image_output])
615
  image_reset_btn.click(lambda: (str(uuid.uuid4()), ""), outputs=[session_image, image_output])
616
  image_download_btn.click(download_pdf_summary, inputs=[session_image], outputs=[image_summary_file])
617
 
 
 
 
618
  if __name__ == "__main__":
619
- demo.launch()
 
1
+ # app.py
2
  """
3
+ Multi-Mode AI Assistant (Voice, PDF, Image) with Ultra Neon FX
4
+ - Preserves all original logic and functionality
5
+ - Visual tweaks: Background lightened (~30%), stronger header and labels,
6
+ brighter mic icon, increased button glow, neon borders, animations, rounded chat boxes,
7
+ soft shadows. NO functional changes.
 
 
 
8
  """
9
+
10
+
11
  import os
12
  import uuid
13
  import tempfile
 
20
  from fpdf import FPDF
21
  from datetime import datetime
22
 
23
+ # ------------------ Load API KEYS ------------------
24
  load_dotenv()
25
  GROQ_API_KEY = os.getenv("GROQ_API_KEY", "").strip()
26
  OCR_SPACE_API_KEY = os.getenv("OCR_SPACE_API_KEY", "").strip()
 
161
  {"role": "user", "content": f"PDF chunk:\n{chunk}\n\nQuestion: {question}"}
162
  ]
163
  assistant_text = groq_chat_completion(messages)
 
164
  assistant_text = f"**Snippet from PDF:**\n{chunk[:200]}...\n\n**Answer:**\n{assistant_text}"
165
  if session_id not in SESSION_HISTORY:
166
  SESSION_HISTORY[session_id] = []
 
283
 
284
  # ------------------ Gradio UI ------------------
285
  with gr.Blocks() as demo:
286
+ # Inject CSS via HTML to avoid gr.Blocks(css=...) (compatibility)
287
+ gr.HTML("""
288
  <style>
289
+
290
+ /* ================= MIC INPUT BOX FIX ================= */
291
+ /* ===== MIC BOX FIX ===== */
292
+ #mic_box {
293
+ width: 100% !important;
294
+ height: 250px !important;
295
+ padding: 10px !important;
296
+ margin: 0 !important;
297
+ border-radius: 20px !important;
298
+ background: linear-gradient(180deg, #f0e0ff, #d8c0ff) !important;
299
+ border: 2px solid #aa66ff !important;
300
+ box-shadow: 0 8px 30px rgba(0,200,255,0.2) !important;
301
+ overflow: visible !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  }
303
+
304
+ /* Hide all buttons except the first record and first stop */
305
+ #mic_box button[title="Record"]:not(:first-of-type),
306
+ #mic_box button[title="Stop"]:not(:first-of-type),
307
+ #mic_box button[title="Download"],
308
+ #mic_box button[title="Share"],
309
+ #mic_box button[title="Edit"] {
310
+ display: none !important;
311
  }
312
+
313
+ /* Make buttons smaller */
314
+ #mic_box button {
315
+ width: 36px !important;
316
+ height: 36px !important;
317
+ min-width: 36px !important;
318
+ min-height: 36px !important;
319
+ padding: 0 !important;
320
+ margin: 0 5px !important;
321
  }
 
 
 
 
 
 
 
 
 
322
 
323
+ /* Center everything */
324
+ #mic_box > div {
325
+ width: 100% !important;
326
+ min-height: 100px !important;
327
+ display: flex !important;
328
+ flex-direction: column !important;
329
+ align-items: left !important;
330
+ justify-content: center !important;
331
+ gap: 20px !important;
332
+ }
333
 
334
+ /* Button styles */
335
+ #mic_box button[title="Record"] {
336
+ background: #ff4d4d !important;
337
+ border-radius: 50% !important;
338
  }
339
+
340
+ #mic_box button[title="Stop"] {
341
+ background: #4CAF50 !important;
342
+ border-radius: 50% !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  }
344
+
345
+ /* Hide other elements */
346
+ #mic_box .waveform,
347
+ #mic_box .time,
348
+ #mic_box .duration {
349
+ display: none !important;
350
+ }
351
+
352
+ /* Style the "Drop audio here" text */
353
+ #mic_box .drag-text {
354
+ color: #6a0dad !important;
355
+ font-weight: bold !important;
356
+ font-size: 14px !important;
357
+ margin-top: 5px !important;
358
+ text-align: center !important;
359
+ }
360
+
361
+ /* ================= AUDIO PLAYER FIX ================= */
362
+ #audio_output_box {
363
+ width: 100% !important;
364
+ padding: 12px !important;
365
+ margin: 0 !important;
366
+ border-radius: 20px !important;
367
+ background: linear-gradient(180deg, #f0e0ff, #d8c0ff) !important;
368
+ border: 2px solid #aa66ff !important;
369
+ box-shadow: 0 8px 30px rgba(0,200,255,0.2) !important;
370
+ overflow: visible !important;
371
+ }
372
+
373
+ /* Audio player container */
374
+ #audio_output_box .gradio-audio {
375
+ width: 100% !important;
376
+ min-width: 100% !important;
377
+ margin: 0 !important;
378
+ padding: 0 !important;
379
+ position: relative;
380
+ }
381
+
382
+ /* Controls row */
383
+ #audio_output_box .controls {
384
+ display: flex !important;
385
+ align-items: center !important;
386
+ justify-content: flex-start !important;
387
+ width: 100% !important;
388
+ gap: 4px !important;
389
+ padding: 4px 0 !important;
390
+ margin: 0 !important;
391
+ flex-wrap: nowrap !important;
392
+ overflow: visible !important;
393
+ }
394
+
395
+ /* Buttons */
396
+ #audio_output_box button {
397
+ width: 32px !important;
398
+ height: 32px !important;
399
+ min-width: 32px !important;
400
+ min-height: 32px !important;
401
+ margin: 0 2px !important;
402
+ padding: 0 !important;
403
  border-radius: 50% !important;
404
+ background: linear-gradient(90deg, #7fe9ff, #00a1ff) !important;
 
405
  display: flex !important;
406
  align-items: center !important;
407
  justify-content: center !important;
408
+ box-shadow: 0 2px 6px rgba(0,0,0,0.1) !important;
409
+ flex-shrink: 0 !important;
410
+ }
411
+
412
+ /* Button icons */
413
+ #audio_output_box button svg {
414
+ width: 16px !important;
415
+ height: 16px !important;
416
+ color: #000 !important;
417
+ fill: #000 !important;
418
+ }
419
+
420
+ /* Progress bar */
421
+ #audio_output_box .progress {
422
+ flex: 1 !important;
423
+ min-width: 60px !important;
424
+ margin: 0 8px !important;
425
+ height: 4px !important;
426
+ background: rgba(0,0,0,0.1) !important;
427
+ border-radius: 2px !important;
 
 
428
  }
429
 
430
+ /* Time display */
431
+ #audio_output_box .time {
432
+ min-width: 70px !important;
433
+ text-align: center !important;
434
  font-size: 12px !important;
435
+ color: #000 !important;
436
+ font-weight: 600 !important;
437
+ padding: 0 4px !important;
438
+ flex-shrink: 0 !important;
439
+ }
440
+
441
+ /* Volume control */
442
+ #audio_output_box .volume {
443
+ min-width: 80px !important;
444
+ margin-left: 4px !important;
445
+ flex-shrink: 0 !important;
446
  }
447
 
448
+ /* Hide default audio element */
449
+ #audio_output_box audio {
450
+ display: none !important;
451
+ }
452
+
453
+ /* Ensure all controls are properly aligned */
454
+ #audio_output_box .gradio-audio > div {
455
  display: flex !important;
 
 
456
  align-items: center !important;
457
+ width: 100% !important;
458
+ overflow: visible !important;
459
  }
460
 
461
+
462
+ /* Force button visibility */
463
+ #audio_output_box button[title="Mute"] {
464
+ margin-right: 4px !important;
465
  }
466
 
467
+ /* Ensure time display has enough space */
468
+ #audio_output_box .time {
469
+ min-width: 80px !important;
 
470
  text-align: center !important;
 
 
 
471
  }
472
 
473
+ /* Audio player container adjustments */
474
+ #audio_output_box .gradio-audio {
475
+ min-height: 50px !important;
 
476
  display: flex !important;
477
  align-items: center !important;
478
+ padding: 8px !important;
479
+ }
480
+ /* --------------------- GLOBAL BODY & CONTAINER --------------------- */
481
+ body, .gradio-container {
482
+ background: radial-gradient(circle at 8% 12%, #5a6ea0 0%, #7a8fc0 60%, #6f82b5 100%) !important;
483
+ color: #eaf6ff !important;
484
+ font-family: Inter, Arial, sans-serif;
485
+ -webkit-font-smoothing: antialiased;
486
+ }
487
+
488
+ /* --------------------- HEADER & TITLE --------------------- */
489
+ .header-box {
490
+ text-align: center;
491
+ padding: 18px 12px;
492
+ margin-bottom: 14px;
493
+ border-radius: 14px;
494
+ background: linear-gradient(180deg, rgba(255,255,255,0.08), rgba(255,255,255,0.03));
495
+ box-shadow: 0 12px 46px rgba(20, 30, 70, 0.35), inset 0 1px 0 rgba(255,255,255,0.03);
496
+ }
497
+ .app-title {
498
+ font-size: 34px;
499
+ font-weight: 900;
500
+ color: #ffffff !important;
501
+ letter-spacing: 1px;
502
+ text-shadow: 0 0 18px rgba(180,220,255,0.95), 0 0 48px rgba(140,180,255,0.65);
503
+ animation: titleGlow 3s infinite alternate;
504
+ }
505
+ @keyframes titleGlow {
506
+ from { opacity: 0.88; text-shadow: 0 0 16px rgba(120,200,255,0.6); transform: translateY(0); }
507
+ to { opacity: 1; text-shadow: 0 0 54px rgba(200,240,255,0.98); transform: translateY(-2px); }
508
+ }
509
+ .app-sub { color: rgba(235,245,255,0.98); margin-top:6px; }
510
+
511
+ /* --------------------- CARDS & BOXES --------------------- */
512
+ .glow-card, .header-box, .gr-chatbot, .upload-box, .gradio-container > .container {
513
+ border-radius: 20px !important;
514
+ border: 1px solid rgba(120,180,255,0.22) !important;
515
+ box-shadow: 0 16px 50px rgba(10,20,40,0.20), inset 0 0 28px rgba(140,180,255,0.02);
516
+ transition: transform 0.28s ease, box-shadow 0.28s ease;
517
+ }
518
+ .glow-card:hover { transform: translateY(-6px); box-shadow: 0 22px 58px rgba(30,50,90,0.32); }
519
+
520
+ /* --------------------- BUTTONS --------------------- */
521
+ .neon-btn, button {
522
+ background: linear-gradient(90deg,#7fe9ff,#00a1ff) !important;
523
+ color: #001528 !important;
524
+ border-radius: 18px !important;
525
+ padding: 10px 18px !important;
526
+ font-weight: 800 !important;
527
+ border: none !important;
528
+ box-shadow: 0 16px 36px rgba(0,150,255,0.28), 0 0 120px rgba(0,190,255,0.24), inset 0 1px 0 rgba(255,255,255,0.06);
529
+ transition: transform .18s ease, box-shadow .18s ease;
530
+ }
531
+ .neon-btn:hover, button:hover {
532
+ transform: translateY(-8px) scale(1.06);
533
+ box-shadow: 0 24px 58px rgba(0,160,255,0.46), 0 0 140px rgba(0,220,255,0.34);
534
+ }
535
+ .neon-btn:active, button:active { transform: scale(.98); }
536
+
537
+ /* --------------------- MIC & AUDIO BOX --------------------- */
538
+
539
+
540
+ @keyframes micPulse {
541
+ from { transform: scale(.985); box-shadow: 0 0 28px rgba(0,140,255,0.36); }
542
+ to { transform: scale(1.04); box-shadow: 0 0 120px rgba(0,230,255,0.95); }
543
+ }
544
+
545
+ /* AUDIO BUTTONS ICONS */
546
+
547
+
548
+
549
+
550
+ /* --------------------- MIC & AUDIO ICONS FIX --------------------- */
551
+
552
+
553
+
554
+ /* Make all audio control buttons visible in Assistant Voice Output */
555
+ #audio_output_box .gradio-audio button,
556
+ #audio_output_box .gradio-audio button svg,
557
+ #audio_output_box .gradio-audio button i {
558
+ color: #00f7ff !important; /* bright cyan */
559
+ fill: #00f7ff !important;
560
+ stroke: #00f7ff !important;
561
+ background: transparent !important;
562
+ filter: drop-shadow(0 8px 26px rgba(0,255,255,0.7)) !important;
563
+ }
564
+
565
+
566
+
567
+
568
+
569
+ #audio_output_box {
570
+ border-radius: 20px !important;
571
+ padding: 8px !important;
572
+ background: linear-gradient(180deg, #f0e0ff, #d8c0ff) !important;
573
+ border: 2px solid #aa66ff !important;
574
+ box-shadow: 0 8px 30px rgba(0,200,255,0.2), inset 0 0 20px rgba(0,200,255,0.1);
575
+ }
576
+ #audio_output_box audio {
577
+ border-radius: 12px !important;
578
+ height: 40px !important;
579
+ width: 100% !important;
580
+ background: linear-gradient(90deg, rgba(255,255,255,0.02), rgba(255,255,255,0.04));
581
+ border: 2px solid rgba(0,180,255,0.12) !important;
582
+ }
583
+
584
+ #audio_output_box .gradio-audio button,
585
+ #audio_output_box .gradio-audio button svg,
586
+ #audio_output_box .gradio-audio button i {
587
+ color: #000000 !important;
588
+ fill: #000000 !important;
589
+ stroke: #000000 !important;
590
+ opacity: 1 !important;
591
+ filter: none !important;
592
+ }
593
+
594
+
595
+
596
+
597
+
598
+ /* AUDIO ELEMENTS */
599
+ #audio_output_box, #mic_box, #pdf_box, #img_box {
600
+ border-radius: 20px !important;
601
+ padding: 8px !important;
602
+ background: linear-gradient(180deg, #f0e0ff, #d8c0ff) !important;
603
+ border: 2px solid #aa66ff !important;
604
+ box-shadow: 0 8px 30px rgba(0,200,255,0.2), inset 0 0 20px rgba(0,200,255,0.1);
605
+ position: relative !important;
606
+ overflow: visible !important;
607
+ }
608
+
609
+ /* ====================== PDF Upload Box ====================== */
610
+ #pdf_box,
611
+ #pdf_box .file-container,
612
+ #pdf_box .gr-file,
613
+ #pdf_box input[type="file"],
614
+ #pdf_box button {
615
+ border-radius: 20px !important;
616
+ padding: 8px !important;
617
+ background: linear-gradient(180deg, #f0e0ff, #d8c0ff) !important; /* same gradient as mic box */
618
+ border: 2px solid #aa66ff !important;
619
+ box-shadow: 0 8px 30px rgba(0,200,255,0.2), inset 0 0 20px rgba(0,200,255,0.1);
620
+ color: #001528 !important;
621
+ transition: transform 0.2s, box-shadow 0.2s;
622
+ }
623
+
624
+ /* Hover effect for PDF box */
625
+ #pdf_box:hover,
626
+ #pdf_box .file-container:hover,
627
+ #pdf_box .gr-file:hover,
628
+ #pdf_box input[type="file"]:hover,
629
+ #pdf_box button:hover {
630
+ transform: translateY(-4px);
631
+ box-shadow: 0 12px 40px rgba(30,50,90,0.32), inset 0 0 25px rgba(0,220,255,0.08);
632
+ }
633
+
634
+ /* ====================== Image Upload Box ====================== */
635
+ #img_box,
636
+ #img_box .file-container,
637
+ #img_box .gr-file,
638
+ #img_box input[type="file"],
639
+ #img_box button {
640
+ border-radius: 20px !important;
641
+ padding: 8px !important;
642
+ background: linear-gradient(180deg, #f0e0ff, #d8c0ff) !important; /* same gradient as mic box */
643
+ border: 2px solid #aa66ff !important;
644
+ box-shadow: 0 8px 30px rgba(0,200,255,0.2), inset 0 0 20px rgba(0,200,255,0.1);
645
+ color: #001528 !important;
646
+ transition: transform 0.2s, box-shadow 0.2s;
647
+ }
648
+
649
+ /* Hover effect for Image box */
650
+ #img_box:hover,
651
+ #img_box .file-container:hover,
652
+ #img_box .gr-file:hover,
653
+ #img_box input[type="file"]:hover,
654
+ #img_box button:hover {
655
+ transform: translateY(-4px);
656
+ box-shadow: 0 12px 40px rgba(30,50,90,0.32), inset 0 0 25px rgba(0,220,255,0.08);
657
+ }
658
+
659
+ /* Adjust mic glow ring to fit new box size */
660
+ #mic_box::before {
661
+ width: 88px !important;
662
+ height: 88px !important;
663
+ left: -14px !important;
664
+ top: -14px !important;
665
+ }
666
+
667
+
668
+ /* --------------------- CHAT BOT --------------------- */
669
+ .gr-chatbot {
670
+ border-radius: 28px !important;
671
  padding: 12px !important;
672
+ background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)) !important;
673
+ border: 1px solid rgba(120,170,255,0.06) !important;
674
+ box-shadow: 0 16px 40px rgba(10,20,40,0.20);
675
  }
676
+ .message.user { background: linear-gradient(90deg,#b0e0ff,#60b0ff) !important; color: #001528 !important; border-radius: 20px !important; padding:8px !important; }
677
+ .message.bot { background: linear-gradient(90deg,#004cff,#00aaff) !important; color: #ffffff !important; border-radius: 20px !important; padding:8px !important; }
678
 
679
+ /* --------------------- INPUTS & DROPDOWNS --------------------- */
680
+ label, .gradio-textbox label, .gradio-select label, .gradio-dropdown label, .gradio-file label {
681
+ color: #001528 !important;
682
+ font-weight: 800;
 
683
  }
684
+ select, .gradio-dropdown, .gradio-select, .gradio-file, input, textarea {
685
+ color: #00171f !important;
686
+ background: rgba(255,255,255,0.96) !important;
687
+ border: 1px solid rgba(0,120,255,0.12) !important;
688
+ }
689
+ .gradio-row .gradio-dropdown, .gradio-row select, .gradio-dropdown select {
690
+ background: linear-gradient(180deg,#ffffff,#f0f8ff) !important;
691
+ color: #00171f !important;
692
+ font-weight: 800;
693
+ border-radius: 12px !important;
694
+ }
695
+
696
+ /* --------------------- MARKDOWN & TEXT --------------------- */
697
+ .gr-markdown, h1, h2, h3, p {
698
+ color: #effbff !important;
699
+ }
700
+
701
+ /* --------------------- ANIMATIONS --------------------- */
702
+ .section-slide { animation: slideIn 0.9s cubic-bezier(.2,.9,.3,1) both; }
703
+ @keyframes slideIn { 0% { transform: translateY(26px); opacity: 0 } 100% { transform: translateY(0); opacity: 1 } }
704
+ .shimmer { background: linear-gradient(90deg, rgba(255,255,255,0.02), rgba(255,255,255,0.06), rgba(255,255,255,0.02)); background-size: 200% 100%; animation: shimmer 2.8s infinite linear; }
705
+ @keyframes shimmer { 0% { background-position: 200% 0 } 100% { background-position: -200% 0 } }
706
+
707
+ /* --------------------- RESPONSIVE --------------------- */
708
+ @media (max-width: 800px) { #mic_box::before { left: -12px; top: -12px; width: 96px; height: 96px; } .app-title { font-size: 22px; } }
709
+ @media (max-width: 480px) { #mic_box::before { left: -10px; top: -10px; width: 80px; height: 80px; } #mic_box audio { height: 36px !important; } #mic_box svg, #mic_box i { font-size: 20px !important; } }
710
+
711
+
712
+
713
+
714
  </style>
715
+
716
  """)
717
 
718
+ # Header (title color adjusted for visibility)
719
  gr.HTML("""
720
+ <div class="header-box">
721
+ <div class="app-title">⚡ OmniSense AI Bot — Ultra Neon</div>
722
+ <div class="app-sub">Voice • PDF • Image — Multi-Modal Intelligence with Neon FX</div>
 
 
723
  </div>
724
  """)
725
 
726
+ # Keep the main markdown visible and readable
727
+ gr.Markdown("## 🛠 Multi-Mode AI Assistant (Voice, PDF, Image)")
728
+
729
  session_voice = gr.State(str(uuid.uuid4()))
730
  session_pdf = gr.State(str(uuid.uuid4()))
731
  session_image = gr.State(str(uuid.uuid4()))
732
 
733
+ # ---------------- Voice Tab ----------------
734
  with gr.Tab("🎤 Voice Chat"):
735
+ chat_voice = gr.Chatbot(height=320, elem_classes=["section-slide"])
736
+ with gr.Row(elem_classes=["section-slide"]):
737
+ mic = gr.Audio(type="filepath", label="🎤 Record Voice (hold & speak)", elem_id="mic_box", interactive=True)
738
+ audio_output = gr.Audio(label="Assistant Voice Output", type="filepath", interactive=False,elem_id="audio_output_box")
739
+ tts_lang = gr.Dropdown(choices=["en","ur"], value="en", label="TTS Language")
740
+ with gr.Row(elem_classes=["section-slide"]):
741
+ btn_general = gr.Button("⚡Ask General 🎯", elem_classes=["neon-btn"])
742
+ btn_pdf = gr.Button("⚡Ask PDF 📄", elem_classes=["neon-btn"])
743
+ btn_image = gr.Button("⚡Ask Image 🖼", elem_classes=["neon-btn"])
744
+ enhancer_toggle = gr.Checkbox(label="Enable Response Enhancer", value=False, scale=1)
745
+ tone_dropdown = gr.Dropdown(choices=["Helpful","Formal","Friendly"], value="Helpful", label="Enhancer Tone", scale=1)
746
+ with gr.Row(elem_classes=["section-slide"]):
747
+ btn_reset_logs = gr.Button(" Reset LOGs", elem_classes=["neon-btn"])
748
+ btn_download_logs = gr.Button("📥 Download Summary", elem_classes=["neon-btn"])
749
+ Voice_summary_file = gr.File(label="📥Download Summary File", interactive=False, scale=1,elem_id="summary_file_voice")
750
+ answer_voice = gr.Textbox(label="Assistant Answer", lines=2, visible=False)
751
+
752
+ # Bind click handlers (functionality unchanged)
753
+ btn_general.click(fn=handle_voice_general, inputs=[mic, session_voice, tts_lang, enhancer_toggle, tone_dropdown], outputs=[answer_voice, audio_output, chat_voice])
 
 
 
 
 
 
 
 
 
 
 
754
  btn_pdf.click(fn=handle_voice_pdf, inputs=[mic, session_pdf, tts_lang], outputs=[answer_voice, audio_output, chat_voice])
755
  btn_image.click(fn=handle_voice_image, inputs=[mic, session_image, tts_lang], outputs=[answer_voice, audio_output, chat_voice])
756
  btn_reset_logs.click(lambda: (str(uuid.uuid4()), [], None, None, ""), outputs=[session_voice, chat_voice, mic, audio_output, answer_voice])
757
  btn_download_logs.click(download_pdf_summary, inputs=[session_voice], outputs=[Voice_summary_file])
758
 
759
+ # ---------------- PDF Tab ----------------
760
  with gr.Tab("📄 PDF Summarizer"):
761
+ pdf_output = gr.Textbox(label="Answer (Text Only)", lines=5, elem_classes=["glow-card","section-slide"])
762
+ with gr.Row(elem_classes=["section-slide"]):
763
+ pdf_upload_btn = gr.File(label="Upload PDF", file_types=[".pdf"], scale=1,elem_id="pdf_box")
764
+ pdf_question = gr.Textbox(label="Ask a question about PDF", lines=3)
 
 
 
 
 
 
 
765
  pdf_upload_msg = gr.Textbox(label="Upload Status", interactive=False)
766
+ with gr.Row(elem_classes=["section-slide"]):
767
+ pdf_send_btn = gr.Button("Ask (Questions)", elem_classes=["neon-btn"])
768
+ pdf_reset_btn = gr.Button(" Reset LOGs", elem_classes=["neon-btn"])
769
+ with gr.Row(elem_classes=["section-slide"]):
770
+ pdf_summary_file = gr.File(label="📥Download Summary File", interactive=False, scale=1)
771
+ pdf_download_btn = gr.Button("📥 Download Summary", elem_classes=["neon-btn"])
 
772
 
773
  pdf_upload_btn.upload(handle_pdf_upload, inputs=[pdf_upload_btn, session_pdf], outputs=[pdf_upload_msg])
774
  pdf_send_btn.click(handle_text_pdf, inputs=[pdf_question, session_pdf], outputs=[pdf_output])
775
  pdf_reset_btn.click(lambda: (str(uuid.uuid4()), ""), outputs=[session_pdf, pdf_output])
776
  pdf_download_btn.click(download_pdf_summary, inputs=[session_pdf], outputs=[pdf_summary_file])
777
 
778
+ # ---------------- IMAGE Tab ----------------
779
  with gr.Tab("🖼 Image OCR"):
780
+ image_output = gr.Textbox(label="Answer (Text Only)", lines=5, elem_classes=["glow-card","section-slide"])
781
+ with gr.Row(elem_classes=["section-slide"]):
782
+ image_upload_btn = gr.File(label="Upload Image", file_types=[".png",".jpg",".jpeg"], scale=1, elem_id="img_box")
 
 
 
 
 
 
 
783
  image_question = gr.Textbox(label="Ask question about Image", lines=3)
784
  image_upload_msg = gr.Textbox(label="Upload Status", interactive=False)
785
+ with gr.Row(elem_classes=["section-slide"]):
786
+ image_send_btn = gr.Button("Ask (Questions)", elem_classes=["neon-btn"])
787
+ image_reset_btn = gr.Button(" Reset LOGs", elem_classes=["neon-btn"])
788
+ with gr.Row(elem_classes=["section-slide"]):
789
+ image_summary_file = gr.File(label="📥Download Summary File", interactive=False, scale=1)
790
+ image_download_btn = gr.Button("📥 Download Summary", elem_classes=["neon-btn"])
 
791
 
792
  image_upload_btn.upload(handle_image_upload, inputs=[image_upload_btn, session_image], outputs=[image_upload_msg, image_output])
793
  image_send_btn.click(handle_text_image, inputs=[image_question, session_image], outputs=[image_output])
794
  image_reset_btn.click(lambda: (str(uuid.uuid4()), ""), outputs=[session_image, image_output])
795
  image_download_btn.click(download_pdf_summary, inputs=[session_image], outputs=[image_summary_file])
796
 
797
+
798
+
799
+
800
  if __name__ == "__main__":
801
+ demo.launch()