From 33cea7ded5b7a95e86a3a6c506fc87e3ecaf256e Mon Sep 17 00:00:00 2001 From: shubh24 Date: Mon, 18 Aug 2025 19:28:38 -0700 Subject: [PATCH 1/6] passing setDownloadBehavior in env=LOCAL setup --- stagehand/main.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/stagehand/main.py b/stagehand/main.py index 4a201ad..3c7d125 100644 --- a/stagehand/main.py +++ b/stagehand/main.py @@ -531,6 +531,30 @@ async def init(self): self.logger, ) self._playwright_page = self._page._page + + # Set up download behavior via CDP + try: + # Check if downloadsPath is provided in launch options, otherwise use default + downloads_path = self.local_browser_launch_options.get("downloadsPath") + if not downloads_path: + downloads_path = str(Path.cwd() / "downloads") + # Create downloads directory if it doesn't exist + Path(downloads_path).mkdir(parents=True, exist_ok=True) + + # Create CDP session for the page + cdp_session = await self._context.new_cdp_session(self._playwright_page) + # Enable download behavior + await cdp_session.send("Browser.setDownloadBehavior", { + "behavior": "allow", + "downloadPath": downloads_path, + "eventsEnabled": True + }) + + self.logger.debug(f"Set up CDP download behavior for local browser with path: {downloads_path}") + except Exception as e: + self.logger.warning(f"Failed to set up CDP download behavior for local browser: {str(e)}") + # Continue without download support - non-critical feature + except Exception: await self.close() raise From 29f0e2369d87cb4b4435607c18763d6bdf301d0b Mon Sep 17 00:00:00 2001 From: shubh24 Date: Tue, 19 Aug 2025 11:09:39 -0700 Subject: [PATCH 2/6] updated download logic to work with use_api=false --- stagehand/main.py | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/stagehand/main.py b/stagehand/main.py index 3c7d125..a95e204 100644 --- a/stagehand/main.py +++ b/stagehand/main.py @@ -511,6 +511,23 @@ async def init(self): self.logger, ) self._playwright_page = self._page._page + + # Set up download behavior via CDP + try: + # Create CDP session for the page + cdp_session = await self._context.new_cdp_session(self._playwright_page) + # Enable download behavior + await cdp_session.send("Browser.setDownloadBehavior", { + "behavior": "allow", + "downloadPath": "downloads", + "eventsEnabled": True + }) + + self.logger.debug(f"Set up CDP download behavior") + except Exception as e: + self.logger.warning(f"Failed to set up CDP download behavior: {str(e)}") + # Continue without download support - non-critical feature + except Exception: await self.close() raise @@ -532,29 +549,6 @@ async def init(self): ) self._playwright_page = self._page._page - # Set up download behavior via CDP - try: - # Check if downloadsPath is provided in launch options, otherwise use default - downloads_path = self.local_browser_launch_options.get("downloadsPath") - if not downloads_path: - downloads_path = str(Path.cwd() / "downloads") - # Create downloads directory if it doesn't exist - Path(downloads_path).mkdir(parents=True, exist_ok=True) - - # Create CDP session for the page - cdp_session = await self._context.new_cdp_session(self._playwright_page) - # Enable download behavior - await cdp_session.send("Browser.setDownloadBehavior", { - "behavior": "allow", - "downloadPath": downloads_path, - "eventsEnabled": True - }) - - self.logger.debug(f"Set up CDP download behavior for local browser with path: {downloads_path}") - except Exception as e: - self.logger.warning(f"Failed to set up CDP download behavior for local browser: {str(e)}") - # Continue without download support - non-critical feature - except Exception: await self.close() raise From ff8f1e257e4d4727775e3fb1e5be61fce92e0a2c Mon Sep 17 00:00:00 2001 From: shubh24 Date: Tue, 19 Aug 2025 11:10:16 -0700 Subject: [PATCH 3/6] black formatting --- stagehand/main.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/stagehand/main.py b/stagehand/main.py index a95e204..34512e3 100644 --- a/stagehand/main.py +++ b/stagehand/main.py @@ -515,17 +515,24 @@ async def init(self): # Set up download behavior via CDP try: # Create CDP session for the page - cdp_session = await self._context.new_cdp_session(self._playwright_page) + cdp_session = await self._context.new_cdp_session( + self._playwright_page + ) # Enable download behavior - await cdp_session.send("Browser.setDownloadBehavior", { - "behavior": "allow", - "downloadPath": "downloads", - "eventsEnabled": True - }) + await cdp_session.send( + "Browser.setDownloadBehavior", + { + "behavior": "allow", + "downloadPath": "downloads", + "eventsEnabled": True, + }, + ) self.logger.debug(f"Set up CDP download behavior") except Exception as e: - self.logger.warning(f"Failed to set up CDP download behavior: {str(e)}") + self.logger.warning( + f"Failed to set up CDP download behavior: {str(e)}" + ) # Continue without download support - non-critical feature except Exception: From 60b51d5cf0a31b2151db1cd173ef3a09e194e73d Mon Sep 17 00:00:00 2001 From: shubh24 Date: Tue, 19 Aug 2025 11:17:27 -0700 Subject: [PATCH 4/6] fixed downloads for use_api=false --- .changeset/spectral-labrador-of-tolerance.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/spectral-labrador-of-tolerance.md diff --git a/.changeset/spectral-labrador-of-tolerance.md b/.changeset/spectral-labrador-of-tolerance.md new file mode 100644 index 0000000..68cb094 --- /dev/null +++ b/.changeset/spectral-labrador-of-tolerance.md @@ -0,0 +1,5 @@ +--- +"stagehand": patch +--- + +Fixing downloads behavior for use_api=false From 4251741fe7758a37e63237a53cac311227c408c9 Mon Sep 17 00:00:00 2001 From: shubh24 Date: Tue, 19 Aug 2025 11:18:55 -0700 Subject: [PATCH 5/6] fixed the ruff error --- stagehand/main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/stagehand/main.py b/stagehand/main.py index 34512e3..eb77417 100644 --- a/stagehand/main.py +++ b/stagehand/main.py @@ -527,13 +527,11 @@ async def init(self): "eventsEnabled": True, }, ) - - self.logger.debug(f"Set up CDP download behavior") + self.logger.debug("Set up CDP download behavior") except Exception as e: self.logger.warning( f"Failed to set up CDP download behavior: {str(e)}" ) - # Continue without download support - non-critical feature except Exception: await self.close() From c20cb16d2ccfbf39e491cba2fab07e1742fa61c5 Mon Sep 17 00:00:00 2001 From: miguel Date: Tue, 19 Aug 2025 12:19:46 -0700 Subject: [PATCH 6/6] refactor and patch litellm newer version dependency --- pyproject.toml | 2 +- stagehand/main.py | 40 ++++++++++++++++++---------------------- stagehand/utils.py | 13 +++++++++++++ 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fbc5ab1..24eb8e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ dependencies = [ "rich>=13.7.0", "openai>=1.83.0,<1.99.6", "anthropic>=0.51.0", - "litellm>=1.72.0", + "litellm>=1.72.0,<1.75.0", "nest-asyncio>=1.6.0", ] [[project.authors]] diff --git a/stagehand/main.py b/stagehand/main.py index eb77417..063efb0 100644 --- a/stagehand/main.py +++ b/stagehand/main.py @@ -29,7 +29,7 @@ from .logging import StagehandLogger, default_log_handler from .metrics import StagehandFunctionName, StagehandMetrics from .page import StagehandPage -from .utils import make_serializable +from .utils import get_download_path, make_serializable load_dotenv() @@ -512,27 +512,6 @@ async def init(self): ) self._playwright_page = self._page._page - # Set up download behavior via CDP - try: - # Create CDP session for the page - cdp_session = await self._context.new_cdp_session( - self._playwright_page - ) - # Enable download behavior - await cdp_session.send( - "Browser.setDownloadBehavior", - { - "behavior": "allow", - "downloadPath": "downloads", - "eventsEnabled": True, - }, - ) - self.logger.debug("Set up CDP download behavior") - except Exception as e: - self.logger.warning( - f"Failed to set up CDP download behavior: {str(e)}" - ) - except Exception: await self.close() raise @@ -561,6 +540,23 @@ async def init(self): # Should not happen due to __init__ validation raise RuntimeError(f"Invalid env value: {self.env}") + # Set up download behavior via CDP + try: + # Create CDP session for the page + cdp_session = await self._context.new_cdp_session(self._playwright_page) + # Enable download behavior + await cdp_session.send( + "Browser.setDownloadBehavior", + { + "behavior": "allow", + "downloadPath": get_download_path(self), + "eventsEnabled": True, + }, + ) + self.logger.debug("Set up CDP download behavior") + except Exception as e: + self.logger.warning(f"Failed to set up CDP download behavior: {str(e)}") + self._initialized = True def agent(self, **kwargs) -> Agent: diff --git a/stagehand/utils.py b/stagehand/utils.py index 7a69a63..37f4978 100644 --- a/stagehand/utils.py +++ b/stagehand/utils.py @@ -1,4 +1,5 @@ import inspect +import os from typing import Any, Union, get_args, get_origin from pydantic import AnyUrl, BaseModel, Field, HttpUrl, create_model @@ -530,3 +531,15 @@ def make_serializable(obj): elif isinstance(obj, dict): return {key: make_serializable(value) for key, value in obj.items()} return obj + + +def get_download_path(stagehand): + if stagehand.env == "BROWSERBASE": + return "downloads" + else: + if stagehand.local_browser_launch_options.get("downloadPath"): + return stagehand.local_browser_launch_options["downloadPath"] + else: + path = os.path.join(os.getcwd(), "downloads") + os.makedirs(path, exist_ok=True) + return path