Spaces:
Sleeping
Sleeping
| """ | |
| 🤖 Fagun Browser Automation Testing Agent - WebUI Manager | |
| ========================================================= | |
| Core management system for the Fagun Browser Automation Testing Agent. | |
| Author: Mejbaur Bahar Fagun | |
| Role: Software Engineer in Test | |
| LinkedIn: https://www.linkedin.com/in/mejbaur/ | |
| """ | |
| import json | |
| from collections.abc import Generator | |
| from typing import TYPE_CHECKING | |
| import os | |
| import gradio as gr | |
| from datetime import datetime | |
| from typing import Optional, Dict, List | |
| import uuid | |
| import asyncio | |
| import time | |
| from gradio.components import Component | |
| from browser_use.browser.browser import Browser | |
| from browser_use.browser.context import BrowserContext | |
| from browser_use.agent.service import Agent | |
| from src.browser.custom_browser import CustomBrowser | |
| from src.browser.custom_context import CustomBrowserContext | |
| from src.controller.custom_controller import CustomController | |
| from src.agent.deep_research.deep_research_agent import DeepResearchAgent | |
| class WebuiManager: | |
| def __init__(self, settings_save_dir: str = "./tmp/webui_settings"): | |
| self.id_to_component: dict[str, Component] = {} | |
| self.component_to_id: dict[Component, str] = {} | |
| self.settings_save_dir = settings_save_dir | |
| os.makedirs(self.settings_save_dir, exist_ok=True) | |
| def init_browser_use_agent(self) -> None: | |
| """ | |
| init browser use agent | |
| """ | |
| self.bu_agent: Optional[Agent] = None | |
| self.bu_browser: Optional[CustomBrowser] = None | |
| self.bu_browser_context: Optional[CustomBrowserContext] = None | |
| self.bu_controller: Optional[CustomController] = None | |
| self.bu_chat_history: List[Dict[str, Optional[str]]] = [] | |
| self.bu_response_event: Optional[asyncio.Event] = None | |
| self.bu_last_pdf_report: Optional[str] = None | |
| self.bu_user_help_response: Optional[str] = None | |
| self.bu_current_task: Optional[asyncio.Task] = None | |
| self.bu_agent_task_id: Optional[str] = None | |
| def init_deep_research_agent(self) -> None: | |
| """ | |
| init deep research agent | |
| """ | |
| self.dr_agent: Optional[DeepResearchAgent] = None | |
| self.dr_current_task = None | |
| self.dr_agent_task_id: Optional[str] = None | |
| self.dr_save_dir: Optional[str] = None | |
| def add_components(self, tab_name: str, components_dict: dict[str, "Component"]) -> None: | |
| """ | |
| Add tab components | |
| """ | |
| for comp_name, component in components_dict.items(): | |
| comp_id = f"{tab_name}.{comp_name}" | |
| self.id_to_component[comp_id] = component | |
| self.component_to_id[component] = comp_id | |
| def get_components(self) -> list["Component"]: | |
| """ | |
| Get all components | |
| """ | |
| return list(self.id_to_component.values()) | |
| def get_component_by_id(self, comp_id: str) -> "Component": | |
| """ | |
| Get component by id | |
| """ | |
| return self.id_to_component[comp_id] | |
| def get_id_by_component(self, comp: "Component") -> str: | |
| """ | |
| Get id by component | |
| """ | |
| return self.component_to_id[comp] | |
| def save_config(self, components: Dict["Component", str]) -> None: | |
| """ | |
| Save config | |
| """ | |
| cur_settings = {} | |
| for comp in components: | |
| if not isinstance(comp, gr.Button) and not isinstance(comp, gr.File) and str( | |
| getattr(comp, "interactive", True)).lower() != "false": | |
| comp_id = self.get_id_by_component(comp) | |
| cur_settings[comp_id] = components[comp] | |
| config_name = datetime.now().strftime("%Y%m%d-%H%M%S") | |
| with open(os.path.join(self.settings_save_dir, f"{config_name}.json"), "w") as fw: | |
| json.dump(cur_settings, fw, indent=4) | |
| return os.path.join(self.settings_save_dir, f"{config_name}.json") | |
| def load_config(self, config_path: str): | |
| """ | |
| Load config | |
| """ | |
| with open(config_path, "r") as fr: | |
| ui_settings = json.load(fr) | |
| update_components = {} | |
| for comp_id, comp_val in ui_settings.items(): | |
| if comp_id in self.id_to_component: | |
| comp = self.id_to_component[comp_id] | |
| if comp.__class__.__name__ == "Chatbot": | |
| update_components[comp] = comp.__class__(value=comp_val, type="messages") | |
| else: | |
| update_components[comp] = comp.__class__(value=comp_val) | |
| if comp_id == "agent_settings.planner_llm_provider": | |
| yield update_components # yield provider, let callback run | |
| time.sleep(0.1) # wait for Gradio UI callback | |
| # Note: load_save_config component was removed from the interface | |
| yield update_components | |
| def update_pdf_report_status(self, report_path: Optional[str] = None, status_message: str = "Report will be generated automatically after testing completion"): | |
| """Update the PDF report status and file.""" | |
| update_components = {} | |
| # Update report status | |
| if "browser_use_agent.auto_report_status" in self.id_to_component: | |
| status_comp = self.id_to_component["browser_use_agent.auto_report_status"] | |
| update_components[status_comp] = status_comp.__class__(value=status_message) | |
| # Update report file if path is provided | |
| if report_path and "browser_use_agent.auto_pdf_report" in self.id_to_component: | |
| report_comp = self.id_to_component["browser_use_agent.auto_pdf_report"] | |
| update_components[report_comp] = report_comp.__class__(value=report_path, visible=True) | |
| self.bu_last_pdf_report = report_path | |
| return update_components | |