stagehand 4.2.2a0.dev1615__tar.gz → 4.3.0__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.2a0.dev1615 → stagehand-4.3.0}/PKG-INFO +1 -1
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/pyproject.toml +1 -1
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/__init__.py +2 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_extension/service-worker.js +211 -46
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_generated/input_types.py +22 -4
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_generated/models.py +45 -7
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_generated/protocol_version.py +1 -1
- stagehand-4.3.0/src/stagehand/_validation.py +139 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/browser.py +23 -1
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/cdp_client.py +98 -10
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/client_models.py +7 -2
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/client_types.py +4 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/extension_assets.py +9 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/page.py +45 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/rpc_client.py +8 -4
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/stagehand.py +4 -1
- stagehand-4.2.2a0.dev1615/src/stagehand/_validation.py +0 -67
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/README.md +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_extension/blank.html +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_extension/content-script.js +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_extension/manifest.json +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_extension/offscreen/service-worker-heartbeat.html +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_extension/offscreen/service-worker-heartbeat.js +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_extension/wake-service-worker.html +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_extension/wake-service-worker.js +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_generated/__init__.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/_sdk_identity.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/browser_clipboard.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/browser_context.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/browserbase_connection.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/browserbase_rpc.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/browserbase_services.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/browserbase_session.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/browserbase_transport.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/file_upload.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/locator.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/py.typed +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/response.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/timeouts.py +0 -0
- {stagehand-4.2.2a0.dev1615 → stagehand-4.3.0}/src/stagehand/webmcp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stagehand
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
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
|
|
@@ -75,6 +75,7 @@ from .client_types import (
|
|
|
75
75
|
LLMGenerateOutput,
|
|
76
76
|
StagehandClientLoggingConfig,
|
|
77
77
|
)
|
|
78
|
+
from .extension_assets import get_extension_archive
|
|
78
79
|
from .file_upload import FileInput, FilePayload
|
|
79
80
|
from .locator import Locator
|
|
80
81
|
from .page import (
|
|
@@ -172,5 +173,6 @@ __all__ = [
|
|
|
172
173
|
"WebMCPTool",
|
|
173
174
|
"WebMCPToolResponse",
|
|
174
175
|
"browserbase",
|
|
176
|
+
"get_extension_archive",
|
|
175
177
|
"local_browser",
|
|
176
178
|
]
|
|
@@ -7363,7 +7363,7 @@ function isRecord$1(value) {
|
|
|
7363
7363
|
}
|
|
7364
7364
|
var package_default$1 = {
|
|
7365
7365
|
name: "@browserbasehq/stagehand-protocol",
|
|
7366
|
-
version: "3.0.0
|
|
7366
|
+
version: "3.0.0",
|
|
7367
7367
|
"private": true,
|
|
7368
7368
|
type: "module",
|
|
7369
7369
|
exports: {
|
|
@@ -8553,6 +8553,13 @@ var PageWaitForLoadStateParamsSchema = PageIdParamsSchema.extend({
|
|
|
8553
8553
|
timeout: number$1().int().nonnegative().optional()
|
|
8554
8554
|
}).meta({ id: "PageWaitForLoadStateParams" });
|
|
8555
8555
|
var PageWaitForTimeoutParamsSchema = PageIdParamsSchema.extend({ ms: number$1().int().nonnegative() }).meta({ id: "PageWaitForTimeoutParams" });
|
|
8556
|
+
var PageWaitForFunctionParamsSchema = PageIdParamsSchema.extend({
|
|
8557
|
+
expression: string(),
|
|
8558
|
+
options: strictObject({
|
|
8559
|
+
polling: union([literal("raf"), number$1().positive().max(2147483647)]).optional(),
|
|
8560
|
+
timeout: number$1().int().nonnegative().optional()
|
|
8561
|
+
}).meta({ id: "PageWaitForFunctionOptions" }).optional()
|
|
8562
|
+
}).meta({ id: "PageWaitForFunctionParams" });
|
|
8556
8563
|
var PageWaitForSelectorParamsSchema = PageIdParamsSchema.extend({
|
|
8557
8564
|
selector: string().min(1),
|
|
8558
8565
|
options: strictObject({
|
|
@@ -8626,6 +8633,7 @@ var PageEvaluateResultSchema = strictObject({ value: json$1() }).meta({ id: "Pag
|
|
|
8626
8633
|
var PageScreenshotResultSchema = strictObject({ data: base64().meta({ format: "byte" }) }).meta({ id: "PageScreenshotResult" });
|
|
8627
8634
|
var PagePDFResultSchema = strictObject({ data: base64().meta({ format: "byte" }) }).meta({ id: "PagePDFResult" });
|
|
8628
8635
|
var PageWaitForSelectorResultSchema = strictObject({ matched: boolean() }).meta({ id: "PageWaitForSelectorResult" });
|
|
8636
|
+
var PageWaitForFunctionResultSchema = strictObject({ value: json$1() }).meta({ id: "PageWaitForFunctionResult" });
|
|
8629
8637
|
var LocatorClickResultSchema = strictObject({ clicked: literal(true) }).meta({ id: "LocatorClickResult" });
|
|
8630
8638
|
var LocatorFillResultSchema = strictObject({ filled: literal(true) }).meta({ id: "LocatorFillResult" });
|
|
8631
8639
|
var LocatorHoverResultSchema = strictObject({ hovered: literal(true) }).meta({ id: "LocatorHoverResult" });
|
|
@@ -8940,6 +8948,12 @@ var StagehandMethods = {
|
|
|
8940
8948
|
params: PageWaitForSelectorParamsSchema,
|
|
8941
8949
|
result: PageWaitForSelectorResultSchema
|
|
8942
8950
|
},
|
|
8951
|
+
pageWaitForFunction: {
|
|
8952
|
+
name: "page.wait_for_function",
|
|
8953
|
+
params: PageWaitForFunctionParamsSchema,
|
|
8954
|
+
result: PageWaitForFunctionResultSchema,
|
|
8955
|
+
resultWire: { opaqueKeys: ["value"] }
|
|
8956
|
+
},
|
|
8943
8957
|
pageWebMCPTools: {
|
|
8944
8958
|
name: "page.webmcp_tools",
|
|
8945
8959
|
params: PageWebMCPToolsParamsSchema,
|
|
@@ -12001,9 +12015,18 @@ var Locator$1 = class Locator$1 {
|
|
|
12001
12015
|
};
|
|
12002
12016
|
//#endregion
|
|
12003
12017
|
//#region ../sdk-ts/src/pageScripts.ts
|
|
12004
|
-
function normalizeEvaluationExpression(expression, arg) {
|
|
12018
|
+
function normalizeEvaluationExpression(expression, arg, caller = "page.evaluate") {
|
|
12005
12019
|
if (typeof expression === "string") return expression;
|
|
12006
|
-
return `(${expression.toString()})(${serializeArgument(arg,
|
|
12020
|
+
return `(${expression.toString()})(${serializeArgument(arg, caller)})`;
|
|
12021
|
+
}
|
|
12022
|
+
function normalizeFunctionWaitExpression(expression, arg, caller = "page.waitForFunction") {
|
|
12023
|
+
if (typeof expression === "function") return `() => (${expression.toString()})(${parsedArgument(arg, caller)})`;
|
|
12024
|
+
if (arg === void 0) return expression;
|
|
12025
|
+
return `((value) => typeof value === "function" ? () => value(${parsedArgument(arg, caller)}) : value)((${expression}))`;
|
|
12026
|
+
}
|
|
12027
|
+
function parsedArgument(arg, caller) {
|
|
12028
|
+
if (arg === void 0) return "undefined";
|
|
12029
|
+
return `JSON.parse(${JSON.stringify(serializeArgument(arg, caller))})`;
|
|
12007
12030
|
}
|
|
12008
12031
|
async function normalizeInitScriptSource$1(script, arg, caller = "page.addInitScript") {
|
|
12009
12032
|
if (typeof script === "function") return `(${script.toString()})(${serializeArgument(arg, caller)})`;
|
|
@@ -12026,9 +12049,8 @@ async function normalizeInitScriptSource$1(script, arg, caller = "page.addInitSc
|
|
|
12026
12049
|
}
|
|
12027
12050
|
function serializeArgument(arg, caller) {
|
|
12028
12051
|
if (arg === void 0) return "undefined";
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
const serialized = JSON.stringify(parsed.data);
|
|
12052
|
+
if (!json$1().safeParse(arg).success) throw new TypeError(`${caller}: 'arg' must be JSON-serializable.`);
|
|
12053
|
+
const serialized = JSON.stringify(arg);
|
|
12032
12054
|
if (serialized === void 0) throw new TypeError(`${caller}: 'arg' must be JSON-serializable.`);
|
|
12033
12055
|
return serialized;
|
|
12034
12056
|
}
|
|
@@ -12362,6 +12384,14 @@ var Page$1 = class {
|
|
|
12362
12384
|
...options ? { options } : {}
|
|
12363
12385
|
})).matched;
|
|
12364
12386
|
}
|
|
12387
|
+
/** Poll in the page's main world until the expression returns a truthy JSON value. */
|
|
12388
|
+
async waitForFunction(expression, arg, options) {
|
|
12389
|
+
return (await this.rpcClient.send(StagehandMethods.pageWaitForFunction, {
|
|
12390
|
+
pageId: this.pageId,
|
|
12391
|
+
expression: normalizeFunctionWaitExpression(expression, arg),
|
|
12392
|
+
...options ? { options } : {}
|
|
12393
|
+
})).value;
|
|
12394
|
+
}
|
|
12365
12395
|
async screenshot(options) {
|
|
12366
12396
|
const { path, mask, ...screenshotOptions } = options ?? {};
|
|
12367
12397
|
return await decodeCaptureResult((await this.rpcClient.send(StagehandMethods.pageScreenshot, {
|
|
@@ -12527,9 +12557,36 @@ strictObject({
|
|
|
12527
12557
|
acceptDownloads: boolean().optional(),
|
|
12528
12558
|
keepAlive: boolean().optional()
|
|
12529
12559
|
}).meta({ id: "LocalBrowserLaunchOptions" });
|
|
12560
|
+
var CDPHeadersSchema = preprocess((value) => {
|
|
12561
|
+
try {
|
|
12562
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return null;
|
|
12563
|
+
const entries = Object.entries(value);
|
|
12564
|
+
if (!entries.every(([name, content]) => name.length > 0 && !/[^!#$%&'*+\-.^_`|~0-9A-Za-z]/.test(name) && typeof content === "string" && !/[^\t\x20-\x7e]/.test(content) && content === content.replace(/^[ \t]+|[ \t]+$/g, ""))) return null;
|
|
12565
|
+
return Object.fromEntries(entries);
|
|
12566
|
+
} catch {
|
|
12567
|
+
return null;
|
|
12568
|
+
}
|
|
12569
|
+
}, record(string(), string(), { error: "headers must map valid HTTP header names to ASCII string values without leading or trailing spaces or tabs" }));
|
|
12530
12570
|
strictObject({
|
|
12531
12571
|
cdpUrl: string().min(1),
|
|
12532
|
-
|
|
12572
|
+
/** Headers for client-side CDP discovery and WebSocket connections. */
|
|
12573
|
+
headers: CDPHeadersSchema.optional(),
|
|
12574
|
+
extensionId: string().optional(),
|
|
12575
|
+
/**
|
|
12576
|
+
* Browser-level CDP WebSocket URL dialed by the extension inside Chrome.
|
|
12577
|
+
* Defaults to the client's URL. Set this when the client connects through
|
|
12578
|
+
* a gateway the extension cannot or should not use.
|
|
12579
|
+
*/
|
|
12580
|
+
extensionCdpUrl: url({
|
|
12581
|
+
protocol: /^wss?$/,
|
|
12582
|
+
hostname: /.+/
|
|
12583
|
+
}).refine((value) => {
|
|
12584
|
+
try {
|
|
12585
|
+
return new URL(value).port !== "0";
|
|
12586
|
+
} catch {
|
|
12587
|
+
return false;
|
|
12588
|
+
}
|
|
12589
|
+
}, { message: "Port must be between 1 and 65535" }).optional()
|
|
12533
12590
|
}).meta({ id: "LocalBrowserConnectOptions" });
|
|
12534
12591
|
var DEFAULT_BROWSERBASE_URL = "https://api.browserbase.com";
|
|
12535
12592
|
var BrowserbaseClientOptionsSchema = strictObject({
|
|
@@ -12990,6 +13047,10 @@ function createPageController(runtime) {
|
|
|
12990
13047
|
logger.debug("page.wait_for_selector", {});
|
|
12991
13048
|
return runtime.pageWaitForSelector(params);
|
|
12992
13049
|
}
|
|
13050
|
+
async function waitForFunction(params, { logger }) {
|
|
13051
|
+
logger.debug("page.wait_for_function", {});
|
|
13052
|
+
return runtime.pageWaitForFunction(params);
|
|
13053
|
+
}
|
|
12993
13054
|
async function screenshot(params, { logger }) {
|
|
12994
13055
|
logger.debug("page.screenshot", {});
|
|
12995
13056
|
return runtime.pageScreenshot(params);
|
|
@@ -13056,6 +13117,7 @@ function createPageController(runtime) {
|
|
|
13056
13117
|
waitForLoadState,
|
|
13057
13118
|
waitForTimeout,
|
|
13058
13119
|
waitForSelector,
|
|
13120
|
+
waitForFunction,
|
|
13059
13121
|
screenshot,
|
|
13060
13122
|
pdf,
|
|
13061
13123
|
snapshot,
|
|
@@ -16928,6 +16990,38 @@ async function act$1(params) {
|
|
|
16928
16990
|
};
|
|
16929
16991
|
}
|
|
16930
16992
|
//#endregion
|
|
16993
|
+
//#region understudy/browserWait.ts
|
|
16994
|
+
/** Browser exceptions are not transient CDP context-loss errors. */
|
|
16995
|
+
var BrowserWaitError = class extends Error {};
|
|
16996
|
+
/** Own a browser-side promise and dispose its resources, even after late installation. */
|
|
16997
|
+
async function browserWait(session, progress, install, phase) {
|
|
16998
|
+
const dispose = (objectId) => Promise.all([progress.cleanup(() => session.send("Runtime.callFunctionOn", {
|
|
16999
|
+
objectId,
|
|
17000
|
+
functionDeclaration: "function() { this.dispose(); }",
|
|
17001
|
+
returnByValue: true
|
|
17002
|
+
})), progress.cleanup(() => session.send("Runtime.releaseObject", { objectId }))]);
|
|
17003
|
+
const response = await install(async (late) => {
|
|
17004
|
+
if (late.result.objectId) await dispose(late.result.objectId);
|
|
17005
|
+
});
|
|
17006
|
+
const objectId = response.result.objectId;
|
|
17007
|
+
let completed = false;
|
|
17008
|
+
try {
|
|
17009
|
+
if (response.exceptionDetails || !objectId) throw new BrowserWaitError(response.exceptionDetails?.exception?.description ?? response.exceptionDetails?.text ?? "Browser wait handle was not returned");
|
|
17010
|
+
const result = await progress.run(phase, () => session.send("Runtime.callFunctionOn", {
|
|
17011
|
+
objectId,
|
|
17012
|
+
functionDeclaration: "function() { return this.promise; }",
|
|
17013
|
+
awaitPromise: true,
|
|
17014
|
+
returnByValue: true
|
|
17015
|
+
}));
|
|
17016
|
+
if (result.exceptionDetails) throw new BrowserWaitError(result.exceptionDetails.exception?.description ?? result.exceptionDetails.text ?? "Browser wait failed");
|
|
17017
|
+
completed = true;
|
|
17018
|
+
return result.result.value;
|
|
17019
|
+
} finally {
|
|
17020
|
+
if (objectId) if (completed) progress.cleanup(() => session.send("Runtime.releaseObject", { objectId }));
|
|
17021
|
+
else await dispose(objectId);
|
|
17022
|
+
}
|
|
17023
|
+
}
|
|
17024
|
+
//#endregion
|
|
16931
17025
|
//#region understudy/frame.ts
|
|
16932
17026
|
function base64ToBytes$1(base64) {
|
|
16933
17027
|
const binary = globalThis.atob(base64);
|
|
@@ -17053,46 +17147,25 @@ var Frame = class {
|
|
|
17053
17147
|
}
|
|
17054
17148
|
/** Own a disposable browser wait, including a handle delivered after expiry. */
|
|
17055
17149
|
async waitInLocatorWorld(buildExpression, progress) {
|
|
17056
|
-
const dispose = (objectId) => Promise.all([progress.cleanup(() => this.session.send("Runtime.callFunctionOn", {
|
|
17057
|
-
objectId,
|
|
17058
|
-
functionDeclaration: "function() { this.dispose(); }",
|
|
17059
|
-
returnByValue: true
|
|
17060
|
-
})), progress.cleanup(() => this.session.send("Runtime.releaseObject", { objectId }))]);
|
|
17061
17150
|
for (let attempt = 0;; attempt++) {
|
|
17062
17151
|
progress.throwIfStopped();
|
|
17063
|
-
|
|
17064
|
-
progress,
|
|
17065
|
-
returnByValue: false,
|
|
17066
|
-
awaitPromise: false,
|
|
17067
|
-
onLateResult: async (late) => {
|
|
17068
|
-
if (late.result.objectId) await dispose(late.result.objectId);
|
|
17069
|
-
}
|
|
17070
|
-
});
|
|
17071
|
-
const objectId = response.result.objectId;
|
|
17072
|
-
let completed = false;
|
|
17152
|
+
let contextId;
|
|
17073
17153
|
try {
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
17077
|
-
|
|
17078
|
-
|
|
17079
|
-
|
|
17080
|
-
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
}
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
|
|
17089
|
-
}
|
|
17090
|
-
if (result.exceptionDetails) throw new Error(result.exceptionDetails.exception?.description ?? result.exceptionDetails.text ?? "Selector wait failed");
|
|
17091
|
-
completed = true;
|
|
17092
|
-
return result.result.value;
|
|
17093
|
-
} finally {
|
|
17094
|
-
if (objectId) if (completed) progress.cleanup(() => this.session.send("Runtime.releaseObject", { objectId }));
|
|
17095
|
-
else await dispose(objectId);
|
|
17154
|
+
return await browserWait(this.session, progress, async (onLateResult) => {
|
|
17155
|
+
const response = await this.evaluateLocatorExpression(buildExpression, {
|
|
17156
|
+
progress,
|
|
17157
|
+
returnByValue: false,
|
|
17158
|
+
awaitPromise: false,
|
|
17159
|
+
onLateResult
|
|
17160
|
+
});
|
|
17161
|
+
contextId = response.contextId;
|
|
17162
|
+
return response;
|
|
17163
|
+
}, "waiting for selector");
|
|
17164
|
+
} catch (error) {
|
|
17165
|
+
progress.throwIfStopped();
|
|
17166
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
17167
|
+
if (attempt !== 0 || contextId === void 0 || error instanceof BrowserWaitError || !message.includes("Cannot find context with specified id")) throw error;
|
|
17168
|
+
executionContexts.unregisterLocatorContext(this.session, contextId);
|
|
17096
17169
|
}
|
|
17097
17170
|
}
|
|
17098
17171
|
}
|
|
@@ -52061,6 +52134,7 @@ var RPCRouter = class {
|
|
|
52061
52134
|
case "page.wait_for_load_state": return this.pageController.waitForLoadState(parseParams(StagehandMethods.pageWaitForLoadState, request.params), context);
|
|
52062
52135
|
case "page.wait_for_timeout": return this.pageController.waitForTimeout(parseParams(StagehandMethods.pageWaitForTimeout, request.params), context);
|
|
52063
52136
|
case "page.wait_for_selector": return this.pageController.waitForSelector(parseParams(StagehandMethods.pageWaitForSelector, request.params), context);
|
|
52137
|
+
case "page.wait_for_function": return this.pageController.waitForFunction(parseParams(StagehandMethods.pageWaitForFunction, request.params), context);
|
|
52064
52138
|
case "page.screenshot": return this.pageController.screenshot(parseParams(StagehandMethods.pageScreenshot, request.params), context);
|
|
52065
52139
|
case "page.pdf": return this.pageController.pdf(parseParams(StagehandMethods.pagePDF, request.params), context);
|
|
52066
52140
|
case "page.snapshot": return this.pageController.snapshot(parseParams(StagehandMethods.pageSnapshot, request.params), context);
|
|
@@ -54456,7 +54530,7 @@ var WebTracerProvider = class extends BasicTracerProvider {
|
|
|
54456
54530
|
};
|
|
54457
54531
|
var package_default = {
|
|
54458
54532
|
name: "@browserbasehq/stagehand-extension",
|
|
54459
|
-
version: "1.2.0
|
|
54533
|
+
version: "1.2.0",
|
|
54460
54534
|
"private": true,
|
|
54461
54535
|
type: "module",
|
|
54462
54536
|
scripts: {
|
|
@@ -55851,6 +55925,83 @@ async function normalizeInitScriptSource(script, arg, caller = DEFAULT_CALLER) {
|
|
|
55851
55925
|
throw new TypeError(`${caller}: provide a string, function, or an object with content.`);
|
|
55852
55926
|
}
|
|
55853
55927
|
//#endregion
|
|
55928
|
+
//#region understudy/functionWait.ts
|
|
55929
|
+
/** Runs in the page's main world; keep this function self-contained. */
|
|
55930
|
+
function createFunctionWait(predicate, polling) {
|
|
55931
|
+
let stopped = false;
|
|
55932
|
+
let timer;
|
|
55933
|
+
let animationFrame;
|
|
55934
|
+
let resolve;
|
|
55935
|
+
let reject;
|
|
55936
|
+
const promise = new Promise((done, fail) => {
|
|
55937
|
+
resolve = done;
|
|
55938
|
+
reject = fail;
|
|
55939
|
+
});
|
|
55940
|
+
promise.catch(() => {});
|
|
55941
|
+
const stop = () => {
|
|
55942
|
+
stopped = true;
|
|
55943
|
+
clearTimeout(timer);
|
|
55944
|
+
if (animationFrame !== void 0) cancelAnimationFrame(animationFrame);
|
|
55945
|
+
};
|
|
55946
|
+
const poll = async () => {
|
|
55947
|
+
if (stopped) return;
|
|
55948
|
+
try {
|
|
55949
|
+
const evaluated = predicate();
|
|
55950
|
+
const value = await (typeof evaluated === "function" ? evaluated() : evaluated);
|
|
55951
|
+
if (stopped) return;
|
|
55952
|
+
if (value) {
|
|
55953
|
+
const serialized = JSON.stringify(value);
|
|
55954
|
+
if (serialized === void 0) throw new TypeError("waitForFunction result must be JSON-serializable");
|
|
55955
|
+
const result = JSON.parse(serialized);
|
|
55956
|
+
stop();
|
|
55957
|
+
resolve(result);
|
|
55958
|
+
} else if (polling === "raf") animationFrame = requestAnimationFrame(() => void poll());
|
|
55959
|
+
else timer = setTimeout(() => void poll(), polling);
|
|
55960
|
+
} catch (error) {
|
|
55961
|
+
stop();
|
|
55962
|
+
reject(error);
|
|
55963
|
+
}
|
|
55964
|
+
};
|
|
55965
|
+
poll();
|
|
55966
|
+
return {
|
|
55967
|
+
promise,
|
|
55968
|
+
dispose() {
|
|
55969
|
+
if (stopped) return;
|
|
55970
|
+
stop();
|
|
55971
|
+
reject(/* @__PURE__ */ new Error("Function wait disposed"));
|
|
55972
|
+
}
|
|
55973
|
+
};
|
|
55974
|
+
}
|
|
55975
|
+
async function waitForFunction(getFrame, expression, options = {}) {
|
|
55976
|
+
const polling = options.polling ?? "raf";
|
|
55977
|
+
if (polling !== "raf" && (!Number.isFinite(polling) || polling <= 0 || polling > 2147483647)) throw new RangeError("Polling must be 'raf' or a positive interval up to 2147483647ms");
|
|
55978
|
+
return runWithProgress({
|
|
55979
|
+
name: "waitForFunction",
|
|
55980
|
+
timeout: options.timeout ?? 0
|
|
55981
|
+
}, async (progress) => {
|
|
55982
|
+
for (;;) {
|
|
55983
|
+
progress.throwIfStopped();
|
|
55984
|
+
const frame = getFrame();
|
|
55985
|
+
try {
|
|
55986
|
+
const contextId = await frame.getMainWorldExecutionContextId(progress);
|
|
55987
|
+
if (getFrame() !== frame) continue;
|
|
55988
|
+
return await browserWait(frame.session, progress, (onLateResult) => progress.run("installing function wait", () => frame.session.send("Runtime.evaluate", {
|
|
55989
|
+
expression: `(${createFunctionWait.toString()})(() => (${expression}), ${JSON.stringify(polling)})`,
|
|
55990
|
+
contextId,
|
|
55991
|
+
awaitPromise: false,
|
|
55992
|
+
returnByValue: false
|
|
55993
|
+
}), onLateResult), "waiting for function");
|
|
55994
|
+
} catch (error) {
|
|
55995
|
+
progress.throwIfStopped();
|
|
55996
|
+
if (error instanceof BrowserWaitError) throw error;
|
|
55997
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
55998
|
+
if (!message.includes("Cannot find context with specified id") && !message.includes("Execution context was destroyed") && !message.includes("Cannot find object with given id") && !message.includes("Inspected target navigated or closed") && !message.startsWith("main world not ready for frame ")) throw error;
|
|
55999
|
+
await progress.delay(25);
|
|
56000
|
+
}
|
|
56001
|
+
}
|
|
56002
|
+
});
|
|
56003
|
+
}
|
|
56004
|
+
//#endregion
|
|
55854
56005
|
//#region dom/screenshotScripts/resolveMaskRect.ts
|
|
55855
56006
|
function resolveMaskRect(maskToken) {
|
|
55856
56007
|
function safeClosest(el, selector) {
|
|
@@ -57409,6 +57560,14 @@ var Page = class Page {
|
|
|
57409
57560
|
async waitForTimeout(ms) {
|
|
57410
57561
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
57411
57562
|
}
|
|
57563
|
+
/** Poll an expression in the page's main world until its value is truthy. */
|
|
57564
|
+
async waitForFunction(expression, options) {
|
|
57565
|
+
return waitForFunction(() => {
|
|
57566
|
+
if (this.disposed) throw new Error("Page is disposed");
|
|
57567
|
+
if (!this.conn.connected) throw new Error("CDP connection closed: function wait stopped");
|
|
57568
|
+
return this.mainFrameWrapper;
|
|
57569
|
+
}, expression, options);
|
|
57570
|
+
}
|
|
57412
57571
|
/**
|
|
57413
57572
|
* Wait for an element matching the selector to appear in the DOM.
|
|
57414
57573
|
* Uses MutationObserver for efficiency
|
|
@@ -58376,12 +58535,14 @@ var StagehandRuntime = class {
|
|
|
58376
58535
|
const { cdpUrl } = params;
|
|
58377
58536
|
const previousSession = this.browserSession;
|
|
58378
58537
|
this.browserSession = void 0;
|
|
58538
|
+
this.browserSessionCdpUrl = void 0;
|
|
58379
58539
|
this.disposeAllPageEventSubscriptions();
|
|
58380
58540
|
this.pagesById.clear();
|
|
58381
58541
|
this.responseHandles.clear();
|
|
58382
58542
|
await previousSession?.close();
|
|
58383
58543
|
try {
|
|
58384
58544
|
this.browserSession = await this.adapters.browserSessionFactory(cdpUrl, this.logger, bootstrapLogger);
|
|
58545
|
+
this.browserSessionCdpUrl = cdpUrl;
|
|
58385
58546
|
} catch (error) {
|
|
58386
58547
|
await this.browserSession?.close();
|
|
58387
58548
|
this.browserSession = void 0;
|
|
@@ -58396,7 +58557,7 @@ var StagehandRuntime = class {
|
|
|
58396
58557
|
const state = this.state.getState();
|
|
58397
58558
|
if (state.status !== "idle") throw new Error("A Stagehand instance is already initialized");
|
|
58398
58559
|
this.logger.setLevel(params.logLevel);
|
|
58399
|
-
if (!this.browserSession?.connected) {
|
|
58560
|
+
if (!this.browserSession?.connected || params.browserCdpUrl !== void 0 && params.browserCdpUrl !== this.browserSessionCdpUrl) {
|
|
58400
58561
|
if (!params.browserCdpUrl) throw new Error("stagehand.init requires browserCdpUrl until resident mode is active");
|
|
58401
58562
|
await this.replaceBrowserConnection({ cdpUrl: params.browserCdpUrl }, logger);
|
|
58402
58563
|
}
|
|
@@ -58616,6 +58777,9 @@ var StagehandRuntime = class {
|
|
|
58616
58777
|
async pageWaitForSelector(params) {
|
|
58617
58778
|
return { matched: await this.resolvePage(params.pageId).waitForSelector(params.selector, params.options) };
|
|
58618
58779
|
}
|
|
58780
|
+
async pageWaitForFunction(params) {
|
|
58781
|
+
return { value: await this.resolvePage(params.pageId).waitForFunction(params.expression, params.options) };
|
|
58782
|
+
}
|
|
58619
58783
|
async pageScreenshot(params) {
|
|
58620
58784
|
const page = this.resolvePage(params.pageId);
|
|
58621
58785
|
let options;
|
|
@@ -58798,6 +58962,7 @@ var StagehandRuntime = class {
|
|
|
58798
58962
|
await this.enqueueLifecycle(async () => {
|
|
58799
58963
|
const session = this.browserSession;
|
|
58800
58964
|
this.browserSession = void 0;
|
|
58965
|
+
this.browserSessionCdpUrl = void 0;
|
|
58801
58966
|
this.clearStagehandInstance();
|
|
58802
58967
|
await session?.close();
|
|
58803
58968
|
});
|
|
@@ -277,6 +277,9 @@ FieldSchema13: TypeAlias = Optional[Union[str, float, bool, list["FieldSchema13"
|
|
|
277
277
|
FieldSchema14: TypeAlias = Optional[Union[str, float, bool, list["FieldSchema14"], dict[str, "FieldSchema14"]]]
|
|
278
278
|
|
|
279
279
|
|
|
280
|
+
FieldSchema15: TypeAlias = Optional[Union[str, float, bool, list["FieldSchema15"], dict[str, "FieldSchema15"]]]
|
|
281
|
+
|
|
282
|
+
|
|
280
283
|
FieldSchema2: TypeAlias = Optional[Union[str, float, bool, list["FieldSchema2"], dict[str, "FieldSchema2"]]]
|
|
281
284
|
|
|
282
285
|
|
|
@@ -332,7 +335,7 @@ class InputFilePayload(TypedDict):
|
|
|
332
335
|
class JSONRPCErrorObject(TypedDict):
|
|
333
336
|
code: int
|
|
334
337
|
message: str
|
|
335
|
-
data: NotRequired[
|
|
338
|
+
data: NotRequired[FieldSchema15]
|
|
336
339
|
|
|
337
340
|
|
|
338
341
|
JSONRPCRequestId: TypeAlias = int
|
|
@@ -718,7 +721,7 @@ class PageAddInitScriptParams(TypedDict):
|
|
|
718
721
|
source: str
|
|
719
722
|
|
|
720
723
|
|
|
721
|
-
PageCDPEventParams: TypeAlias = dict[str,
|
|
724
|
+
PageCDPEventParams: TypeAlias = dict[str, FieldSchema13]
|
|
722
725
|
|
|
723
726
|
|
|
724
727
|
class PageCDPEvent(TypedDict):
|
|
@@ -984,6 +987,21 @@ class PageVoidResult(TypedDict):
|
|
|
984
987
|
ok: Literal[True]
|
|
985
988
|
|
|
986
989
|
|
|
990
|
+
class PageWaitForFunctionOptions(TypedDict):
|
|
991
|
+
polling: NotRequired[Literal["raf"] | float]
|
|
992
|
+
timeout: NotRequired[int]
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
class PageWaitForFunctionParams(TypedDict):
|
|
996
|
+
page_id: str
|
|
997
|
+
expression: str
|
|
998
|
+
options: NotRequired[PageWaitForFunctionOptions]
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
class PageWaitForFunctionResult(TypedDict):
|
|
1002
|
+
value: FieldSchema10
|
|
1003
|
+
|
|
1004
|
+
|
|
987
1005
|
class PageWaitForLoadStateParams(TypedDict):
|
|
988
1006
|
page_id: str
|
|
989
1007
|
state: LoadState
|
|
@@ -1101,7 +1119,7 @@ class StagehandInitResult(TypedDict):
|
|
|
1101
1119
|
pages: list[PageRef]
|
|
1102
1120
|
|
|
1103
1121
|
|
|
1104
|
-
StagehandLogData: TypeAlias = dict[str,
|
|
1122
|
+
StagehandLogData: TypeAlias = dict[str, FieldSchema12]
|
|
1105
1123
|
|
|
1106
1124
|
|
|
1107
1125
|
StagehandLogLevel: TypeAlias = Literal["debug", "info", "warn", "error"]
|
|
@@ -1242,7 +1260,7 @@ class WebMCPAnnotation(TypedDict):
|
|
|
1242
1260
|
WebMCPInvocationStatus: TypeAlias = Literal["Completed", "Canceled", "Error"]
|
|
1243
1261
|
|
|
1244
1262
|
|
|
1245
|
-
WebMCPJsonValue: TypeAlias =
|
|
1263
|
+
WebMCPJsonValue: TypeAlias = FieldSchema11
|
|
1246
1264
|
|
|
1247
1265
|
|
|
1248
1266
|
class PageWebMCPInvokeToolParams(TypedDict):
|
|
@@ -710,6 +710,12 @@ class FieldSchema14(
|
|
|
710
710
|
root: Optional[Union[StrictStr, StrictInt, StrictFloat, StrictBool, list[Optional["FieldSchema14"]], dict[StrictStr, Optional["FieldSchema14"]]]]
|
|
711
711
|
|
|
712
712
|
|
|
713
|
+
class FieldSchema15(
|
|
714
|
+
RootModel[Optional[Union[StrictStr, StrictInt, StrictFloat, StrictBool, list[Optional["FieldSchema15"]], dict[StrictStr, Optional["FieldSchema15"]]]]]
|
|
715
|
+
):
|
|
716
|
+
root: Optional[Union[StrictStr, StrictInt, StrictFloat, StrictBool, list[Optional["FieldSchema15"]], dict[StrictStr, Optional["FieldSchema15"]]]]
|
|
717
|
+
|
|
718
|
+
|
|
713
719
|
class FieldSchema2(
|
|
714
720
|
RootModel[Optional[Union[StrictStr, StrictInt, StrictFloat, StrictBool, list[Optional["FieldSchema2"]], dict[StrictStr, Optional["FieldSchema2"]]]]]
|
|
715
721
|
):
|
|
@@ -811,7 +817,7 @@ class JSONRPCErrorObject(WireModel):
|
|
|
811
817
|
)
|
|
812
818
|
code: Annotated[StrictInt, Field(ge=-9007199254740991, le=9007199254740991)]
|
|
813
819
|
message: StrictStr
|
|
814
|
-
data: Optional[
|
|
820
|
+
data: Optional[FieldSchema15] = None
|
|
815
821
|
|
|
816
822
|
|
|
817
823
|
class JSONRPCRequestId(RootModel[StrictInt]):
|
|
@@ -1564,8 +1570,8 @@ class PageCDPEventNotification(WireModel):
|
|
|
1564
1570
|
event: PageCDPEvent
|
|
1565
1571
|
|
|
1566
1572
|
|
|
1567
|
-
class PageCDPEventParams(RootModel[dict[StrictStr, Optional[
|
|
1568
|
-
root: dict[StrictStr, Optional[
|
|
1573
|
+
class PageCDPEventParams(RootModel[dict[StrictStr, Optional[FieldSchema13]]]):
|
|
1574
|
+
root: dict[StrictStr, Optional[FieldSchema13]]
|
|
1569
1575
|
|
|
1570
1576
|
|
|
1571
1577
|
class PageClickOptions(WireModel):
|
|
@@ -2027,6 +2033,33 @@ class PageVoidResult(WireModel):
|
|
|
2027
2033
|
ok: Literal[True]
|
|
2028
2034
|
|
|
2029
2035
|
|
|
2036
|
+
class PageWaitForFunctionOptions(WireModel):
|
|
2037
|
+
model_config = ConfigDict(
|
|
2038
|
+
extra="forbid",
|
|
2039
|
+
validate_by_name=True,
|
|
2040
|
+
)
|
|
2041
|
+
polling: Optional[Union[Literal["raf"], Polling]] = None
|
|
2042
|
+
timeout: Annotated[Optional[StrictInt], Field(ge=0, le=9007199254740991)] = None
|
|
2043
|
+
|
|
2044
|
+
|
|
2045
|
+
class PageWaitForFunctionParams(WireModel):
|
|
2046
|
+
model_config = ConfigDict(
|
|
2047
|
+
extra="forbid",
|
|
2048
|
+
validate_by_name=True,
|
|
2049
|
+
)
|
|
2050
|
+
page_id: StrictStr
|
|
2051
|
+
expression: StrictStr
|
|
2052
|
+
options: Optional[PageWaitForFunctionOptions] = None
|
|
2053
|
+
|
|
2054
|
+
|
|
2055
|
+
class PageWaitForFunctionResult(WireModel):
|
|
2056
|
+
model_config = ConfigDict(
|
|
2057
|
+
extra="forbid",
|
|
2058
|
+
validate_by_name=True,
|
|
2059
|
+
)
|
|
2060
|
+
value: Optional[FieldSchema10]
|
|
2061
|
+
|
|
2062
|
+
|
|
2030
2063
|
class PageWaitForLoadStateParams(WireModel):
|
|
2031
2064
|
model_config = ConfigDict(
|
|
2032
2065
|
extra="forbid",
|
|
@@ -2123,6 +2156,10 @@ class PageWebMCPToolsResult(WireModel):
|
|
|
2123
2156
|
tools: list[WebMCPToolDescriptor]
|
|
2124
2157
|
|
|
2125
2158
|
|
|
2159
|
+
class Polling(RootModel[StrictFloat]):
|
|
2160
|
+
root: Annotated[StrictFloat, Field(gt=0.0, le=2147483647.0)]
|
|
2161
|
+
|
|
2162
|
+
|
|
2126
2163
|
class ProxyConfig(RootModel[Union[BrowserbaseProxyConfig, ExternalProxyConfig]]):
|
|
2127
2164
|
root: Union[BrowserbaseProxyConfig, ExternalProxyConfig]
|
|
2128
2165
|
|
|
@@ -2321,8 +2358,8 @@ class StagehandLog(WireModel):
|
|
|
2321
2358
|
data: StagehandLogData
|
|
2322
2359
|
|
|
2323
2360
|
|
|
2324
|
-
class StagehandLogData(RootModel[dict[StrictStr, Optional[
|
|
2325
|
-
root: dict[StrictStr, Optional[
|
|
2361
|
+
class StagehandLogData(RootModel[dict[StrictStr, Optional[FieldSchema12]]]):
|
|
2362
|
+
root: dict[StrictStr, Optional[FieldSchema12]]
|
|
2326
2363
|
|
|
2327
2364
|
|
|
2328
2365
|
class StagehandLogLevel(StrEnum):
|
|
@@ -2481,8 +2518,8 @@ class WebMCPInvocationStatus(StrEnum):
|
|
|
2481
2518
|
error = "Error"
|
|
2482
2519
|
|
|
2483
2520
|
|
|
2484
|
-
class WebMCPJsonValue(RootModel[Optional[
|
|
2485
|
-
root: Optional[
|
|
2521
|
+
class WebMCPJsonValue(RootModel[Optional[FieldSchema11]]):
|
|
2522
|
+
root: Optional[FieldSchema11]
|
|
2486
2523
|
|
|
2487
2524
|
|
|
2488
2525
|
class WebMCPRemoteObject(RootModel[dict[StrictStr, WebMCPJsonValue]]):
|
|
@@ -2548,6 +2585,7 @@ FieldSchema11.model_rebuild()
|
|
|
2548
2585
|
FieldSchema12.model_rebuild()
|
|
2549
2586
|
FieldSchema13.model_rebuild()
|
|
2550
2587
|
FieldSchema14.model_rebuild()
|
|
2588
|
+
FieldSchema15.model_rebuild()
|
|
2551
2589
|
FieldSchema2.model_rebuild()
|
|
2552
2590
|
FieldSchema3.model_rebuild()
|
|
2553
2591
|
FieldSchema4.model_rebuild()
|
|
@@ -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 = '3.0.0
|
|
4
|
+
STAGEHAND_PROTOCOL_VERSION = '3.0.0'
|