ErNewdev0 commited on
Commit
db42d03
Β·
verified Β·
1 Parent(s): cedc4db

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +176 -160
app.py CHANGED
@@ -342,42 +342,42 @@ class RepoAnalyzer:
342
  history[-1][1] = f"⚠️ Error: {str(e)}"
343
  yield history
344
 
345
- def process_code_blocks(text):
346
- """Process markdown code blocks to use custom artifact styling"""
347
- import re
348
 
349
  # Pattern for code blocks with language specification
350
- pattern = r"```(\w+)\n(.*?)```"
351
 
352
- def replace_code_block(match):
353
- language = match.group(1)
354
- code = match.group(2)
355
- escaped_code = code.replace('`', r'\`')
356
 
357
- html = (
358
- '<div class="wrapper-artifact">'
359
- f'<div class="header-artifact">'
360
- f'<span>{language}</span>'
361
- f'<button class="copy-button" onclick="copyToClipboard(`{escaped_code}`)">Copy</button>'
362
- '</div>'
363
- '<div class="content-artifact">'
364
- f'<pre><code>{code}</code></pre>'
365
- '</div>'
366
- '</div>'
367
- )
368
- return html
369
 
370
  # Replace all code blocks in the text
371
- processed_text = re.sub(pattern, replace_code_block, text, flags=re.DOTALL)
372
- return processed_text
373
 
374
- def create_ui():
375
- # Get local time
376
- local_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
377
- analyzer = RepoAnalyzer()
378
-
379
- with gr.Blocks(title="Repository Chat Analysis", theme=gr.themes.Soft()) as app:
380
- gr.Markdown("""
381
  <style>
382
  .container { max-width: 100% !important; padding: 1rem; }
383
  .mobile-full { width: 100% !important; }
@@ -460,176 +460,177 @@ class RepoAnalyzer:
460
  </script>
461
  """)
462
 
463
- with gr.Row(elem_classes="container"):
464
- gr.Markdown(f"# πŸ€– Repository Chat Analysis\n\nπŸ“… {local_time}")
465
-
466
- with gr.Tabs() as tabs:
467
- with gr.Tab("πŸ› οΈ Konfigurasi", elem_classes="mobile-full"):
468
- provider = gr.Radio(
469
- choices=[AIProvider.XAI, AIProvider.GEMINI, AIProvider.OLLAMA],
470
- label="Penyedia AI",
471
- value=AIProvider.XAI,
472
- interactive=True,
473
- elem_classes="mobile-full"
474
- )
475
-
476
- with gr.Group() as api_settings:
477
- with gr.Group():
478
- with gr.Row():
479
- xai_key = gr.Textbox(
480
- label="X.AI (Grok) API Key",
481
- type="password",
482
- placeholder="Opsional - Klik icon (?) untuk info",
483
- show_label=True,
484
- scale=3
485
- )
486
- with gr.Column(scale=1):
487
- gr.Markdown(XAI_API_HELP)
488
-
489
- with gr.Group():
490
- with gr.Row():
491
- gemini_key = gr.Textbox(
492
- label="Gemini API Key",
493
- type="password",
494
- placeholder="Opsional - Kosongkan untuk gunakan key default",
495
- show_label=True,
496
- scale=3
497
- )
498
- with gr.Column(scale=1):
499
- gr.Markdown(GEMINI_API_HELP)
500
-
501
- # Model selection with better layout
502
- with gr.Row():
503
- model_dropdown = gr.Dropdown(
504
- label="Model AI",
505
- choices=XAI_MODELS,
506
- value="grok-2-latest",
507
- interactive=True,
508
- elem_classes="mobile-full"
509
- )
510
-
511
- with gr.Tab("πŸ“Š Analisis Repository", elem_classes="mobile-full"):
512
  with gr.Group():
513
  with gr.Row():
514
- repo_url = gr.Textbox(
515
- label="URL Repository GitHub",
516
- placeholder="https://github.com/username/repository",
517
- elem_classes="mobile-full"
 
 
518
  )
519
-
 
 
 
 
520
  with gr.Row():
521
- with gr.Column(scale=2):
522
- github_token = gr.Textbox(
523
- label="Token GitHub",
524
- type="password",
525
- placeholder="Klik icon (?) untuk panduan",
526
- elem_classes="mobile-full"
527
- )
528
  with gr.Column(scale=1):
529
- branch = gr.Textbox(
530
- label="Branch (opsional)",
531
- placeholder="main",
532
- elem_classes="mobile-full"
533
- )
534
-
535
- clone_button = gr.Button(
536
- "πŸ”„ Clone Repository",
537
- variant="primary",
538
  elem_classes="mobile-full"
539
  )
 
 
 
 
 
 
 
 
 
 
 
540
 
541
- clone_status = gr.Markdown(
542
- value="",
543
- label="Status Repository",
544
- elem_classes="mobile-full"
545
- )
546
-
547
- # File selection components
548
- with gr.Group():
549
- gr.Markdown("### πŸ“Ž File yang Dipilih")
550
-
551
- with gr.Row():
552
- file_selector = gr.Dropdown(
553
- label="Pilih File dari Repository",
554
- choices=[],
555
- multiselect=True,
556
  elem_classes="mobile-full"
557
  )
558
-
559
- file_list = gr.HTML(
560
- value="<div class='file-list'>Belum ada file yang dipilih</div>",
561
- label="Daftar File Terpilih"
562
- )
563
-
564
- # Enhanced chat interface with fullscreen support
565
- with gr.Group():
566
- chat_history = gr.Chatbot(
567
- label="πŸ“ Riwayat Chat",
568
- elem_classes="fullscreen-chat",
569
- height=None, # Let CSS handle the height
570
- show_label=True,
571
- type="messages" # Fix deprecation warning
572
  )
573
 
574
- with gr.Group(elem_classes="chat-input"):
575
- chat_input = gr.Textbox(
576
- label="πŸ’­ Tanyakan tentang Repository",
577
- placeholder="Ketik pertanyaan Anda di sini...",
578
- lines=3,
579
- elem_classes="mobile-full"
580
- )
 
 
 
581
  with gr.Row():
582
- clear_button = gr.Button("🧹 Bersihkan", variant="secondary")
583
- send_button = gr.Button("πŸ“€ Kirim", variant="primary")
 
 
 
 
 
 
 
 
 
584
 
585
- # Connect event handlers
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  def clear_chat_history():
587
  return None
588
 
589
- clear_button.click(
590
- fn=clear_chat_history,
591
- outputs=chat_history
592
- )
593
-
594
  def handle_clone(repo_url, github_token, branch):
595
  if not repo_url:
596
  return "⚠️ URL repository diperlukan!", [], []
597
-
598
  success, message = analyzer.clone_repository(repo_url, github_token, branch)
599
-
600
  if success:
601
- # Get list of files from cloned repository
602
  files = list(analyzer.repo_content.keys())
603
  return message, files, []
604
-
605
  return message, [], []
606
 
607
- # Connect clone button click event
608
- clone_button.click(
609
- fn=handle_clone,
610
- inputs=[repo_url, github_token, branch],
611
- outputs=[clone_status, file_selector, file_list]
612
- )
613
-
614
  def update_file_list(selected):
615
  if not selected:
616
  return "<div class='file-list'>Belum ada file yang dipilih</div>"
617
-
618
  html = "<div class='file-list'>"
619
  for file in selected:
620
  html += f"<div class='file-item'><span>{file}</span></div>"
621
  html += "</div>"
622
  return html
623
 
624
- # Update file list when selection changes
 
 
 
 
 
 
 
 
 
 
 
625
  file_selector.change(
626
  fn=update_file_list,
627
  inputs=[file_selector],
628
  outputs=[file_list]
629
  )
630
 
631
- # Connect chat events
632
- send_event = send_button.click(
633
  fn=handle_chat,
634
  inputs=[
635
  chat_input,
@@ -647,7 +648,7 @@ class RepoAnalyzer:
647
  outputs=chat_input
648
  )
649
 
650
- input_event = chat_input.submit(
651
  fn=handle_chat,
652
  inputs=[
653
  chat_input,
@@ -665,12 +666,27 @@ class RepoAnalyzer:
665
  outputs=chat_input
666
  )
667
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
668
  return app
669
 
670
  if __name__ == "__main__":
671
  print(f"""
672
  πŸš€ Memulai Repository Chat Analysis
673
- πŸ“… {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
674
  """)
675
 
676
  app = create_ui()
 
342
  history[-1][1] = f"⚠️ Error: {str(e)}"
343
  yield history
344
 
345
+ def process_code_blocks(text):
346
+ """Process markdown code blocks to use custom artifact styling"""
347
+ import re
348
 
349
  # Pattern for code blocks with language specification
350
+ pattern = r"```(\w+)\n(.*?)```"
351
 
352
+ def replace_code_block(match):
353
+ language = match.group(1)
354
+ code = match.group(2)
355
+ escaped_code = code.replace('`', r'\`')
356
 
357
+ html = (
358
+ '<div class="wrapper-artifact">'
359
+ f'<div class="header-artifact">'
360
+ f'<span>{language}</span>'
361
+ f'<button class="copy-button" onclick="copyToClipboard(`{escaped_code}`)">Copy</button>'
362
+ '</div>'
363
+ '<div class="content-artifact">'
364
+ f'<pre><code>{code}</code></pre>'
365
+ '</div>'
366
+ '</div>'
367
+ )
368
+ return html
369
 
370
  # Replace all code blocks in the text
371
+ processed_text = re.sub(pattern, replace_code_block, text, flags=re.DOTALL)
372
+ return processed_text
373
 
374
+ def create_ui():
375
+ # Get local time
376
+ local_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
377
+ analyzer = RepoAnalyzer()
378
+
379
+ with gr.Blocks(title="Repository Chat Analysis", theme=gr.themes.Soft()) as app:
380
+ gr.Markdown("""
381
  <style>
382
  .container { max-width: 100% !important; padding: 1rem; }
383
  .mobile-full { width: 100% !important; }
 
460
  </script>
461
  """)
462
 
463
+ # Header
464
+ with gr.Row(elem_classes="container"):
465
+ gr.Markdown(f"# πŸ€– Repository Chat Analysis\n\nπŸ“… {local_time}")
466
+
467
+ # Main Interface
468
+ with gr.Tabs() as tabs:
469
+ # Configuration Tab
470
+ with gr.Tab("πŸ› οΈ Konfigurasi", elem_classes="mobile-full"):
471
+ provider = gr.Radio(
472
+ choices=[AIProvider.XAI, AIProvider.GEMINI, AIProvider.OLLAMA],
473
+ label="Penyedia AI",
474
+ value=AIProvider.XAI,
475
+ interactive=True,
476
+ elem_classes="mobile-full"
477
+ )
478
+
479
+ with gr.Group() as api_settings:
480
+ # XAI API Key
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  with gr.Group():
482
  with gr.Row():
483
+ xai_key = gr.Textbox(
484
+ label="X.AI (Grok) API Key",
485
+ type="password",
486
+ placeholder="Opsional - Klik icon (?) untuk info",
487
+ show_label=True,
488
+ scale=3
489
  )
490
+ with gr.Column(scale=1):
491
+ gr.Markdown(XAI_API_HELP)
492
+
493
+ # Gemini API Key
494
+ with gr.Group():
495
  with gr.Row():
496
+ gemini_key = gr.Textbox(
497
+ label="Gemini API Key",
498
+ type="password",
499
+ placeholder="Opsional - Kosongkan untuk gunakan key default",
500
+ show_label=True,
501
+ scale=3
502
+ )
503
  with gr.Column(scale=1):
504
+ gr.Markdown(GEMINI_API_HELP)
505
+
506
+ # Model Selection
507
+ with gr.Row():
508
+ model_dropdown = gr.Dropdown(
509
+ label="Model AI",
510
+ choices=XAI_MODELS,
511
+ value="grok-2-latest",
512
+ interactive=True,
513
  elem_classes="mobile-full"
514
  )
515
+
516
+ # Repository Analysis Tab
517
+ with gr.Tab("πŸ“Š Analisis Repository", elem_classes="mobile-full"):
518
+ # Repository Input Section
519
+ with gr.Group():
520
+ with gr.Row():
521
+ repo_url = gr.Textbox(
522
+ label="URL Repository GitHub",
523
+ placeholder="https://github.com/username/repository",
524
+ elem_classes="mobile-full"
525
+ )
526
 
527
+ with gr.Row():
528
+ with gr.Column(scale=2):
529
+ github_token = gr.Textbox(
530
+ label="Token GitHub",
531
+ type="password",
532
+ placeholder="Klik icon (?) untuk panduan",
 
 
 
 
 
 
 
 
 
533
  elem_classes="mobile-full"
534
  )
535
+ with gr.Column(scale=1):
536
+ branch = gr.Textbox(
537
+ label="Branch (opsional)",
538
+ placeholder="main",
539
+ elem_classes="mobile-full"
540
+ )
541
+
542
+ # Clone Repository Section
543
+ clone_button = gr.Button(
544
+ "πŸ”„ Clone Repository",
545
+ variant="primary",
546
+ elem_classes="mobile-full"
 
 
547
  )
548
 
549
+ clone_status = gr.Markdown(
550
+ value="",
551
+ label="Status Repository",
552
+ elem_classes="mobile-full"
553
+ )
554
+
555
+ # File Selection Section
556
+ with gr.Group():
557
+ gr.Markdown("### πŸ“Ž File yang Dipilih")
558
+
559
  with gr.Row():
560
+ file_selector = gr.Dropdown(
561
+ label="Pilih File dari Repository",
562
+ choices=[],
563
+ multiselect=True,
564
+ elem_classes="mobile-full"
565
+ )
566
+
567
+ file_list = gr.HTML(
568
+ value="<div class='file-list'>Belum ada file yang dipilih</div>",
569
+ label="Daftar File Terpilih"
570
+ )
571
 
572
+ # Chat Interface (Outside tabs for full width)
573
+ with gr.Group():
574
+ chat_history = gr.Chatbot(
575
+ label="πŸ“ Riwayat Chat",
576
+ elem_classes="fullscreen-chat",
577
+ height=None,
578
+ show_label=True,
579
+ type="messages"
580
+ )
581
+
582
+ with gr.Group(elem_classes="chat-input"):
583
+ chat_input = gr.Textbox(
584
+ label="πŸ’­ Tanyakan tentang Repository",
585
+ placeholder="Ketik pertanyaan Anda di sini...",
586
+ lines=3,
587
+ elem_classes="mobile-full"
588
+ )
589
+ with gr.Row():
590
+ clear_button = gr.Button("🧹 Bersihkan", variant="secondary")
591
+ send_button = gr.Button("πŸ“€ Kirim", variant="primary")
592
+
593
+ # Event Handlers
594
  def clear_chat_history():
595
  return None
596
 
 
 
 
 
 
597
  def handle_clone(repo_url, github_token, branch):
598
  if not repo_url:
599
  return "⚠️ URL repository diperlukan!", [], []
 
600
  success, message = analyzer.clone_repository(repo_url, github_token, branch)
 
601
  if success:
 
602
  files = list(analyzer.repo_content.keys())
603
  return message, files, []
 
604
  return message, [], []
605
 
 
 
 
 
 
 
 
606
  def update_file_list(selected):
607
  if not selected:
608
  return "<div class='file-list'>Belum ada file yang dipilih</div>"
 
609
  html = "<div class='file-list'>"
610
  for file in selected:
611
  html += f"<div class='file-item'><span>{file}</span></div>"
612
  html += "</div>"
613
  return html
614
 
615
+ # Connect Events
616
+ clear_button.click(
617
+ fn=clear_chat_history,
618
+ outputs=chat_history
619
+ )
620
+
621
+ clone_button.click(
622
+ fn=handle_clone,
623
+ inputs=[repo_url, github_token, branch],
624
+ outputs=[clone_status, file_selector, file_list]
625
+ )
626
+
627
  file_selector.change(
628
  fn=update_file_list,
629
  inputs=[file_selector],
630
  outputs=[file_list]
631
  )
632
 
633
+ send_button.click(
 
634
  fn=handle_chat,
635
  inputs=[
636
  chat_input,
 
648
  outputs=chat_input
649
  )
650
 
651
+ chat_input.submit(
652
  fn=handle_chat,
653
  inputs=[
654
  chat_input,
 
666
  outputs=chat_input
667
  )
668
 
669
+ # Update model list when provider changes
670
+ def update_model_list(provider_choice):
671
+ if provider_choice == AIProvider.XAI:
672
+ return gr.Dropdown(choices=XAI_MODELS, value="grok-2-latest")
673
+ elif provider_choice == AIProvider.GEMINI:
674
+ return gr.Dropdown(choices=GEMINI_MODELS, value="gemini-pro")
675
+ else: # OLLAMA
676
+ return gr.Dropdown(choices=OLLAMA_MODELS, value="llama2")
677
+
678
+ provider.change(
679
+ fn=update_model_list,
680
+ inputs=[provider],
681
+ outputs=[model_dropdown]
682
+ )
683
+
684
  return app
685
 
686
  if __name__ == "__main__":
687
  print(f"""
688
  πŸš€ Memulai Repository Chat Analysis
689
+ πŸ“… Current Date and Time (UTC): {datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")}
690
  """)
691
 
692
  app = create_ui()