From f21a4475339f7fa5f011118100e080fc6c134aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=BCller?= <67061560+MagMueller@users.noreply.github.com> Date: Thu, 18 Sep 2025 18:44:15 -0700 Subject: [PATCH 1/4] fix framework_events_script --- README.md | 2 +- browser_use/browser/watchdogs/default_action_watchdog.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1a3bea2f4..ea313edab 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,8 @@ Check out the [library docs](https://docs.browser-use.com) and [cloud docs](http https://github.com/user-attachments/assets/171fb4d6-0355-46f2-863e-edb04a828d04

-See more [examples in the docs](https://docs.browser-use.com/examples). +See [more examples](https://docs.browser-use.com/examples) in the docs and give us a star!

diff --git a/browser_use/browser/watchdogs/default_action_watchdog.py b/browser_use/browser/watchdogs/default_action_watchdog.py index 263420c5e..b420e6054 100644 --- a/browser_use/browser/watchdogs/default_action_watchdog.py +++ b/browser_use/browser/watchdogs/default_action_watchdog.py @@ -1179,8 +1179,8 @@ class DefaultActionWatchdog(BaseWatchdog): # Execute JavaScript to trigger comprehensive event sequence framework_events_script = """ (function() { - // Find the target element - const element = arguments[0]; + // Find the target element (available as 'this' when using objectId) + const element = this; if (!element) return false; // Ensure element is focused @@ -1255,7 +1255,7 @@ class DefaultActionWatchdog(BaseWatchdog): } return success; - })(arguments[0]); + })(); """ # Execute the framework events script @@ -1263,7 +1263,6 @@ class DefaultActionWatchdog(BaseWatchdog): params={ 'objectId': object_id, 'functionDeclaration': framework_events_script, - 'arguments': [{'objectId': object_id}], 'returnByValue': True, }, session_id=cdp_session.session_id, From 206b01273d135d385d9b1bd3d446a19cafaac33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=BCller?= <67061560+MagMueller@users.noreply.github.com> Date: Thu, 18 Sep 2025 18:51:09 -0700 Subject: [PATCH 2/4] update docs2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ea313edab..ac21ef1da 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ https://github.com/user-attachments/assets/171fb4d6-0355-46f2-863e-edb04a828d04

-See [more examples](https://docs.browser-use.com/examples) in the docs and give us a star! +See [more examples](https://docs.browser-use.com/examples) and give us a star!

From a64c42bb41df038cf565b81e76a1f1bec493c0e5 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 19 Sep 2025 01:57:51 +0000 Subject: [PATCH 3/4] Add check for latest browser-use version Co-authored-by: mamagnus00 --- browser_use/agent/service.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/browser_use/agent/service.py b/browser_use/agent/service.py index 18a6570bb..3325b6dd2 100644 --- a/browser_use/agent/service.py +++ b/browser_use/agent/service.py @@ -12,6 +12,7 @@ from pathlib import Path from typing import Any, Generic, Literal, TypeVar from urllib.parse import urlparse +import requests from dotenv import load_dotenv from browser_use.agent.cloud_events import ( @@ -77,6 +78,23 @@ from browser_use.utils import ( logger = logging.getLogger(__name__) +def _check_latest_browser_use_version() -> str | None: + """Check the latest version of browser-use from PyPI. + + Returns: + The latest version string if successful, None if failed + """ + try: + response = requests.get('https://pypi.org/pypi/browser-use/json', timeout=3) + if response.status_code == 200: + data = response.json() + return data['info']['version'] + except Exception: + # Silently fail - we don't want to break agent startup due to network issues + pass + return None + + def log_response(response: AgentOutput, registry=None, logger=None) -> None: """Utility function to log the model's response.""" @@ -1182,6 +1200,13 @@ class Agent(Generic[Context, AgentStructuredOutput]): self.logger.debug(f'🤖 Browser-Use Library Version {self.version} ({self.source})') + # Check for latest version and log upgrade message if needed + latest_version = _check_latest_browser_use_version() + if latest_version and latest_version != self.version: + self.logger.info( + f'📦 Newer version available: {latest_version} (current: {self.version}). Upgrade with: uv add browser-use@{latest_version}' + ) + def _log_first_step_startup(self) -> None: """Log startup message only on the first step""" if len(self.history.history) == 0: From c4ed783a2b44951d5f04d45d75a01dab7498fc7a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 19 Sep 2025 04:12:48 +0000 Subject: [PATCH 4/4] Refactor: Make version check async and use httpx Co-authored-by: mamagnus00 --- browser_use/agent/service.py | 25 ++++--------------------- browser_use/utils.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/browser_use/agent/service.py b/browser_use/agent/service.py index 3325b6dd2..17d57449f 100644 --- a/browser_use/agent/service.py +++ b/browser_use/agent/service.py @@ -12,7 +12,6 @@ from pathlib import Path from typing import Any, Generic, Literal, TypeVar from urllib.parse import urlparse -import requests from dotenv import load_dotenv from browser_use.agent.cloud_events import ( @@ -69,6 +68,7 @@ from browser_use.tools.service import Tools from browser_use.utils import ( URL_PATTERN, _log_pretty_path, + check_latest_browser_use_version, get_browser_use_version, get_git_info, time_execution_async, @@ -78,23 +78,6 @@ from browser_use.utils import ( logger = logging.getLogger(__name__) -def _check_latest_browser_use_version() -> str | None: - """Check the latest version of browser-use from PyPI. - - Returns: - The latest version string if successful, None if failed - """ - try: - response = requests.get('https://pypi.org/pypi/browser-use/json', timeout=3) - if response.status_code == 200: - data = response.json() - return data['info']['version'] - except Exception: - # Silently fail - we don't want to break agent startup due to network issues - pass - return None - - def log_response(response: AgentOutput, registry=None, logger=None) -> None: """Utility function to log the model's response.""" @@ -1193,7 +1176,7 @@ class Agent(Generic[Context, AgentStructuredOutput]): # Just re-raise - Pydantic's validation errors are already descriptive raise - def _log_agent_run(self) -> None: + async def _log_agent_run(self) -> None: """Log the agent run""" # Blue color for task self.logger.info(f'\033[34m🚀 Task: {self.task}\033[0m') @@ -1201,7 +1184,7 @@ class Agent(Generic[Context, AgentStructuredOutput]): self.logger.debug(f'🤖 Browser-Use Library Version {self.version} ({self.source})') # Check for latest version and log upgrade message if needed - latest_version = _check_latest_browser_use_version() + latest_version = await check_latest_browser_use_version() if latest_version and latest_version != self.version: self.logger.info( f'📦 Newer version available: {latest_version} (current: {self.version}). Upgrade with: uv add browser-use@{latest_version}' @@ -1431,7 +1414,7 @@ class Agent(Generic[Context, AgentStructuredOutput]): signal_handler.register() try: - self._log_agent_run() + await self._log_agent_run() self.logger.debug( f'🔧 Agent setup: Agent Session ID {self.session_id[-4:]}, Task ID {self.task_id[-4:]}, Browser Session ID {self.browser_session.id[-4:] if self.browser_session else "None"} {"(connecting via CDP)" if (self.browser_session and self.browser_session.cdp_url) else "(launching local browser)"}' diff --git a/browser_use/utils.py b/browser_use/utils.py index 35f9a9db0..efd4d2a18 100644 --- a/browser_use/utils.py +++ b/browser_use/utils.py @@ -13,6 +13,7 @@ from sys import stderr from typing import Any, ParamSpec, TypeVar from urllib.parse import urlparse +import httpx from dotenv import load_dotenv load_dotenv() @@ -578,6 +579,24 @@ def get_browser_use_version() -> str: return 'unknown' +async def check_latest_browser_use_version() -> str | None: + """Check the latest version of browser-use from PyPI asynchronously. + + Returns: + The latest version string if successful, None if failed + """ + try: + async with httpx.AsyncClient(timeout=3.0) as client: + response = await client.get('https://pypi.org/pypi/browser-use/json') + if response.status_code == 200: + data = response.json() + return data['info']['version'] + except Exception: + # Silently fail - we don't want to break agent startup due to network issues + pass + return None + + @cache def get_git_info() -> dict[str, str] | None: """Get git information if installed from git repository"""