From 6ac9e268d31da5cca65dd3207123e171f253b877 Mon Sep 17 00:00:00 2001 From: vvincent1234 Date: Sun, 27 Apr 2025 23:28:47 +0800 Subject: [PATCH] add ui --- src/webui/components/agent_settings_tab.py | 36 ++++- src/webui/components/browser_settings_tab.py | 125 ++++++++++++++++++ src/webui/components/browser_use_agent_tab.py | 62 +++++++++ ...arch_tab.py => deep_research_agent_tab.py} | 0 src/webui/components/run_agent_tab.py | 4 - src/webui/interface.py | 6 +- tests/test_controller.py | 30 ++--- 7 files changed, 239 insertions(+), 24 deletions(-) create mode 100644 src/webui/components/browser_use_agent_tab.py rename src/webui/components/{run_deep_research_tab.py => deep_research_agent_tab.py} (100%) delete mode 100644 src/webui/components/run_agent_tab.py diff --git a/src/webui/components/agent_settings_tab.py b/src/webui/components/agent_settings_tab.py index 4f69ac1..764487c 100644 --- a/src/webui/components/agent_settings_tab.py +++ b/src/webui/components/agent_settings_tab.py @@ -1,8 +1,14 @@ +import json +import os + import gradio as gr from gradio.components import Component - +from typing import Any, Dict, Optional from src.webui.webui_manager import WebuiManager from src.utils import config +import logging + +logger = logging.getLogger(__name__) def update_model_dropdown(llm_provider): @@ -17,6 +23,20 @@ def update_model_dropdown(llm_provider): return gr.Dropdown(choices=[], value="", interactive=True, allow_custom_value=True) +def update_mcp_server(mcp_file: str): + """ + Update the MCP server. + """ + if not mcp_file or not os.path.exists(mcp_file) or mcp_file.endswith('.json'): + logger.warning(f"{mcp_file} is not a valid MCP file.") + return gr.update() + + with open(mcp_file, 'r') as f: + mcp_server = json.load(f) + + return gr.update(value=json.dumps(mcp_server, indent=2), visible=True) + + def create_agent_settings_tab(webui_manager: WebuiManager) -> dict[str, Component]: """ Creates an agent settings tab. @@ -29,6 +49,10 @@ def create_agent_settings_tab(webui_manager: WebuiManager) -> dict[str, Componen override_system_prompt = gr.Textbox(label="Override system prompt", lines=4, interactive=True) extend_system_prompt = gr.Textbox(label="Extend system prompt", lines=4, interactive=True) + with gr.Group(): + mcp_json_file = gr.File(label="MCP server file", interactive=True, file_types=["json"]) + mcp_server_config = gr.Textbox(label="MCP server", lines=6, interactive=True, visible=False) + with gr.Group(): with gr.Row(): llm_provider = gr.Dropdown( @@ -92,7 +116,6 @@ def create_agent_settings_tab(webui_manager: WebuiManager) -> dict[str, Componen with gr.Row(): planner_llm_provider = gr.Dropdown( choices=[provider for provider, model in config.model_names.items()], - value=None, label="Planner LLM Provider", info="Select LLM provider for LLM", interactive=True @@ -202,7 +225,8 @@ def create_agent_settings_tab(webui_manager: WebuiManager) -> dict[str, Componen max_actions=max_actions, max_input_tokens=max_input_tokens, tool_calling_method=tool_calling_method, - + mcp_json_file=mcp_json_file, + mcp_server_config=mcp_server_config, )) llm_provider.change( fn=lambda x: gr.update(visible=x == "ollama"), @@ -225,4 +249,10 @@ def create_agent_settings_tab(webui_manager: WebuiManager) -> dict[str, Componen outputs=planner_llm_model_name ) + mcp_json_file.change( + update_mcp_server, + inputs=mcp_json_file, + outputs=mcp_server_config + ) + return tab_components diff --git a/src/webui/components/browser_settings_tab.py b/src/webui/components/browser_settings_tab.py index e69de29..c2b3e56 100644 --- a/src/webui/components/browser_settings_tab.py +++ b/src/webui/components/browser_settings_tab.py @@ -0,0 +1,125 @@ +import gradio as gr +from gradio.components import Component + +from src.webui.webui_manager import WebuiManager +from src.utils import config + + +def create_browser_settings_tab(webui_manager: WebuiManager) -> dict[str, Component]: + """ + Creates a browser settings tab. + """ + input_components = set(webui_manager.get_components()) + tab_components = {} + + with gr.Group(): + with gr.Row(): + browser_binary_path = gr.Textbox( + label="Browser Binary Path", + lines=1, + interactive=True, + placeholder="e.g. '/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome'" + ) + browser_user_data_dir = gr.Textbox( + label="Browser User Data Dir", + lines=1, + interactive=True, + placeholder="Leave it empty if you use your default user data", + ) + with gr.Row(): + use_own_browser = gr.Checkbox( + label="Use Own Browser", + value=False, + info="Use your existing browser instance", + interactive=True + ) + keep_browser_open = gr.Checkbox( + label="Keep Browser Open", + value=False, + info="Keep Browser Open between Tasks", + interactive=True + ) + headless = gr.Checkbox( + label="Headless Mode", + value=False, + info="Run browser without GUI", + interactive=True + ) + disable_security = gr.Checkbox( + label="Disable Security", + value=True, + info="Disable browser security features", + interactive=True + ) + + with gr.Row(): + window_w = gr.Number( + label="Window Width", + value=1280, + info="Browser window width", + interactive=True + ) + window_h = gr.Number( + label="Window Height", + value=1100, + info="Browser window height", + interactive=True + ) + + with gr.Row(): + cdp_url = gr.Textbox( + label="CDP URL", + info="CDP URL for browser remote debugging", + interactive=True, + ) + wss_url = gr.Textbox( + label="WSS URL", + info="WSS URL for browser remote debugging", + interactive=True, + ) + + with gr.Row(): + save_recording_path = gr.Textbox( + label="Recording Path", + placeholder="e.g. ./tmp/record_videos", + info="Path to save browser recordings", + interactive=True, + ) + + save_trace_path = gr.Textbox( + label="Trace Path", + placeholder="e.g. ./tmp/traces", + info="Path to save Agent traces", + interactive=True, + ) + + with gr.Row(): + save_agent_history_path = gr.Textbox( + label="Agent History Save Path", + value="./tmp/agent_history", + info="Specify the directory where agent history should be saved.", + interactive=True, + ) + save_download_path = gr.Textbox( + label="Save Directory for browser downloads", + value="./tmp/downloads", + info="Specify the directory where downloaded files should be saved.", + interactive=True, + ) + tab_components.update( + dict( + browser_binary_path=browser_binary_path, + browser_user_data_dir=browser_user_data_dir, + use_own_browser=use_own_browser, + keep_browser_open=keep_browser_open, + headless=headless, + disable_security=disable_security, + save_recording_path=save_recording_path, + save_trace_path=save_trace_path, + save_agent_history_path=save_agent_history_path, + save_download_path=save_download_path, + cdp_url=cdp_url, + wss_url=wss_url + ) + ) + return tab_components diff --git a/src/webui/components/browser_use_agent_tab.py b/src/webui/components/browser_use_agent_tab.py new file mode 100644 index 0000000..0534872 --- /dev/null +++ b/src/webui/components/browser_use_agent_tab.py @@ -0,0 +1,62 @@ +import gradio as gr +from gradio.components import Component + +from src.webui.webui_manager import WebuiManager +from src.utils import config + + +def create_browser_use_agent_tab(webui_manager: WebuiManager) -> dict[str, Component]: + """ + Create the run agent tab + """ + input_components = set(webui_manager.get_components()) + tab_components = {} + + chatbot = gr.Chatbot(type='messages', label="Chat History", height=600) + user_input = gr.Textbox( + label="User Input", + lines=3, + value="go to google.com and type 'OpenAI' click search and give me the first url", + interactive=True + ) + + with gr.Row(): + stop_button = gr.Button("âšī¸ Stop", interactive=False, variant="stop", scale=2) + clear_button = gr.Button("🧹 Clear", interactive=False, variant="stop", scale=2) + run_button = gr.Button("â–ļī¸ Summit", variant="primary", scale=3) + + browser_view = gr.HTML( + value="

Waiting for browser session...

", + label="Browser Live View", + visible=False + ) + + with gr.Row(): + agent_final_result = gr.Textbox( + label="Final Result", lines=3, show_label=True, interactive=False + ) + agent_errors = gr.Textbox( + label="Errors", lines=3, show_label=True, interactive=False + ) + + with gr.Row(): + agent_trace_file = gr.File(label="Trace File", interactive=False) + agent_history_file = gr.File(label="Agent History", interactive=False) + + recording_gif = gr.Image(label="Result GIF", format="gif", interactive=False) + tab_components.update( + dict( + chatbot=chatbot, + user_input=user_input, + clear_button=clear_button, + run_button=run_button, + stop_button=stop_button, + agent_final_result=agent_final_result, + agent_errors=agent_errors, + agent_trace_file=agent_trace_file, + agent_history_file=agent_history_file, + recording_gif=recording_gif, + browser_view=browser_view + ) + ) + return tab_components diff --git a/src/webui/components/run_deep_research_tab.py b/src/webui/components/deep_research_agent_tab.py similarity index 100% rename from src/webui/components/run_deep_research_tab.py rename to src/webui/components/deep_research_agent_tab.py diff --git a/src/webui/components/run_agent_tab.py b/src/webui/components/run_agent_tab.py deleted file mode 100644 index a071a83..0000000 --- a/src/webui/components/run_agent_tab.py +++ /dev/null @@ -1,4 +0,0 @@ -import gradio as gr - -def creat_auto_agent_tab(): - pass \ No newline at end of file diff --git a/src/webui/interface.py b/src/webui/interface.py index e2690a9..a53d1f8 100644 --- a/src/webui/interface.py +++ b/src/webui/interface.py @@ -2,6 +2,8 @@ import gradio as gr from src.webui.webui_manager import WebuiManager from src.webui.components.agent_settings_tab import create_agent_settings_tab +from src.webui.components.browser_settings_tab import create_browser_settings_tab +from src.webui.components.browser_use_agent_tab import create_browser_use_agent_tab theme_map = { "Default": gr.themes.Default(), @@ -54,10 +56,10 @@ def create_ui(theme_name="Ocean"): ui_manager.add_components("agent_settings", create_agent_settings_tab(ui_manager)) with gr.TabItem("🌐 Browser Settings"): - pass + ui_manager.add_components("browser_settings", create_browser_settings_tab(ui_manager)) with gr.TabItem("🤖 Run Agent"): - pass + ui_manager.add_components("browser_use_agent", create_browser_use_agent_tab(ui_manager)) with gr.TabItem("🧐 Deep Research"): pass diff --git a/tests/test_controller.py b/tests/test_controller.py index ef859ed..6a10ebc 100644 --- a/tests/test_controller.py +++ b/tests/test_controller.py @@ -46,21 +46,21 @@ async def test_controller_with_mcp(): from browser_use.controller.registry.views import ActionModel test_server_config = { - # "playwright": { - # "command": "npx", - # "args": [ - # "@playwright/mcp@latest", - # ], - # "transport": "stdio", - # }, - # "filesystem": { - # "command": "npx", - # "args": [ - # "-y", - # "@modelcontextprotocol/server-filesystem", - # "/Users/xxx/ai_workspace", - # ] - # }, + "playwright": { + "command": "npx", + "args": [ + "@playwright/mcp@latest", + ], + "transport": "stdio", + }, + "filesystem": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + "/Users/xxx/ai_workspace", + ] + }, "desktop-commander": { "command": "npx", "args": [