stagehand 4.2.0a0.dev1587__tar.gz → 4.2.0a0.dev1588__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/PKG-INFO +1 -1
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/pyproject.toml +1 -1
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/service-worker.js +4 -4
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_generated/protocol_version.py +1 -1
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/browser.py +16 -5
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/cdp_client.py +52 -12
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/client_models.py +4 -2
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/client_types.py +2 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/README.md +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/__init__.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/blank.html +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/content-script.js +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/manifest.json +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/offscreen/service-worker-heartbeat.html +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/offscreen/service-worker-heartbeat.js +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/wake-service-worker.html +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/wake-service-worker.js +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_generated/__init__.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_generated/input_types.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_generated/models.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_sdk_identity.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_validation.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/browser_clipboard.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/browser_context.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/browserbase_services.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/browserbase_session.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/extension_assets.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/file_upload.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/locator.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/page.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/py.typed +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/response.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/rpc_client.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/stagehand.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/timeouts.py +0 -0
- {stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/webmcp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stagehand
|
|
3
|
-
Version: 4.2.0a0.
|
|
3
|
+
Version: 4.2.0a0.dev1588
|
|
4
4
|
Summary: Browserbase's SDK for building browser agents
|
|
5
5
|
Keywords: ai,agent,ai-agent,browser,browser-agent,browser-automation,computer-use,headless,playwright,cdp,llm,automation,web-scraping,testing
|
|
6
6
|
Author: Browserbase
|
{stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/service-worker.js
RENAMED
|
@@ -7363,7 +7363,7 @@ function isRecord$1(value) {
|
|
|
7363
7363
|
}
|
|
7364
7364
|
var package_default$1 = {
|
|
7365
7365
|
name: "@browserbasehq/stagehand-protocol",
|
|
7366
|
-
version: "2.1.0-alpha-
|
|
7366
|
+
version: "2.1.0-alpha-f2060a689d150957768d92e41eda8decc68bc5bf",
|
|
7367
7367
|
"private": true,
|
|
7368
7368
|
type: "module",
|
|
7369
7369
|
exports: {
|
|
@@ -12557,7 +12557,7 @@ strictObject({
|
|
|
12557
12557
|
}).meta({ id: "LocalBrowserLaunchOptions" });
|
|
12558
12558
|
strictObject({
|
|
12559
12559
|
cdpUrl: string().min(1),
|
|
12560
|
-
extensionId: string().
|
|
12560
|
+
extensionId: string().optional()
|
|
12561
12561
|
}).meta({ id: "LocalBrowserConnectOptions" });
|
|
12562
12562
|
var DEFAULT_BROWSERBASE_URL = "https://api.browserbase.com";
|
|
12563
12563
|
var BrowserbaseClientOptionsSchema = strictObject({
|
|
@@ -12579,7 +12579,7 @@ strictObject({
|
|
|
12579
12579
|
baseUrl: url().default(DEFAULT_BROWSERBASE_URL),
|
|
12580
12580
|
clientOptions: BrowserbaseClientOptionsSchema.optional(),
|
|
12581
12581
|
sessionId: string().min(1),
|
|
12582
|
-
extensionId: string().
|
|
12582
|
+
extensionId: string().optional()
|
|
12583
12583
|
}).meta({ id: "BrowserbaseConnectOptions" });
|
|
12584
12584
|
var BrowserbaseCredentialsShape = {
|
|
12585
12585
|
apiKey: string().min(1),
|
|
@@ -54394,7 +54394,7 @@ var WebTracerProvider = class extends BasicTracerProvider {
|
|
|
54394
54394
|
};
|
|
54395
54395
|
var package_default = {
|
|
54396
54396
|
name: "@browserbasehq/stagehand-extension",
|
|
54397
|
-
version: "1.1.0-alpha-
|
|
54397
|
+
version: "1.1.0-alpha-f2060a689d150957768d92e41eda8decc68bc5bf",
|
|
54398
54398
|
"private": true,
|
|
54399
54399
|
type: "module",
|
|
54400
54400
|
scripts: {
|
{stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_generated/protocol_version.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"""Generated from packages/protocol/package.json. Do not edit."""
|
|
2
2
|
|
|
3
3
|
PROTOCOL_SEMVER_PATTERN = '^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$'
|
|
4
|
-
STAGEHAND_PROTOCOL_VERSION = '2.1.0-alpha-
|
|
4
|
+
STAGEHAND_PROTOCOL_VERSION = '2.1.0-alpha-f2060a689d150957768d92e41eda8decc68bc5bf'
|
|
@@ -305,6 +305,7 @@ async def _connect_browser(
|
|
|
305
305
|
origin: Literal["launched", "connected"],
|
|
306
306
|
source: _BrowserConnectionSource,
|
|
307
307
|
extension_dir: str | None = None,
|
|
308
|
+
local_extension_dir: Callable[[], str] | None = None,
|
|
308
309
|
extension_id: str | None = None,
|
|
309
310
|
preloaded_extension: bool = False,
|
|
310
311
|
after_connect: Callable[[CDPClient], Awaitable[None]] | None = None,
|
|
@@ -316,6 +317,7 @@ async def _connect_browser(
|
|
|
316
317
|
cdp_client = await CDPClient.connect(
|
|
317
318
|
cdp_url=source.cdp_url,
|
|
318
319
|
extension_dir=extension_dir,
|
|
320
|
+
local_extension_dir=local_extension_dir,
|
|
319
321
|
extension_id=extension_id,
|
|
320
322
|
preloaded_extension=preloaded_extension,
|
|
321
323
|
service_worker_url_includes="service-worker.js",
|
|
@@ -532,6 +534,12 @@ class LocalBrowser:
|
|
|
532
534
|
cdp_url: str,
|
|
533
535
|
extension_id: str | None = None,
|
|
534
536
|
) -> StagehandBrowser:
|
|
537
|
+
"""Connect to an existing browser.
|
|
538
|
+
|
|
539
|
+
Args:
|
|
540
|
+
extension_id: Deprecated and ignored. Omit this argument; Stagehand
|
|
541
|
+
discovers the installed extension automatically.
|
|
542
|
+
"""
|
|
535
543
|
options = LocalBrowserConnectOptions.model_validate({
|
|
536
544
|
name: value
|
|
537
545
|
for name, value in (
|
|
@@ -540,13 +548,11 @@ class LocalBrowser:
|
|
|
540
548
|
)
|
|
541
549
|
if value is not None
|
|
542
550
|
})
|
|
543
|
-
extension_dir = None if options.extension_id is not None else str(extension_directory())
|
|
544
551
|
return await _connect_browser(
|
|
545
552
|
provider="local",
|
|
546
553
|
origin="connected",
|
|
547
554
|
source=_ConnectedBrowserSource(options.cdp_url),
|
|
548
|
-
|
|
549
|
-
extension_id=options.extension_id,
|
|
555
|
+
local_extension_dir=lambda: str(extension_directory()),
|
|
550
556
|
worker_init_metadata=_WorkerInitMetadata(api_key=None, browser=None),
|
|
551
557
|
)
|
|
552
558
|
|
|
@@ -646,6 +652,12 @@ class BrowserbaseBrowser:
|
|
|
646
652
|
session_id: str,
|
|
647
653
|
extension_id: str | None = None,
|
|
648
654
|
) -> StagehandBrowser:
|
|
655
|
+
"""Connect to an existing browser.
|
|
656
|
+
|
|
657
|
+
Args:
|
|
658
|
+
extension_id: Deprecated and ignored. Omit this argument; Stagehand
|
|
659
|
+
discovers the installed extension automatically.
|
|
660
|
+
"""
|
|
649
661
|
options = BrowserbaseConnectOptions.model_validate({
|
|
650
662
|
name: value
|
|
651
663
|
for name, value in (
|
|
@@ -668,8 +680,7 @@ class BrowserbaseBrowser:
|
|
|
668
680
|
keep_alive=True,
|
|
669
681
|
_close_callback=connection.close,
|
|
670
682
|
),
|
|
671
|
-
|
|
672
|
-
preloaded_extension=options.extension_id is None,
|
|
683
|
+
preloaded_extension=True,
|
|
673
684
|
worker_init_metadata=_WorkerInitMetadata(
|
|
674
685
|
api_key=options.api_key,
|
|
675
686
|
browser=_browser_session_metadata(connection.session_id, connection.region),
|
|
@@ -4,7 +4,7 @@ import asyncio
|
|
|
4
4
|
import json
|
|
5
5
|
import re
|
|
6
6
|
import time
|
|
7
|
-
from collections.abc import Mapping
|
|
7
|
+
from collections.abc import Callable, Mapping
|
|
8
8
|
from contextlib import suppress
|
|
9
9
|
from dataclasses import dataclass
|
|
10
10
|
from typing import Any, Literal, Protocol, cast
|
|
@@ -253,6 +253,7 @@ class CDPClient:
|
|
|
253
253
|
*,
|
|
254
254
|
cdp_url: str,
|
|
255
255
|
extension_dir: str | None = None,
|
|
256
|
+
local_extension_dir: Callable[[], str] | None = None,
|
|
256
257
|
extension_id: str | None = None,
|
|
257
258
|
preloaded_extension: bool = False,
|
|
258
259
|
service_worker_url_includes: str | None = None,
|
|
@@ -263,9 +264,18 @@ class CDPClient:
|
|
|
263
264
|
lifecycle. Direct internal callers must provide cancellation themselves.
|
|
264
265
|
CDP command acknowledgements inherit that same caller-owned cancellation.
|
|
265
266
|
"""
|
|
266
|
-
if
|
|
267
|
+
if (
|
|
268
|
+
sum((
|
|
269
|
+
bool(extension_dir),
|
|
270
|
+
local_extension_dir is not None,
|
|
271
|
+
bool(extension_id),
|
|
272
|
+
preloaded_extension,
|
|
273
|
+
))
|
|
274
|
+
!= 1
|
|
275
|
+
):
|
|
267
276
|
raise ValueError(
|
|
268
|
-
"Exactly one of extension_dir, extension_id,
|
|
277
|
+
"Exactly one of extension_dir, local_extension_dir, extension_id, "
|
|
278
|
+
"or preloaded_extension is required"
|
|
269
279
|
)
|
|
270
280
|
|
|
271
281
|
web_socket_debugger_url = await _resolve_browser_web_socket_url(cdp_url)
|
|
@@ -274,10 +284,14 @@ class CDPClient:
|
|
|
274
284
|
|
|
275
285
|
try:
|
|
276
286
|
resolved_extension_id = extension_id
|
|
277
|
-
if
|
|
287
|
+
if local_extension_dir is not None:
|
|
288
|
+
resolved_extension_id = await client._resolve_extension(
|
|
289
|
+
load_if_not_found=True, extension_dir=local_extension_dir
|
|
290
|
+
)
|
|
291
|
+
elif extension_dir is not None:
|
|
278
292
|
resolved_extension_id = await client._load_unpacked_extension(extension_dir)
|
|
279
|
-
|
|
280
|
-
resolved_extension_id = await client.
|
|
293
|
+
elif preloaded_extension:
|
|
294
|
+
resolved_extension_id = await client._resolve_extension(load_if_not_found=False)
|
|
281
295
|
if resolved_extension_id is None:
|
|
282
296
|
raise RuntimeError("Stagehand extension ID was not resolved")
|
|
283
297
|
|
|
@@ -491,12 +505,41 @@ class CDPClient:
|
|
|
491
505
|
if error.code == -32601 or "method not found" in str(error).lower():
|
|
492
506
|
raise RuntimeError(
|
|
493
507
|
"This Chrome build does not support Extensions.loadUnpacked. "
|
|
494
|
-
"
|
|
508
|
+
"Preload the Stagehand extension and connect using a Chrome build "
|
|
509
|
+
"that supports Extensions.getExtensions."
|
|
495
510
|
) from error
|
|
496
511
|
raise
|
|
497
512
|
return _required_string(loaded, "id", "Extensions.loadUnpacked")
|
|
498
513
|
|
|
499
|
-
async def
|
|
514
|
+
async def _resolve_extension(
|
|
515
|
+
self,
|
|
516
|
+
*,
|
|
517
|
+
load_if_not_found: bool,
|
|
518
|
+
extension_dir: Callable[[], str] | None = None,
|
|
519
|
+
) -> str:
|
|
520
|
+
extension_id: str | None = None
|
|
521
|
+
try:
|
|
522
|
+
extension_id = await self._get_installed_stagehand_extension_id()
|
|
523
|
+
except _CDPCommandError as error:
|
|
524
|
+
unsupported = error.method == "Extensions.getExtensions" and (
|
|
525
|
+
error.code == -32601
|
|
526
|
+
or "method not found" in str(error).lower()
|
|
527
|
+
or "wasn't found" in str(error).lower()
|
|
528
|
+
)
|
|
529
|
+
if not load_if_not_found or not unsupported:
|
|
530
|
+
raise
|
|
531
|
+
if extension_id is not None:
|
|
532
|
+
return extension_id
|
|
533
|
+
if load_if_not_found:
|
|
534
|
+
if extension_dir is None:
|
|
535
|
+
raise ValueError("extension_dir is required to load the Stagehand extension")
|
|
536
|
+
return await self._load_unpacked_extension(extension_dir())
|
|
537
|
+
raise RuntimeError(
|
|
538
|
+
"Stagehand extension is not installed in the connected browser. "
|
|
539
|
+
"The extension must be included when the Browserbase session is created."
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
async def _get_installed_stagehand_extension_id(self) -> str | None:
|
|
500
543
|
response = await self.send_command("Extensions.getExtensions")
|
|
501
544
|
installed = [
|
|
502
545
|
extension
|
|
@@ -514,10 +557,7 @@ class CDPClient:
|
|
|
514
557
|
raise RuntimeError(
|
|
515
558
|
"Stagehand extension is installed in the connected browser but is disabled."
|
|
516
559
|
)
|
|
517
|
-
|
|
518
|
-
"Stagehand extension is not installed in the connected browser. "
|
|
519
|
-
"The extension must be included when the Browserbase session is created."
|
|
520
|
-
)
|
|
560
|
+
return None
|
|
521
561
|
|
|
522
562
|
async def _wait_for_service_worker(
|
|
523
563
|
self,
|
|
@@ -105,7 +105,8 @@ class LocalBrowserConnectOptions(WireModel):
|
|
|
105
105
|
model_config = ConfigDict(extra="forbid", strict=True)
|
|
106
106
|
|
|
107
107
|
cdp_url: Annotated[str, Field(min_length=1)]
|
|
108
|
-
extension_id:
|
|
108
|
+
extension_id: str | None = None
|
|
109
|
+
"""Deprecated and ignored. Omit this field; Stagehand discovers the extension automatically."""
|
|
109
110
|
|
|
110
111
|
|
|
111
112
|
class BrowserbaseClientOptions(WireModel):
|
|
@@ -125,7 +126,8 @@ class BrowserbaseConnectOptions(WireModel):
|
|
|
125
126
|
base_url: Annotated[str, Field(min_length=1)] = DEFAULT_BROWSERBASE_URL
|
|
126
127
|
client_options: BrowserbaseClientOptions | None = None
|
|
127
128
|
session_id: Annotated[str, Field(min_length=1)]
|
|
128
|
-
extension_id:
|
|
129
|
+
extension_id: str | None = None
|
|
130
|
+
"""Deprecated and ignored. Omit this field; Stagehand discovers the extension automatically."""
|
|
129
131
|
|
|
130
132
|
|
|
131
133
|
class _BrowserbaseSearchOptions(WireModel):
|
|
@@ -66,6 +66,7 @@ class LocalBrowserLaunchOptions(TypedDict, total=False):
|
|
|
66
66
|
class LocalBrowserConnectOptions(TypedDict):
|
|
67
67
|
cdp_url: str
|
|
68
68
|
extension_id: NotRequired[str]
|
|
69
|
+
"""Deprecated and ignored. Omit this field; Stagehand discovers the extension automatically."""
|
|
69
70
|
|
|
70
71
|
|
|
71
72
|
class BrowserbaseClientOptions(TypedDict, total=False):
|
|
@@ -85,6 +86,7 @@ class BrowserbaseConnectOptions(TypedDict):
|
|
|
85
86
|
client_options: NotRequired[BrowserbaseClientOptions]
|
|
86
87
|
session_id: str
|
|
87
88
|
extension_id: NotRequired[str]
|
|
89
|
+
"""Deprecated and ignored. Omit this field; Stagehand discovers the extension automatically."""
|
|
88
90
|
|
|
89
91
|
|
|
90
92
|
class ClientLLM(TypedDict):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/content-script.js
RENAMED
|
File without changes
|
{stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_extension/manifest.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_generated/__init__.py
RENAMED
|
File without changes
|
{stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/_generated/input_types.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/browserbase_services.py
RENAMED
|
File without changes
|
{stagehand-4.2.0a0.dev1587 → stagehand-4.2.0a0.dev1588}/src/stagehand/browserbase_session.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|