diff --git a/browser_use/agent/prompts.py b/browser_use/agent/prompts.py index 974f62d16..829e3d4c2 100644 --- a/browser_use/agent/prompts.py +++ b/browser_use/agent/prompts.py @@ -266,11 +266,19 @@ class AgentMessagePrompt: if self.include_recent_events and self.browser_state.recent_events: recent_events_text = f'Recent browser events: {self.browser_state.recent_events}\n' + # Add closed popup messages if any + closed_popups_text = '' + if self.browser_state.closed_popup_messages: + closed_popups_text = 'Auto-closed JavaScript dialogs:\n' + for popup_msg in self.browser_state.closed_popup_messages: + closed_popups_text += f' - {popup_msg}\n' + closed_popups_text += '\n' + browser_state = f"""{stats_text}{current_tab_text} Available tabs: {tabs_text} {page_info_text} -{recent_events_text}{pdf_message}Interactive elements{truncated_text}: +{recent_events_text}{closed_popups_text}{pdf_message}Interactive elements{truncated_text}: {elements_text} """ return browser_state diff --git a/browser_use/browser/session.py b/browser_use/browser/session.py index 60c975147..bfe2e03df 100644 --- a/browser_use/browser/session.py +++ b/browser_use/browser/session.py @@ -315,6 +315,7 @@ class BrowserSession(BaseModel): _cached_browser_state_summary: Any = PrivateAttr(default=None) _cached_selector_map: dict[int, EnhancedDOMTreeNode] = PrivateAttr(default_factory=dict) _downloaded_files: list[str] = PrivateAttr(default_factory=list) # Track files downloaded during this session + _closed_popup_messages: list[str] = PrivateAttr(default_factory=list) # Store messages from auto-closed JavaScript dialogs # Watchdogs _crash_watchdog: Any | None = PrivateAttr(default=None) diff --git a/browser_use/browser/views.py b/browser_use/browser/views.py index da222b61d..43ff2a74b 100644 --- a/browser_use/browser/views.py +++ b/browser_use/browser/views.py @@ -107,6 +107,7 @@ class BrowserStateSummary: recent_events: str | None = None # Text summary of recent browser events pending_network_requests: list[NetworkRequest] = field(default_factory=list) # Currently loading network requests pagination_buttons: list[PaginationButton] = field(default_factory=list) # Detected pagination buttons + closed_popup_messages: list[str] = field(default_factory=list) # Messages from auto-closed JavaScript dialogs @dataclass diff --git a/browser_use/browser/watchdogs/dom_watchdog.py b/browser_use/browser/watchdogs/dom_watchdog.py index 48e79b7ff..4216c6fe9 100644 --- a/browser_use/browser/watchdogs/dom_watchdog.py +++ b/browser_use/browser/watchdogs/dom_watchdog.py @@ -349,6 +349,7 @@ class DOMWatchdog(BaseWatchdog): recent_events=self._get_recent_events_str() if event.include_recent_events else None, pending_network_requests=[], # Empty page has no pending requests pagination_buttons=[], # Empty page has no pagination + closed_popup_messages=self.browser_session._closed_popup_messages.copy(), ) # Execute DOM building and screenshot capture in parallel @@ -504,6 +505,7 @@ class DOMWatchdog(BaseWatchdog): recent_events=self._get_recent_events_str() if event.include_recent_events else None, pending_network_requests=pending_requests, pagination_buttons=pagination_buttons_data, + closed_popup_messages=self.browser_session._closed_popup_messages.copy(), ) # Cache the state @@ -541,6 +543,7 @@ class DOMWatchdog(BaseWatchdog): recent_events=None, pending_network_requests=[], # Error state has no pending requests pagination_buttons=[], # Error state has no pagination + closed_popup_messages=self.browser_session._closed_popup_messages.copy() if hasattr(self, 'browser_session') else [], ) @time_execution_async('build_dom_tree_without_highlights') diff --git a/browser_use/browser/watchdogs/popups_watchdog.py b/browser_use/browser/watchdogs/popups_watchdog.py index 20904dfac..7974c0b09 100644 --- a/browser_use/browser/watchdogs/popups_watchdog.py +++ b/browser_use/browser/watchdogs/popups_watchdog.py @@ -65,6 +65,12 @@ class PopupsWatchdog(BaseWatchdog): dialog_type = event_data.get('type', 'alert') message = event_data.get('message', '') + # Store the popup message in browser session for inclusion in browser state + if message: + formatted_message = f"[{dialog_type}] {message}" + self.browser_session._closed_popup_messages.append(formatted_message) + self.logger.debug(f"📝 Stored popup message: {formatted_message[:100]}") + # Choose action based on dialog type: # - alert: accept=true (click OK to dismiss) # - confirm: accept=true (click OK to proceed - safer for automation)