Spaces:
Runtime error
Runtime error
Leonardo
commited on
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,8 +5,7 @@ import os
|
|
| 5 |
import re
|
| 6 |
import shutil
|
| 7 |
import datetime
|
| 8 |
-
import
|
| 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
|
| 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:
|
| 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
|
| 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,7 +385,7 @@ class GradioUI:
|
|
| 385 |
)
|
| 386 |
)
|
| 387 |
yield messages
|
| 388 |
-
return
|
| 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}.
|
| 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 |
-
#
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 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 |
-
|
| 646 |
-
[chatbot, stored_messages, session_state, uploaded_files_state],
|
| 647 |
)
|
| 648 |
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 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("
|
| 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="
|
| 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 |
-
|
| 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 |
-
[
|
| 733 |
).then(
|
| 734 |
self.interact_with_agent,
|
| 735 |
-
[
|
| 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 |
-
|
| 746 |
-
[text_input, launch_research_btn],
|
| 747 |
)
|
| 748 |
|
| 749 |
-
|
|
|
|
| 750 |
self.log_user_message,
|
| 751 |
-
[text_input],
|
| 752 |
-
[
|
| 753 |
).then(
|
| 754 |
self.interact_with_agent,
|
| 755 |
-
[
|
| 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 |
-
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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__":
|