Spaces:
Running
Running
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, Any | |
import uuid | |
import asyncio | |
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) | |
# Add type annotation for vayner_pdf_report | |
self.vayner_pdf_report: Optional[str] = None | |
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_user_help_response: Optional[str] = None | |
self.bu_current_task: Optional[asyncio.Task] = None | |
self.bu_agent_task_id: Optional[str] = None | |
self.bu_task_metrics: Optional[Dict[str, Any]] = None | |
def init_vayner_client_research(self) -> None: | |
""" | |
Initialize Vayner Client Research components and state | |
""" | |
if not hasattr(self, "vayner_chat_history"): | |
self.vayner_chat_history = [] | |
if not hasattr(self, "vayner_pdf_report"): | |
self.vayner_pdf_report = None | |
if not hasattr(self, "vayner_controller"): | |
self.vayner_controller = None | |
if not hasattr(self, "vayner_browser"): | |
self.vayner_browser = None | |
if not hasattr(self, "vayner_browser_context"): | |
self.vayner_browser_context = None | |
if not hasattr(self, "vayner_agent"): | |
self.vayner_agent = None | |
if not hasattr(self, "vayner_current_task"): | |
self.vayner_current_task = None | |
# Initialize data collections for PDF report | |
if not hasattr(self, "vayner_screenshots"): | |
self.vayner_screenshots = [] | |
if not hasattr(self, "vayner_business_info"): | |
self.vayner_business_info = [] | |
if not hasattr(self, "vayner_keyword_data"): | |
self.vayner_keyword_data = [] | |
if not hasattr(self, "vayner_ranking_data"): | |
self.vayner_ranking_data = [] | |
if not hasattr(self, "vayner_current_business"): | |
self.vayner_current_business = "Unknown Business" | |
# New: keyword table rows for third page | |
if not hasattr(self, "vayner_keyword_table_rows"): | |
self.vayner_keyword_table_rows = [] | |
# Queue for updates during task execution | |
if not hasattr(self, "update_queue"): | |
self.update_queue = [] | |
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) -> Optional["Component"]: | |
""" | |
Get component by id. Returns None if not found. | |
""" | |
return self.id_to_component.get(comp_id, None) | |
def get_id_by_component(self, comp: "Component") -> str: | |
""" | |
Get id by component. Raises KeyError if not found. | |
""" | |
return self.component_to_id[comp] | |
def save_config(self, components: Dict["Component", str]) -> str: | |
""" | |
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] | |
update_components[comp] = gr.update(value=comp_val) | |
config_status = self.id_to_component["load_save_config.config_status"] | |
update_components.update( | |
{ | |
config_status: gr.update(value=f"Successfully loaded config: {config_path}") | |
} | |
) | |
yield update_components | |