Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
browser-use==0.1.48
browser-use==0.2.7
pyperclip==1.9.0
gradio==5.27.0
json-repair
Expand Down
21 changes: 1 addition & 20 deletions src/agent/browser_use/browser_use_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,30 +140,11 @@ async def run(
finally:
# Unregister signal handlers before cleanup
signal_handler.unregister()

if self.settings.save_playwright_script_path:
logger.info(
f'Agent run finished. Attempting to save Playwright script to: {self.settings.save_playwright_script_path}'
)
try:
# Extract sensitive data keys if sensitive_data is provided
keys = list(self.sensitive_data.keys()) if self.sensitive_data else None
# Pass browser and context config to the saving method
self.state.history.save_as_playwright_script(
self.settings.save_playwright_script_path,
sensitive_data_keys=keys,
browser_config=self.browser.config,
context_config=self.browser_context.config,
)
except Exception as script_gen_err:
# Log any error during script generation/saving
logger.error(f'Failed to save Playwright script: {script_gen_err}', exc_info=True)

await self.close()

if self.settings.generate_gif:
output_path: str = 'agent_history.gif'
if isinstance(self.settings.generate_gif, str):
output_path = self.settings.generate_gif

create_history_gif(task=self.task, history=self.state.history, output_path=output_path)
create_history_gif(task=self.task, history=self.state.history, output_path=output_path)
68 changes: 23 additions & 45 deletions src/agent/deep_research/deep_research_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from pathlib import Path
from typing import Any, Dict, List, Optional, TypedDict

from browser_use.browser.browser import BrowserConfig
from browser_use.browser import BrowserProfile, BrowserSession
from browser_use.browser.profile import ViewportSize
from langchain_community.tools.file_management import (
ListDirectoryTool,
ReadFileTool,
Expand All @@ -29,10 +30,7 @@
from langgraph.graph import StateGraph
from pydantic import BaseModel, Field

from browser_use.browser.context import BrowserContextConfig

from src.agent.browser_use.browser_use_agent import BrowserUseAgent
from src.browser.custom_browser import CustomBrowser
from src.controller.custom_controller import CustomController
from src.utils.mcp_client import setup_mcp_client_and_tools

Expand Down Expand Up @@ -77,42 +75,30 @@ async def run_single_browser_task(
cdp_url = browser_config.get("cdp_url", None)
disable_security = browser_config.get("disable_security", False)

bu_browser = None
bu_browser_context = None
bu_browser_session = None
try:
browser_user_data = None
logger.info(f"Starting browser task for query: {task_query}")
extra_args = []
if use_own_browser:
browser_binary_path = os.getenv("BROWSER_PATH", None) or browser_binary_path
if browser_binary_path == "":
browser_binary_path = None
browser_user_data = browser_user_data_dir or os.getenv("BROWSER_USER_DATA", None)
if browser_user_data:
extra_args += [f"--user-data-dir={browser_user_data}"]
else:
browser_binary_path = None

bu_browser = CustomBrowser(
config=BrowserConfig(
headless=headless,
browser_binary_path=browser_binary_path,
extra_browser_args=extra_args,
wss_url=wss_url,
cdp_url=cdp_url,
new_context_config=BrowserContextConfig(
window_width=window_w,
window_height=window_h,
)
)
browser_profile = BrowserProfile(
headless=headless,
executable_path=browser_binary_path,
user_data_dir=browser_user_data,
window_size=ViewportSize(width=window_w, height=window_h),
traces_dir=None,
record_video_dir=None,
downloads_path="./tmp/downloads"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The disable_security setting retrieved earlier from browser_config is ignored, so the BrowserProfile is always created with its default security settings. This prevents callers from actually disabling browser security headers as intended.

Suggested change
downloads_path="./tmp/downloads"
downloads_path="./tmp/downloads", disable_security=disable_security

)

context_config = BrowserContextConfig(
save_downloads_path="./tmp/downloads",
window_height=window_h,
window_width=window_w,
force_new_context=True,
)
bu_browser_context = await bu_browser.new_context(config=context_config)
bu_browser_session = BrowserSession(
browser_profile=browser_profile,
wss_url=wss_url,
cdp_url=cdp_url)

# Simple controller example, replace with your actual implementation if needed
bu_controller = CustomController()
Expand All @@ -133,8 +119,7 @@ async def run_single_browser_task(
bu_agent_instance = BrowserUseAgent(
task=bu_task_prompt,
llm=llm, # Use the passed LLM
browser=bu_browser,
browser_context=bu_browser_context,
browser_session=bu_browser_session,
controller=bu_controller,
use_vision=use_vision,
source="webui",
Expand Down Expand Up @@ -174,20 +159,13 @@ async def run_single_browser_task(
)
return {"query": task_query, "error": str(e), "status": "failed"}
finally:
if bu_browser_context:
try:
await bu_browser_context.close()
bu_browser_context = None
logger.info("Closed browser context.")
except Exception as e:
logger.error(f"Error closing browser context: {e}")
if bu_browser:
if bu_browser_session:
try:
await bu_browser.close()
bu_browser = None
logger.info("Closed browser.")
await bu_browser_session.kill()
bu_browser_session = None
logger.info("Closed browser session.")
except Exception as e:
logger.error(f"Error closing browser: {e}")
logger.error(f"Error closing browser session: {e}")

if task_key in _BROWSER_AGENT_INSTANCES:
del _BROWSER_AGENT_INSTANCES[task_key]
Expand Down Expand Up @@ -1258,4 +1236,4 @@ async def stop(self):
await self._stop_lingering_browsers(self.current_task_id)

def close(self):
self.stopped = False
self.stopped = False
Empty file removed src/browser/__init__.py
Empty file.
109 changes: 0 additions & 109 deletions src/browser/custom_browser.py

This file was deleted.

22 changes: 0 additions & 22 deletions src/browser/custom_context.py

This file was deleted.

18 changes: 10 additions & 8 deletions src/controller/custom_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import pyperclip
from typing import Optional, Type, Callable, Dict, Any, Union, Awaitable, TypeVar

from browser_use import BrowserSession
from pydantic import BaseModel
from browser_use.agent.views import ActionResult
from browser_use.browser.context import BrowserContext
from browser_use import BrowserSession
from browser_use.controller.service import Controller, DoneAction
from browser_use.controller.registry.service import Registry, RegisteredAction
from main_content_extractor import MainContentExtractor
Expand Down Expand Up @@ -39,8 +41,8 @@
class CustomController(Controller):
def __init__(self, exclude_actions: list[str] = [],
output_model: Optional[Type[BaseModel]] = None,
ask_assistant_callback: Optional[Union[Callable[[str, BrowserContext], Dict[str, Any]], Callable[
[str, BrowserContext], Awaitable[Dict[str, Any]]]]] = None,
ask_assistant_callback: Optional[Union[Callable[[str, BrowserSession], Dict[str, Any]], Callable[
[str, BrowserSession], Awaitable[Dict[str, Any]]]]] = None,
):
super().__init__(exclude_actions=exclude_actions, output_model=output_model)
self._register_custom_actions()
Expand All @@ -57,7 +59,7 @@ def _register_custom_actions(self):
"requiring subjective human judgment, needing a physical action performed, encountering complex CAPTCHAs, "
"or facing limitations in your capabilities – you must request human assistance."
)
async def ask_for_assistant(query: str, browser: BrowserContext):
async def ask_for_assistant(query: str, browser: BrowserSession):
if self.ask_assistant_callback:
if inspect.iscoroutinefunction(self.ask_assistant_callback):
user_response = await self.ask_assistant_callback(query, browser)
Expand All @@ -73,7 +75,7 @@ async def ask_for_assistant(query: str, browser: BrowserContext):
@self.registry.action(
'Upload file to interactive element with file path ',
)
async def upload_file(index: int, path: str, browser: BrowserContext, available_file_paths: list[str]):
async def upload_file(index: int, path: str, browser: BrowserSession, available_file_paths: list[str]):
if path not in available_file_paths:
return ActionResult(error=f'File path {path} is not available')

Expand Down Expand Up @@ -110,7 +112,7 @@ async def upload_file(index: int, path: str, browser: BrowserContext, available_
async def act(
self,
action: ActionModel,
browser_context: Optional[BrowserContext] = None,
browser_session: Optional[BrowserSession] = None,
#
page_extraction_llm: Optional[BaseChatModel] = None,
sensitive_data: Optional[Dict[str, str]] = None,
Expand All @@ -132,7 +134,7 @@ async def act(
result = await self.registry.execute_action(
action_name,
params,
browser=browser_context,
browser_session=browser_session,
page_extraction_llm=page_extraction_llm,
sensitive_data=sensitive_data,
available_file_paths=available_file_paths,
Expand Down Expand Up @@ -179,4 +181,4 @@ def register_mcp_tools(self):

async def close_mcp_client(self):
if self.mcp_client:
await self.mcp_client.__aexit__(None, None, None)
await self.mcp_client.__aexit__(None, None, None)
15 changes: 5 additions & 10 deletions src/webui/components/browser_settings_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,10 @@ async def close_browser(webui_manager: WebuiManager):
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
if webui_manager.bu_browser_session:
logger.info("⚠️ Closing browser session when changing browser config.")
await webui_manager.bu_browser_session.kill()
webui_manager.bu_browser_session = None

def create_browser_settings_tab(webui_manager: WebuiManager):
"""
Expand Down Expand Up @@ -158,4 +153,4 @@ async def close_wrapper():
headless.change(close_wrapper)
keep_browser_open.change(close_wrapper)
disable_security.change(close_wrapper)
use_own_browser.change(close_wrapper)
use_own_browser.change(close_wrapper)
Loading