Leonardo commited on
Commit
e2e1581
·
verified ·
1 Parent(s): 09f2cff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -94
app.py CHANGED
@@ -5,8 +5,7 @@ import os
5
  import re
6
  import shutil
7
  import datetime
8
- import mimetypes
9
- from typing import Optional, List, Dict, Tuple
10
 
11
  from dotenv import load_dotenv
12
  from huggingface_hub import login
@@ -150,7 +149,7 @@ class ModelManager:
150
  @staticmethod
151
  def load_model(
152
  chosen_inference: str, model_id: str, key_manager: Optional[object] = None
153
- ):
154
  """Load the specified model with appropriate configuration.
155
 
156
  Args:
@@ -275,15 +274,16 @@ def create_agent() -> CodeAgent:
275
 
276
  try:
277
  doc_tools = ToolRegistry.load_document_tools()
278
- except AssertionError as e:
279
  print(f"Warning: Error loading document tools: {str(e)}")
280
  print("Attempting to continue with available tools...")
 
281
 
282
  image_generator = ToolRegistry.load_image_generation_tools()
283
 
284
  # Combine available tools (filter out None values)
285
  all_tools = [visualizer] + web_tools + doc_tools
286
- if image_generator: # Add only if it's not None
287
  all_tools.append(image_generator)
288
 
289
  # Log available tools
@@ -305,11 +305,11 @@ def create_agent() -> CodeAgent:
305
 
306
 
307
  def stream_to_gradio(
308
- agent,
309
  task: str,
310
  reset_agent_memory: bool = False,
311
  additional_args: Optional[dict] = None,
312
- ):
313
  """Runs an agent with the given task and streams messages as Gradio ChatMessages."""
314
  try:
315
  for step_log in agent.run(
@@ -354,10 +354,10 @@ def stream_to_gradio(
354
  class GradioUI:
355
  """A one-line interface to launch your agent in Gradio."""
356
 
357
- def __init__(self, file_upload_folder: str | None = None):
358
  """Initialize the Gradio UI with optional file upload functionality."""
359
  self.file_upload_folder = file_upload_folder
360
- self.allowed_extensions = ALLOWED_EXTENSIONS # Use the constant
361
 
362
  if self.file_upload_folder:
363
  os.makedirs(self.file_upload_folder, exist_ok=True)
@@ -385,7 +385,7 @@ class GradioUI:
385
  )
386
  )
387
  yield messages
388
- return # Exit if can't create agent
389
 
390
  session_state["request_count"] += 1
391
 
@@ -419,7 +419,7 @@ class GradioUI:
419
  except Exception as e:
420
  prompt_with_files = prompt
421
  print(
422
- f"WARNING: Error processing files: {e}. Continuing without file info."
423
  )
424
 
425
  try:
@@ -455,7 +455,14 @@ class GradioUI:
455
  )
456
 
457
  def upload_file(self, files: List[str]) -> Tuple[str, List[str]]:
458
- """Handle file uploads with validation, security, and clear feedback."""
 
 
 
 
 
 
 
459
  if not files:
460
  return "No file uploaded", []
461
 
@@ -523,52 +530,14 @@ class GradioUI:
523
  def launch(self, **kwargs):
524
  """Launch the Gradio UI with responsive layout."""
525
  with gr.Blocks(theme="ocean", fill_height=True) as demo:
526
- # JavaScript-based layout
527
- demo.load(
528
- None, # No server-side function on load
529
- [],
530
- [],
531
- _js="""
532
- () => {
533
- const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
534
- if (isMobile) {
535
- // Mobile-specific logic (e.g., hide/show certain elements)
536
- document.body.classList.add('mobile-layout'); // Example: Add a CSS class
537
- console.log('Mobile layout applied.');
538
- } else {
539
- // Desktop-specific logic
540
- document.body.classList.add('desktop-layout');
541
- console.log('Desktop layout applied.');
542
- }
543
- }
544
- """,
545
- )
546
-
547
- desktop_layout = self._create_desktop_layout()
548
- mobile_layout = self._create_mobile_layout()
549
-
550
- # Conditional visibility of the layout
551
- js_function = """
552
- () => {
553
- const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
554
- if (isMobile) {
555
- return ['block','none'];
556
- } else {
557
- return ['none','block'];
558
- }
559
- }
560
- """
561
-
562
- # Set the visibility of the layouts based on the clients device
563
- mobile_layout.style = {"display": "none"} # Hide by default
564
- desktop_layout.style = {"display": "none"} # Hide by default
565
-
566
- gr.on(
567
- [],
568
- [],
569
- [mobile_layout, desktop_layout],
570
- js_function,
571
- )
572
 
573
  demo.queue(max_size=20).launch(debug=True, **kwargs)
574
 
@@ -642,16 +611,14 @@ class GradioUI:
642
 
643
  clear_btn.click(
644
  lambda: ([], [], {"agent": session_state.get("agent")}, []),
645
- None,
646
- [chatbot, stored_messages, session_state, uploaded_files_state],
647
  )
648
 
649
- if self.file_upload_folder:
650
- file_upload.change(
651
- self.upload_file,
652
- [file_upload],
653
- [upload_status, uploaded_files_state],
654
- )
655
 
656
  self._connect_event_handlers(
657
  text_input,
@@ -667,7 +634,7 @@ class GradioUI:
667
  def _create_mobile_layout(self):
668
  """Create the mobile layout (simpler without sidebar)."""
669
  with gr.Column(visible=False) as simple_demo:
670
- gr.Markdown("""#OpenDeepResearch - free the AI agents!""")
671
  session_state = gr.State({})
672
  stored_messages = gr.State([])
673
  file_upload = gr.File(
@@ -678,7 +645,7 @@ class GradioUI:
678
  uploaded_files_state = gr.State([])
679
 
680
  chatbot = gr.Chatbot(
681
- label="open-Deep-Research",
682
  type="messages",
683
  avatar_images=(
684
  None,
@@ -718,52 +685,51 @@ class GradioUI:
718
 
719
  def _connect_event_handlers(
720
  self,
721
- text_input,
722
- launch_research_btn,
723
- stored_messages,
724
- chatbot,
725
- session_state,
726
- uploaded_files_state,
727
- ):
728
- """Connect the event handlers for input elements."""
 
 
729
  text_input.submit(
730
  self.log_user_message,
731
- [text_input],
732
- [stored_messages, text_input, launch_research_btn],
733
  ).then(
734
  self.interact_with_agent,
735
- [stored_messages, chatbot, session_state, uploaded_files_state],
736
- [chatbot],
737
  ).then(
738
  lambda: (
739
  gr.Textbox(
740
- interactive=True,
741
- placeholder="Enter your prompt here and press the button",
742
  ),
743
  gr.Button(interactive=True),
744
  ),
745
- None,
746
- [text_input, launch_research_btn],
747
  )
748
 
749
- launch_research_btn.click(
 
750
  self.log_user_message,
751
- [text_input],
752
- [stored_messages, text_input, launch_research_btn],
753
  ).then(
754
  self.interact_with_agent,
755
- [stored_messages, chatbot, session_state, uploaded_files_state],
756
- [chatbot],
757
  ).then(
758
  lambda: (
759
  gr.Textbox(
760
- interactive=True,
761
- placeholder="Enter your prompt here and press the button",
762
  ),
763
  gr.Button(interactive=True),
764
  ),
765
- None,
766
- [text_input, launch_research_btn],
767
  )
768
 
769
 
@@ -772,7 +738,14 @@ def main():
772
  """Main entry point for the application."""
773
  setup_environment()
774
  os.makedirs(f"./{BROWSER_CONFIG['downloads_folder']}", exist_ok=True)
775
- GradioUI(file_upload_folder="uploaded_files").launch()
 
 
 
 
 
 
 
776
 
777
 
778
  if __name__ == "__main__":
 
5
  import re
6
  import shutil
7
  import datetime
8
+ from typing import Optional, List, Dict, Tuple, Generator, Union
 
9
 
10
  from dotenv import load_dotenv
11
  from huggingface_hub import login
 
149
  @staticmethod
150
  def load_model(
151
  chosen_inference: str, model_id: str, key_manager: Optional[object] = None
152
+ ) -> Union[HfApiModel, LiteLLMModel, OpenAIServerModel, TransformersModel]:
153
  """Load the specified model with appropriate configuration.
154
 
155
  Args:
 
274
 
275
  try:
276
  doc_tools = ToolRegistry.load_document_tools()
277
+ except Exception as e:
278
  print(f"Warning: Error loading document tools: {str(e)}")
279
  print("Attempting to continue with available tools...")
280
+ doc_tools = []
281
 
282
  image_generator = ToolRegistry.load_image_generation_tools()
283
 
284
  # Combine available tools (filter out None values)
285
  all_tools = [visualizer] + web_tools + doc_tools
286
+ if image_generator:
287
  all_tools.append(image_generator)
288
 
289
  # Log available tools
 
305
 
306
 
307
  def stream_to_gradio(
308
+ agent: CodeAgent,
309
  task: str,
310
  reset_agent_memory: bool = False,
311
  additional_args: Optional[dict] = None,
312
+ ) -> Generator[gr.ChatMessage, None, None]:
313
  """Runs an agent with the given task and streams messages as Gradio ChatMessages."""
314
  try:
315
  for step_log in agent.run(
 
354
  class GradioUI:
355
  """A one-line interface to launch your agent in Gradio."""
356
 
357
+ def __init__(self, file_upload_folder: Optional[str] = None):
358
  """Initialize the Gradio UI with optional file upload functionality."""
359
  self.file_upload_folder = file_upload_folder
360
+ self.allowed_extensions = ALLOWED_EXTENSIONS
361
 
362
  if self.file_upload_folder:
363
  os.makedirs(self.file_upload_folder, exist_ok=True)
 
385
  )
386
  )
387
  yield messages
388
+ return
389
 
390
  session_state["request_count"] += 1
391
 
 
419
  except Exception as e:
420
  prompt_with_files = prompt
421
  print(
422
+ f"WARNING: Error processing files: {e}. Continuing without file info."
423
  )
424
 
425
  try:
 
455
  )
456
 
457
  def upload_file(self, files: List[str]) -> Tuple[str, List[str]]:
458
+ """Handle file uploads with validation, security, and clear feedback.
459
+
460
+ Args:
461
+ files: List of file paths to upload
462
+
463
+ Returns:
464
+ Tuple of (status message, list of uploaded file paths)
465
+ """
466
  if not files:
467
  return "No file uploaded", []
468
 
 
530
  def launch(self, **kwargs):
531
  """Launch the Gradio UI with responsive layout."""
532
  with gr.Blocks(theme="ocean", fill_height=True) as demo:
533
+ # Different layouts for mobile and computer devices
534
+ @gr.render()
535
+ def layout(request: gr.Request):
536
+ device = self.detect_device(request)
537
+ print(f"Device detected: {device}")
538
+ if device == "Desktop":
539
+ return self._create_desktop_layout()
540
+ return self._create_mobile_layout()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
 
542
  demo.queue(max_size=20).launch(debug=True, **kwargs)
543
 
 
611
 
612
  clear_btn.click(
613
  lambda: ([], [], {"agent": session_state.get("agent")}, []),
614
+ outputs=[chatbot, stored_messages, session_state, uploaded_files_state],
 
615
  )
616
 
617
+ file_upload.change(
618
+ self.upload_file,
619
+ inputs=[file_upload],
620
+ outputs=[upload_status, uploaded_files_state],
621
+ )
 
622
 
623
  self._connect_event_handlers(
624
  text_input,
 
634
  def _create_mobile_layout(self):
635
  """Create the mobile layout (simpler without sidebar)."""
636
  with gr.Column(visible=False) as simple_demo:
637
+ gr.Markdown("# OpenDeepResearch - free the AI agents!")
638
  session_state = gr.State({})
639
  stored_messages = gr.State([])
640
  file_upload = gr.File(
 
645
  uploaded_files_state = gr.State([])
646
 
647
  chatbot = gr.Chatbot(
648
+ label="OpenDeepResearch",
649
  type="messages",
650
  avatar_images=(
651
  None,
 
685
 
686
  def _connect_event_handlers(
687
  self,
688
+ text_input: gr.Textbox,
689
+ launch_btn: gr.Button,
690
+ stored_messages: gr.State,
691
+ chatbot: gr.Chatbot,
692
+ session_state: gr.State,
693
+ uploaded_files_state: gr.State,
694
+ ) -> None:
695
+ """Connect the event handlers for input elements with proper flow control."""
696
+
697
+ # Text input submission handler
698
  text_input.submit(
699
  self.log_user_message,
700
+ inputs=[text_input],
701
+ outputs=[text_input, text_input, launch_btn],
702
  ).then(
703
  self.interact_with_agent,
704
+ inputs=[text_input, stored_messages, session_state, uploaded_files_state],
705
+ outputs=[chatbot],
706
  ).then(
707
  lambda: (
708
  gr.Textbox(
709
+ value="", interactive=True, placeholder="Enter your prompt here..."
 
710
  ),
711
  gr.Button(interactive=True),
712
  ),
713
+ outputs=[text_input, launch_btn],
 
714
  )
715
 
716
+ # Button click handler (same flow)
717
+ launch_btn.click(
718
  self.log_user_message,
719
+ inputs=[text_input],
720
+ outputs=[text_input, text_input, launch_btn],
721
  ).then(
722
  self.interact_with_agent,
723
+ inputs=[text_input, stored_messages, session_state, uploaded_files_state],
724
+ outputs=[chatbot],
725
  ).then(
726
  lambda: (
727
  gr.Textbox(
728
+ value="", interactive=True, placeholder="Enter your prompt here..."
 
729
  ),
730
  gr.Button(interactive=True),
731
  ),
732
+ outputs=[text_input, launch_btn],
 
733
  )
734
 
735
 
 
738
  """Main entry point for the application."""
739
  setup_environment()
740
  os.makedirs(f"./{BROWSER_CONFIG['downloads_folder']}", exist_ok=True)
741
+
742
+ # Set up file upload directory
743
+ upload_folder = os.path.join(os.getcwd(), "uploads")
744
+ os.makedirs(upload_folder, exist_ok=True)
745
+
746
+ # Initialize and launch the UI
747
+ ui = GradioUI(file_upload_folder=upload_folder)
748
+ ui.launch(share=True)
749
 
750
 
751
  if __name__ == "__main__":