import os from distutils.util import strtobool import gradio as gr import logging from gradio.components import Component from src.webui.webui_manager import WebuiManager from src.utils import config logger = logging.getLogger(__name__) async def close_browser(webui_manager: WebuiManager): """ Close browser """ if webui_manager.bu_current_task and not webui_manager.bu_current_task.done(): webui_manager.bu_current_task.cancel() webui_manager.bu_current_task = None if webui_manager.bu_browser_context: logger.info("⚠️ Closing browser context when changing browser config.") await webui_manager.bu_browser_context.close() webui_manager.bu_browser_context = None if webui_manager.bu_browser: logger.info("⚠️ Closing browser when changing browser config.") await webui_manager.bu_browser.close() webui_manager.bu_browser = None def create_browser_settings_tab(webui_manager: WebuiManager): """ Creates a browser settings tab. """ # Create components and store them in a dictionary # Explicitly define component IDs for clarity and consistency components_to_register = { "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", ), "use_own_browser": gr.Checkbox( label="Use Own Browser", value=bool(strtobool(os.getenv("USE_OWN_BROWSER", "false"))), info="Use your existing browser instance", interactive=True ), "keep_browser_open": gr.Checkbox( label="Keep Browser Open", value=bool(strtobool(os.getenv("KEEP_BROWSER_OPEN", "true"))), info="Keep Browser Open between Tasks", interactive=True ), "browser_headless": gr.Checkbox( label="Headless Mode", value=False, info="Run browser without GUI", interactive=True ), "disable_security": gr.Checkbox( label="Disable Security", value=False, info="Disable browser security", interactive=True ), "browser_viewport_width": gr.Number( label="Window Width", value=1280, info="Browser window width", interactive=True ), "browser_viewport_height": gr.Number( label="Window Height", value=1100, info="Browser window height", interactive=True ), "cdp_url": gr.Textbox( label="CDP URL", value=os.getenv("BROWSER_CDP", None), 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, ), "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, ), "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, ), } # Register components with the WebuiManager using their full IDs webui_manager.add_components("browser_settings", components_to_register) # Group and render components within the Gradio UI with gr.Group(): with gr.Row(): components_to_register["browser_binary_path"] components_to_register["browser_user_data_dir"] with gr.Group(): with gr.Row(): components_to_register["use_own_browser"] components_to_register["keep_browser_open"] components_to_register["browser_headless"] components_to_register["disable_security"] with gr.Group(): with gr.Row(): components_to_register["browser_viewport_width"] components_to_register["browser_viewport_height"] with gr.Group(): with gr.Row(): components_to_register["cdp_url"] components_to_register["wss_url"] with gr.Group(): with gr.Row(): components_to_register["save_recording_path"] components_to_register["save_trace_path"] with gr.Row(): components_to_register["save_agent_history_path"] components_to_register["save_download_path"] async def close_wrapper(): """Wrapper for handle_clear.""" await close_browser(webui_manager) # Attach change events to relevant components to trigger browser close components_to_register["browser_headless"].change(close_wrapper) components_to_register["keep_browser_open"].change(close_wrapper) components_to_register["disable_security"].change(close_wrapper) components_to_register["use_own_browser"].change(close_wrapper) components_to_register["browser_viewport_width"].change(close_wrapper) components_to_register["browser_viewport_height"].change(close_wrapper) components_to_register["cdp_url"].change(close_wrapper) components_to_register["wss_url"].change(close_wrapper) # Return a dictionary of components for interface.py to use for rendering return components_to_register