diff --git a/README.md b/README.md index 73cc1ef..81d5841 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ You can also specify an initial URL for the Playwright environment: python main.py --query="Go to Google and type 'Hello World' into the search bar" --env="playwright" --initial_url="https://www.google.com/search?q=latest+AI+news" ``` +To reuse an existing Playwright-compatible browser instead of launching one locally, set `CDP_URL` to the remote browser's CDP endpoint (for example, the URL returned by `playwright run-server`). When this variable is set the agent connects over CDP, reusing the first available context and page on that browser session. + **Browserbase** Runs the agent using Browserbase as the browser backend. Ensure the proper Browserbase environment variables are set:`BROWSERBASE_API_KEY` and `BROWSERBASE_PROJECT_ID`. @@ -137,3 +139,4 @@ The `main.py` script is the command-line interface (CLI) for running the browser | GEMINI_API_KEY | Your API key for the Gemini model. | Yes | | BROWSERBASE_API_KEY | Your API key for Browserbase. | Yes (when using the browserbase environment) | | BROWSERBASE_PROJECT_ID | Your Project ID for Browserbase. | Yes (when using the browserbase environment) | +| CDP_URL | Connects the Playwright environment to a remote Chromium instance over CDP instead of launching locally. | No | diff --git a/computers/playwright/playwright.py b/computers/playwright/playwright.py index e7a53c3..3d807ee 100644 --- a/computers/playwright/playwright.py +++ b/computers/playwright/playwright.py @@ -83,6 +83,9 @@ def __init__( highlight_mouse: bool = False, ): self._initial_url = initial_url + self._browser = None + self._context = None + self._page = None self._screen_size = screen_size self._search_engine_url = search_engine_url self._highlight_mouse = highlight_mouse @@ -100,32 +103,46 @@ def _handle_new_page(self, new_page: playwright.sync_api.Page): def __enter__(self): print("Creating session...") self._playwright = sync_playwright().start() - self._browser = self._playwright.chromium.launch( - args=[ - "--disable-extensions", - "--disable-file-system", - "--disable-plugins", - "--disable-dev-shm-usage", - "--disable-background-networking", - "--disable-default-apps", - "--disable-sync", - # No '--no-sandbox' arg means the sandbox is on. - ], - headless=bool(os.environ.get("PLAYWRIGHT_HEADLESS", False)), - ) - self._context = self._browser.new_context( - viewport={ - "width": self._screen_size[0], - "height": self._screen_size[1], - } - ) - self._page = self._context.new_page() + cdp_url = os.environ.get("CDP_URL") + if cdp_url: + self._browser = self._playwright.chromium.connect_over_cdp(cdp_url) + self._context = self._browser.contexts[0] + self._page = self._context.pages[0] + # Set `viewport_size` based on the existing page width and height, so all interactions are using the right dimensions. + self._page.set_viewport_size({ + "width": self._page.evaluate("window.innerWidth"), + "height": self._page.evaluate("window.innerHeight"), + }) + status_message = "Connected to remote Playwright over CDP." + else: + self._browser = self._playwright.chromium.launch( + args=[ + "--disable-extensions", + "--disable-file-system", + "--disable-plugins", + "--disable-dev-shm-usage", + "--disable-background-networking", + "--disable-default-apps", + "--disable-sync", + # No '--no-sandbox' arg means the sandbox is on. + ], + headless=bool(os.environ.get("PLAYWRIGHT_HEADLESS", False)), + ) + self._context = self._browser.new_context( + viewport={ + "width": self._screen_size[0], + "height": self._screen_size[1], + } + ) + self._page = self._context.new_page() + status_message = "Started local Playwright." + self._page.goto(self._initial_url) self._context.on("page", self._handle_new_page) termcolor.cprint( - f"Started local playwright.", + status_message, color="green", attrs=["bold"], )