stagehand 4.2.0a0.dev1575__tar.gz → 4.2.0a0.dev1577__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.dev1575 → stagehand-4.2.0a0.dev1577}/PKG-INFO +1 -1
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/pyproject.toml +1 -1
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/service-worker.js +238 -193
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_generated/protocol_version.py +1 -1
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/README.md +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/__init__.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/blank.html +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/content-script.js +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/manifest.json +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/offscreen/service-worker-heartbeat.html +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/offscreen/service-worker-heartbeat.js +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/wake-service-worker.html +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/wake-service-worker.js +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_generated/__init__.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_generated/input_types.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_generated/models.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_sdk_identity.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_validation.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/browser.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/browser_clipboard.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/browser_context.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/browserbase_services.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/browserbase_session.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/cdp_client.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/client_models.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/client_types.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/extension_assets.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/file_upload.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/locator.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/page.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/py.typed +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/response.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/rpc_client.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/stagehand.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/timeouts.py +0 -0
- {stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/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.dev1577
|
|
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.dev1575 → stagehand-4.2.0a0.dev1577}/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-c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a",
|
|
7367
7367
|
"private": true,
|
|
7368
7368
|
type: "module",
|
|
7369
7369
|
exports: {
|
|
@@ -16188,12 +16188,12 @@ function stringifyArgument(value) {
|
|
|
16188
16188
|
return "[unserializable]";
|
|
16189
16189
|
}
|
|
16190
16190
|
}
|
|
16191
|
-
async function performUnderstudyMethod(page, frame, method, rawXPath, args, logger, domSettleTimeoutMs) {
|
|
16191
|
+
async function performUnderstudyMethod(page, frame, method, rawXPath, args, logger, progress, domSettleTimeoutMs) {
|
|
16192
16192
|
const selectorRaw = normalizeRootXPath(rawXPath);
|
|
16193
16193
|
try {
|
|
16194
16194
|
await logger.span(`Understudy${toTitleCase(method)}`, { target: selectorRaw }, async (spanLogger) => {
|
|
16195
|
-
const locator = await resolveLocatorWithHops(page, frame, selectorRaw);
|
|
16196
|
-
const initialUrl = await
|
|
16195
|
+
const locator = await resolveLocatorWithHops(page, frame, selectorRaw, progress);
|
|
16196
|
+
const initialUrl = await progress.run("reading frame URL", () => frame.evaluate("location.href", void 0, progress));
|
|
16197
16197
|
spanLogger.debug("Performing understudy method", {
|
|
16198
16198
|
category: "action",
|
|
16199
16199
|
xpath: selectorRaw,
|
|
@@ -16209,11 +16209,12 @@ async function performUnderstudyMethod(page, frame, method, rawXPath, args, logg
|
|
|
16209
16209
|
page,
|
|
16210
16210
|
initialUrl,
|
|
16211
16211
|
logger: spanLogger,
|
|
16212
|
-
domSettleTimeoutMs
|
|
16212
|
+
domSettleTimeoutMs,
|
|
16213
|
+
progress
|
|
16213
16214
|
};
|
|
16214
16215
|
const handler = METHOD_HANDLER_MAP[method] ?? null;
|
|
16215
16216
|
if (handler) {
|
|
16216
|
-
await handler(ctx);
|
|
16217
|
+
await progress.run(`performing ${method}`, () => handler(ctx));
|
|
16217
16218
|
return;
|
|
16218
16219
|
}
|
|
16219
16220
|
spanLogger.debug("Chosen method is invalid", {
|
|
@@ -16258,7 +16259,7 @@ async function selectOption(ctx) {
|
|
|
16258
16259
|
const { locator, xpath, args, logger } = ctx;
|
|
16259
16260
|
try {
|
|
16260
16261
|
const text = args[0]?.toString() || "";
|
|
16261
|
-
await locator.selectOption(text);
|
|
16262
|
+
await locator.selectOption(text, ctx.progress);
|
|
16262
16263
|
} catch (e) {
|
|
16263
16264
|
const msg = e instanceof Error ? e.message : String(e);
|
|
16264
16265
|
const stack = e instanceof Error ? e.stack : void 0;
|
|
@@ -16277,10 +16278,13 @@ async function scrollIntoView(ctx) {
|
|
|
16277
16278
|
category: "action",
|
|
16278
16279
|
xpath
|
|
16279
16280
|
});
|
|
16280
|
-
const { objectId } = await locator.resolveNode();
|
|
16281
|
+
const { objectId } = await locator.resolveNode(ctx.progress);
|
|
16281
16282
|
const ownerSession = locator.getFrame().session;
|
|
16282
|
-
|
|
16283
|
-
|
|
16283
|
+
try {
|
|
16284
|
+
await ctx.progress.run("scrolling element into view", () => ownerSession.send("DOM.scrollIntoViewIfNeeded", { objectId }));
|
|
16285
|
+
} finally {
|
|
16286
|
+
await ctx.progress.cleanup(() => ownerSession.send("Runtime.releaseObject", { objectId }));
|
|
16287
|
+
}
|
|
16284
16288
|
}
|
|
16285
16289
|
async function scrollElementToPercentage(ctx) {
|
|
16286
16290
|
const { locator, xpath, args, logger } = ctx;
|
|
@@ -16290,15 +16294,15 @@ async function scrollElementToPercentage(ctx) {
|
|
|
16290
16294
|
coordinate: [...args]
|
|
16291
16295
|
});
|
|
16292
16296
|
const [yArg = "0%"] = args;
|
|
16293
|
-
await locator.scrollTo(yArg);
|
|
16297
|
+
await locator.scrollTo(yArg, ctx.progress);
|
|
16294
16298
|
}
|
|
16295
16299
|
/** Scroll the page by pixel offset, starting from the element's center. */
|
|
16296
16300
|
async function scrollByPixelOffset(ctx) {
|
|
16297
16301
|
const { locator, page, args } = ctx;
|
|
16298
16302
|
const dx = Number(args[0] ?? 0);
|
|
16299
16303
|
const dy = Number(args[1] ?? 0);
|
|
16300
|
-
const { x, y } = await locator.centroid();
|
|
16301
|
-
await page.scroll(x, y, dx, dy);
|
|
16304
|
+
const { x, y } = await locator.centroid(ctx.progress);
|
|
16305
|
+
await page.scroll(x, y, dx, dy, ctx.progress);
|
|
16302
16306
|
}
|
|
16303
16307
|
async function wheelScroll(ctx) {
|
|
16304
16308
|
const { frame, args, logger } = ctx;
|
|
@@ -16307,19 +16311,19 @@ async function wheelScroll(ctx) {
|
|
|
16307
16311
|
category: "action",
|
|
16308
16312
|
deltaY
|
|
16309
16313
|
});
|
|
16310
|
-
await frame.session.send("Input.dispatchMouseEvent", {
|
|
16314
|
+
await ctx.progress.run("dispatching mouse wheel", () => frame.session.send("Input.dispatchMouseEvent", {
|
|
16311
16315
|
type: "mouseWheel",
|
|
16312
16316
|
x: 0,
|
|
16313
16317
|
y: 0,
|
|
16314
16318
|
deltaY,
|
|
16315
16319
|
deltaX: 0
|
|
16316
|
-
});
|
|
16320
|
+
}));
|
|
16317
16321
|
}
|
|
16318
16322
|
async function fillOrType(ctx) {
|
|
16319
16323
|
const { locator, xpath, args, logger } = ctx;
|
|
16320
16324
|
try {
|
|
16321
|
-
await locator.fill("");
|
|
16322
|
-
await locator.fill(args[0] ?? "");
|
|
16325
|
+
await locator.fill("", ctx.progress);
|
|
16326
|
+
await locator.fill(args[0] ?? "", ctx.progress);
|
|
16323
16327
|
} catch (e) {
|
|
16324
16328
|
const msg = e instanceof Error ? e.message : String(e);
|
|
16325
16329
|
logger.debug("Error filling element", {
|
|
@@ -16333,7 +16337,7 @@ async function fillOrType(ctx) {
|
|
|
16333
16337
|
async function typeText(ctx) {
|
|
16334
16338
|
const { locator, xpath, args, logger } = ctx;
|
|
16335
16339
|
try {
|
|
16336
|
-
await locator.type(args[0] ?? "");
|
|
16340
|
+
await locator.type(args[0] ?? "", void 0, ctx.progress);
|
|
16337
16341
|
} catch (e) {
|
|
16338
16342
|
const msg = e instanceof Error ? e.message : String(e);
|
|
16339
16343
|
logger.debug("Error typing into element", {
|
|
@@ -16353,7 +16357,7 @@ async function pressKey(ctx) {
|
|
|
16353
16357
|
key,
|
|
16354
16358
|
xpath
|
|
16355
16359
|
});
|
|
16356
|
-
await page.keyPress(key);
|
|
16360
|
+
await page.keyPress(key, void 0, ctx.progress);
|
|
16357
16361
|
} catch (e) {
|
|
16358
16362
|
const msg = e instanceof Error ? e.message : String(e);
|
|
16359
16363
|
logger.debug("Error pressing key", {
|
|
@@ -16368,7 +16372,7 @@ async function pressKey(ctx) {
|
|
|
16368
16372
|
async function clickElement(ctx) {
|
|
16369
16373
|
const { locator, xpath, args, logger } = ctx;
|
|
16370
16374
|
try {
|
|
16371
|
-
await locator.click({ button: args[0] || void 0 });
|
|
16375
|
+
await locator.click({ button: args[0] || void 0 }, ctx.progress);
|
|
16372
16376
|
} catch (e) {
|
|
16373
16377
|
const msg = e instanceof Error ? e.message : String(e);
|
|
16374
16378
|
logger.error("Error performing click", {
|
|
@@ -16382,7 +16386,7 @@ async function clickElement(ctx) {
|
|
|
16382
16386
|
async function doubleClick(ctx) {
|
|
16383
16387
|
const { locator, xpath, logger } = ctx;
|
|
16384
16388
|
try {
|
|
16385
|
-
await locator.click({ clickCount: 2 });
|
|
16389
|
+
await locator.click({ clickCount: 2 }, ctx.progress);
|
|
16386
16390
|
} catch (e) {
|
|
16387
16391
|
const msg = e instanceof Error ? e.message : String(e);
|
|
16388
16392
|
logger.error("Error performing double click", {
|
|
@@ -16397,10 +16401,10 @@ async function dragAndDrop(ctx) {
|
|
|
16397
16401
|
const { page, frame, locator, args, xpath, logger } = ctx;
|
|
16398
16402
|
const toXPath = String(args[0] ?? "").trim();
|
|
16399
16403
|
if (!toXPath) throw new Error("dragAndDrop requires a target XPath arg");
|
|
16400
|
-
const targetLocator = await resolveLocatorWithHops(page, frame, toXPath);
|
|
16404
|
+
const targetLocator = await resolveLocatorWithHops(page, frame, toXPath, ctx.progress);
|
|
16401
16405
|
try {
|
|
16402
|
-
const { x: fromLocalX, y: fromLocalY } = await locator.centroid();
|
|
16403
|
-
const { x: toLocalX, y: toLocalY } = await targetLocator.centroid();
|
|
16406
|
+
const { x: fromLocalX, y: fromLocalY } = await locator.centroid(ctx.progress);
|
|
16407
|
+
const { x: toLocalX, y: toLocalY } = await targetLocator.centroid(ctx.progress);
|
|
16404
16408
|
const fromAbs = await locator.getFrame().evaluate(({ x, y }) => {
|
|
16405
16409
|
let X = x;
|
|
16406
16410
|
let Y = y;
|
|
@@ -16420,7 +16424,7 @@ async function dragAndDrop(ctx) {
|
|
|
16420
16424
|
}, {
|
|
16421
16425
|
x: fromLocalX,
|
|
16422
16426
|
y: fromLocalY
|
|
16423
|
-
});
|
|
16427
|
+
}, ctx.progress);
|
|
16424
16428
|
const toAbs = await targetLocator.getFrame().evaluate(({ x, y }) => {
|
|
16425
16429
|
let X = x;
|
|
16426
16430
|
let Y = y;
|
|
@@ -16440,11 +16444,11 @@ async function dragAndDrop(ctx) {
|
|
|
16440
16444
|
}, {
|
|
16441
16445
|
x: toLocalX,
|
|
16442
16446
|
y: toLocalY
|
|
16443
|
-
});
|
|
16447
|
+
}, ctx.progress);
|
|
16444
16448
|
await page.dragAndDrop(fromAbs.x, fromAbs.y, toAbs.x, toAbs.y, {
|
|
16445
16449
|
steps: 10,
|
|
16446
16450
|
delay: 5
|
|
16447
|
-
});
|
|
16451
|
+
}, ctx.progress);
|
|
16448
16452
|
} catch (e) {
|
|
16449
16453
|
const msg = e instanceof Error ? e.message : String(e);
|
|
16450
16454
|
logger.error("Error performing drag and drop", {
|
|
@@ -16468,9 +16472,10 @@ async function scrollByElementHeight(ctx, direction) {
|
|
|
16468
16472
|
category: "action",
|
|
16469
16473
|
xpath
|
|
16470
16474
|
});
|
|
16471
|
-
const { objectId } = await locator.resolveNode();
|
|
16475
|
+
const { objectId } = await locator.resolveNode(ctx.progress);
|
|
16472
16476
|
try {
|
|
16473
|
-
|
|
16477
|
+
const ownerSession = locator.getFrame().session;
|
|
16478
|
+
await ctx.progress.run("scrolling by element height", () => ownerSession.send("Runtime.callFunctionOn", {
|
|
16474
16479
|
objectId,
|
|
16475
16480
|
functionDeclaration: `
|
|
16476
16481
|
function(dir) {
|
|
@@ -16500,15 +16505,16 @@ async function scrollByElementHeight(ctx, direction) {
|
|
|
16500
16505
|
arguments: [{ value: direction }],
|
|
16501
16506
|
awaitPromise: true,
|
|
16502
16507
|
returnByValue: true
|
|
16503
|
-
});
|
|
16508
|
+
}));
|
|
16504
16509
|
} finally {
|
|
16505
|
-
|
|
16510
|
+
const ownerSession = locator.getFrame().session;
|
|
16511
|
+
await ctx.progress.cleanup(() => ownerSession.send("Runtime.releaseObject", { objectId }));
|
|
16506
16512
|
}
|
|
16507
16513
|
}
|
|
16508
16514
|
async function hover(ctx) {
|
|
16509
16515
|
const { locator, xpath, logger } = ctx;
|
|
16510
16516
|
try {
|
|
16511
|
-
await locator.hover();
|
|
16517
|
+
await locator.hover(ctx.progress);
|
|
16512
16518
|
} catch (e) {
|
|
16513
16519
|
const msg = e instanceof Error ? e.message : String(e);
|
|
16514
16520
|
const stack = e instanceof Error ? e.stack : void 0;
|
|
@@ -16521,31 +16527,31 @@ async function hover(ctx) {
|
|
|
16521
16527
|
throw e;
|
|
16522
16528
|
}
|
|
16523
16529
|
}
|
|
16524
|
-
async function getFrameUrl(frame) {
|
|
16525
|
-
return await frame.evaluate("location.href");
|
|
16526
|
-
}
|
|
16527
16530
|
/**
|
|
16528
16531
|
* More robust DOM settle using Network + Page events to detect network quiet.
|
|
16529
16532
|
* Closely modeled after the provided snippet, adapted to our Frame/session + logger.
|
|
16530
16533
|
*/
|
|
16531
|
-
async function waitForDomNetworkQuiet(frame, logger, timeout) {
|
|
16534
|
+
async function waitForDomNetworkQuiet(frame, logger, timeout, progress) {
|
|
16532
16535
|
const overallTimeout = typeof timeout === "number" && Number.isFinite(timeout) ? Math.max(0, timeout) : 5e3;
|
|
16533
16536
|
const client = frame.session;
|
|
16534
16537
|
const settleStart = Date.now();
|
|
16535
16538
|
let hasDoc;
|
|
16536
16539
|
try {
|
|
16537
|
-
const rs = await frame.evaluate("document.readyState");
|
|
16540
|
+
const rs = await progress.run("checking document readiness", () => frame.evaluate("document.readyState", void 0, progress));
|
|
16538
16541
|
hasDoc = rs === "interactive" || rs === "complete";
|
|
16539
16542
|
} catch {
|
|
16543
|
+
progress.throwIfStopped();
|
|
16540
16544
|
hasDoc = false;
|
|
16541
16545
|
}
|
|
16542
|
-
if (!hasDoc && overallTimeout > 0) await frame.waitForLoadState("domcontentloaded", overallTimeout).catch(() => {
|
|
16546
|
+
if (!hasDoc && overallTimeout > 0) await frame.waitForLoadState("domcontentloaded", overallTimeout, progress).catch(() => {
|
|
16547
|
+
progress.throwIfStopped();
|
|
16548
|
+
});
|
|
16543
16549
|
const elapsed = Date.now() - settleStart;
|
|
16544
16550
|
const remainingBudget = Math.max(0, overallTimeout - elapsed);
|
|
16545
16551
|
if (remainingBudget === 0) return;
|
|
16546
|
-
await client.send("Network.enable").catch(() => {});
|
|
16547
|
-
await client.send("Page.enable").catch(() => {});
|
|
16548
|
-
await client.send("Target.setAutoAttach", {
|
|
16552
|
+
await progress.run("enabling network events", () => client.send("Network.enable").catch(() => {}));
|
|
16553
|
+
await progress.run("enabling page events", () => client.send("Page.enable").catch(() => {}));
|
|
16554
|
+
await progress.run("attaching to frames", () => client.send("Target.setAutoAttach", {
|
|
16549
16555
|
autoAttach: true,
|
|
16550
16556
|
waitForDebuggerOnStart: false,
|
|
16551
16557
|
flatten: true,
|
|
@@ -16556,8 +16562,9 @@ async function waitForDomNetworkQuiet(frame, logger, timeout) {
|
|
|
16556
16562
|
type: "shared_worker",
|
|
16557
16563
|
exclude: true
|
|
16558
16564
|
}]
|
|
16559
|
-
}).catch(() => {});
|
|
16560
|
-
|
|
16565
|
+
}).catch(() => {}));
|
|
16566
|
+
progress.throwIfStopped();
|
|
16567
|
+
await new Promise((resolve) => {
|
|
16561
16568
|
const inflight = /* @__PURE__ */ new Set();
|
|
16562
16569
|
const meta = /* @__PURE__ */ new Map();
|
|
16563
16570
|
const docByFrame = /* @__PURE__ */ new Map();
|
|
@@ -16634,18 +16641,12 @@ async function waitForDomNetworkQuiet(frame, logger, timeout) {
|
|
|
16634
16641
|
if (quietTimer) clearTimeout(quietTimer);
|
|
16635
16642
|
if (stalledRequestSweepTimer) clearInterval(stalledRequestSweepTimer);
|
|
16636
16643
|
clearTimeout(guard);
|
|
16644
|
+
progress.signal.removeEventListener("abort", resolveDone);
|
|
16637
16645
|
resolve();
|
|
16638
16646
|
};
|
|
16647
|
+
progress.signal.addEventListener("abort", resolveDone, { once: true });
|
|
16639
16648
|
});
|
|
16640
|
-
|
|
16641
|
-
//#endregion
|
|
16642
|
-
//#region handlers/handlerUtils/timeoutGuard.ts
|
|
16643
|
-
function createTimeoutGuard(timeout, errorFactory) {
|
|
16644
|
-
if (!timeout || timeout <= 0) return () => {};
|
|
16645
|
-
const startTime = Date.now();
|
|
16646
|
-
return () => {
|
|
16647
|
-
if (Date.now() - startTime >= timeout) throw errorFactory?.(timeout) ?? new TimeoutError("operation", timeout);
|
|
16648
|
-
};
|
|
16649
|
+
progress.throwIfStopped();
|
|
16649
16650
|
}
|
|
16650
16651
|
//#endregion
|
|
16651
16652
|
//#region handlers/handlerUtils/variables.ts
|
|
@@ -16958,7 +16959,7 @@ function base64ToBytes$1(base64) {
|
|
|
16958
16959
|
* owning session for `this.frameId`. Page is responsible for constructing
|
|
16959
16960
|
* Frames with the correct session.
|
|
16960
16961
|
*/
|
|
16961
|
-
var Frame = class
|
|
16962
|
+
var Frame = class {
|
|
16962
16963
|
constructor(session, frameId, pageId, remoteBrowser, logger) {
|
|
16963
16964
|
this.session = session;
|
|
16964
16965
|
this.frameId = frameId;
|
|
@@ -16999,22 +17000,17 @@ var Frame = class Frame {
|
|
|
16999
17000
|
height: model.height
|
|
17000
17001
|
};
|
|
17001
17002
|
}
|
|
17002
|
-
/**
|
|
17003
|
-
async getAccessibilityTree(
|
|
17004
|
-
await this.session.send("Accessibility.enable");
|
|
17003
|
+
/** Read this frame's accessibility tree. */
|
|
17004
|
+
async getAccessibilityTree(progress) {
|
|
17005
|
+
await runLocatorStep(progress, "enabling accessibility", () => this.session.send("Accessibility.enable"));
|
|
17005
17006
|
let nodes;
|
|
17006
17007
|
try {
|
|
17007
|
-
({nodes} = await this.session.send("Accessibility.getFullAXTree", { frameId: this.frameId }));
|
|
17008
|
+
({nodes} = await runLocatorStep(progress, "reading accessibility tree", () => this.session.send("Accessibility.getFullAXTree", { frameId: this.frameId })));
|
|
17008
17009
|
} catch (e) {
|
|
17010
|
+
progress?.throwIfStopped();
|
|
17009
17011
|
const msg = String(e?.message ?? e ?? "");
|
|
17010
17012
|
if (!(msg.includes("Frame with the given") || msg.includes("does not belong to the target") || msg.includes("is not found"))) throw e;
|
|
17011
|
-
({nodes} = await this.session.send("Accessibility.getFullAXTree"));
|
|
17012
|
-
}
|
|
17013
|
-
if (!withFrames) return nodes;
|
|
17014
|
-
const children = await this.childFrames();
|
|
17015
|
-
for (const child of children) {
|
|
17016
|
-
const childNodes = await child.getAccessibilityTree(false);
|
|
17017
|
-
nodes.push(...childNodes);
|
|
17013
|
+
({nodes} = await runLocatorStep(progress, "reading accessibility tree", () => this.session.send("Accessibility.getFullAXTree")));
|
|
17018
17014
|
}
|
|
17019
17015
|
return nodes;
|
|
17020
17016
|
}
|
|
@@ -17125,22 +17121,12 @@ var Frame = class Frame {
|
|
|
17125
17121
|
progress.throwIfStopped();
|
|
17126
17122
|
return base64ToBytes$1(data);
|
|
17127
17123
|
}
|
|
17128
|
-
/** Child frames via Page.getFrameTree */
|
|
17129
|
-
async childFrames() {
|
|
17130
|
-
const { frameTree } = await this.session.send("Page.getFrameTree");
|
|
17131
|
-
const frames = [];
|
|
17132
|
-
const collect = (tree) => {
|
|
17133
|
-
if (tree.frame.parentId === this.frameId) frames.push(new Frame(this.session, tree.frame.id, this.pageId, this.remoteBrowser, this.logger));
|
|
17134
|
-
tree.childFrames?.forEach(collect);
|
|
17135
|
-
};
|
|
17136
|
-
collect(frameTree);
|
|
17137
|
-
return frames;
|
|
17138
|
-
}
|
|
17139
17124
|
/** Wait for a lifecycle state (load/domcontentloaded/networkidle) */
|
|
17140
|
-
async waitForLoadState(state = "load", timeout = 15e3) {
|
|
17141
|
-
await this.session.send("Page.enable");
|
|
17125
|
+
async waitForLoadState(state = "load", timeout = 15e3, progress) {
|
|
17126
|
+
await runLocatorStep(progress, "enabling load events", () => this.session.send("Page.enable"));
|
|
17142
17127
|
const targetState = state.toLowerCase();
|
|
17143
17128
|
const effectiveTimeout = Math.max(0, timeout);
|
|
17129
|
+
progress?.throwIfStopped();
|
|
17144
17130
|
await new Promise((resolve, reject) => {
|
|
17145
17131
|
let done = false;
|
|
17146
17132
|
let timer = null;
|
|
@@ -17148,6 +17134,7 @@ var Frame = class Frame {
|
|
|
17148
17134
|
if (done) return;
|
|
17149
17135
|
done = true;
|
|
17150
17136
|
this.session.off("Page.lifecycleEvent", handler);
|
|
17137
|
+
progress?.signal.removeEventListener("abort", finish);
|
|
17151
17138
|
if (timer) {
|
|
17152
17139
|
clearTimeout(timer);
|
|
17153
17140
|
timer = null;
|
|
@@ -17160,13 +17147,16 @@ var Frame = class Frame {
|
|
|
17160
17147
|
if (sameFrame && lifecycleName === targetState) finish();
|
|
17161
17148
|
};
|
|
17162
17149
|
this.session.on("Page.lifecycleEvent", handler);
|
|
17150
|
+
progress?.signal.addEventListener("abort", finish, { once: true });
|
|
17163
17151
|
timer = setTimeout(() => {
|
|
17164
17152
|
if (done) return;
|
|
17165
17153
|
done = true;
|
|
17166
17154
|
this.session.off("Page.lifecycleEvent", handler);
|
|
17155
|
+
progress?.signal.removeEventListener("abort", finish);
|
|
17167
17156
|
reject(/* @__PURE__ */ new Error(`waitForLoadState(${state}) timed out after ${effectiveTimeout}ms for frame ${this.frameId}`));
|
|
17168
17157
|
}, effectiveTimeout);
|
|
17169
17158
|
});
|
|
17159
|
+
progress?.throwIfStopped();
|
|
17170
17160
|
}
|
|
17171
17161
|
/** Simple placeholder for your own locator abstraction */
|
|
17172
17162
|
locator(selector, options) {
|
|
@@ -18597,11 +18587,12 @@ function missMetadata(response, reason) {
|
|
|
18597
18587
|
* or whenever any cache step fails, including `onHit` itself — falls back to
|
|
18598
18588
|
* `execute` and then persists the outcome's `cacheValue`.
|
|
18599
18589
|
*/
|
|
18600
|
-
async function withCache({ method, page, data, caching, bypass, context, logger, onHit, execute }) {
|
|
18590
|
+
async function withCache({ method, page, data, caching, bypass, context, logger, onHit, execute, progress }) {
|
|
18591
|
+
progress?.throwIfStopped();
|
|
18601
18592
|
const resolvedCaching = caching ?? context?.defaultCaching ?? true;
|
|
18602
18593
|
const cachePage = resolvedCaching !== false ? asCachePage(page) : null;
|
|
18603
18594
|
if (bypass || !context || !cachePage) return (await execute()).result;
|
|
18604
|
-
const cdpTree = await collectCdpTree(cachePage, logger);
|
|
18595
|
+
const cdpTree = await collectCdpTree(cachePage, logger, progress);
|
|
18605
18596
|
if (!cdpTree) return (await execute()).result;
|
|
18606
18597
|
const baseRequest = {
|
|
18607
18598
|
method,
|
|
@@ -18612,8 +18603,9 @@ async function withCache({ method, page, data, caching, bypass, context, logger,
|
|
|
18612
18603
|
};
|
|
18613
18604
|
let getResponse = null;
|
|
18614
18605
|
try {
|
|
18615
|
-
getResponse = await context.client.get(baseRequest);
|
|
18606
|
+
getResponse = await runLocatorStep(progress, "reading cache", () => context.client.get(baseRequest));
|
|
18616
18607
|
} catch (error) {
|
|
18608
|
+
progress?.throwIfStopped();
|
|
18617
18609
|
logger.warn("Cache read failed; executing without cache", {
|
|
18618
18610
|
category: "cache",
|
|
18619
18611
|
method,
|
|
@@ -18622,7 +18614,7 @@ async function withCache({ method, page, data, caching, bypass, context, logger,
|
|
|
18622
18614
|
}
|
|
18623
18615
|
let cacheMetadata;
|
|
18624
18616
|
if (getResponse?.hit && getResponse.value !== void 0 && getResponse.value !== null) try {
|
|
18625
|
-
const result = await onHit(getResponse.value);
|
|
18617
|
+
const result = await runLocatorStep(progress, "applying cached result", async () => onHit(getResponse.value));
|
|
18626
18618
|
result.metadata.cache = hitMetadata(getResponse);
|
|
18627
18619
|
logger.debug("Cache hit", {
|
|
18628
18620
|
category: "cache",
|
|
@@ -18633,6 +18625,7 @@ async function withCache({ method, page, data, caching, bypass, context, logger,
|
|
|
18633
18625
|
});
|
|
18634
18626
|
return result;
|
|
18635
18627
|
} catch (error) {
|
|
18628
|
+
progress?.throwIfStopped();
|
|
18636
18629
|
logger.warn("Cached value could not be applied; falling back to execution", {
|
|
18637
18630
|
category: "cache",
|
|
18638
18631
|
method,
|
|
@@ -18650,14 +18643,16 @@ async function withCache({ method, page, data, caching, bypass, context, logger,
|
|
|
18650
18643
|
missReason: cacheMetadata.missReason ?? "unknown"
|
|
18651
18644
|
});
|
|
18652
18645
|
} else cacheMetadata = missMetadata(null, "read_failed");
|
|
18646
|
+
progress?.throwIfStopped();
|
|
18653
18647
|
const outcome = await execute();
|
|
18648
|
+
progress?.throwIfStopped();
|
|
18654
18649
|
outcome.result.metadata.cache = cacheMetadata;
|
|
18655
18650
|
if (outcome.cacheValue !== void 0 && outcome.cacheValue !== null) try {
|
|
18656
|
-
const setResponse = await context.client.set({
|
|
18651
|
+
const setResponse = await runLocatorStep(progress, "writing cache", () => context.client.set({
|
|
18657
18652
|
...baseRequest,
|
|
18658
18653
|
value: outcome.cacheValue,
|
|
18659
18654
|
llmUsage: outcome.llmUsage
|
|
18660
|
-
});
|
|
18655
|
+
}));
|
|
18661
18656
|
logger.debug(setResponse.written ? "Cache write completed" : "Cache write skipped", {
|
|
18662
18657
|
category: "cache",
|
|
18663
18658
|
method,
|
|
@@ -18665,6 +18660,7 @@ async function withCache({ method, page, data, caching, bypass, context, logger,
|
|
|
18665
18660
|
skippedReason: setResponse.skippedReason ?? ""
|
|
18666
18661
|
});
|
|
18667
18662
|
} catch (error) {
|
|
18663
|
+
progress?.throwIfStopped();
|
|
18668
18664
|
logger.warn("Cache write failed", {
|
|
18669
18665
|
category: "cache",
|
|
18670
18666
|
method,
|
|
@@ -18699,19 +18695,20 @@ function asCachePage(page) {
|
|
|
18699
18695
|
* Collects the verbatim Accessibility.getFullAXTree nodes for every frame.
|
|
18700
18696
|
* Returns null (skip caching) when the payload can't be assembled.
|
|
18701
18697
|
*/
|
|
18702
|
-
async function collectCdpTree(page, logger) {
|
|
18698
|
+
async function collectCdpTree(page, logger, progress) {
|
|
18703
18699
|
try {
|
|
18704
18700
|
const mainFrame = page.mainFrame();
|
|
18705
18701
|
const frames = [];
|
|
18706
18702
|
for (const frame of page.frames()) frames.push({
|
|
18707
18703
|
frameId: frame.frameId,
|
|
18708
|
-
axNodes: await frame.getAccessibilityTree(
|
|
18704
|
+
axNodes: await runLocatorStep(progress, "reading cache accessibility tree", () => frame.getAccessibilityTree(progress))
|
|
18709
18705
|
});
|
|
18710
18706
|
return {
|
|
18711
18707
|
rootFrameId: mainFrame.frameId,
|
|
18712
18708
|
frames
|
|
18713
18709
|
};
|
|
18714
18710
|
} catch (error) {
|
|
18711
|
+
progress?.throwIfStopped();
|
|
18715
18712
|
logger.warn("Failed to collect CDP tree for cache; executing without cache", {
|
|
18716
18713
|
category: "cache",
|
|
18717
18714
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -51231,11 +51228,15 @@ function disabledCacheMetadata() {
|
|
|
51231
51228
|
}
|
|
51232
51229
|
//#endregion
|
|
51233
51230
|
//#region services/actService.ts
|
|
51234
|
-
async function act(
|
|
51231
|
+
async function act(options) {
|
|
51232
|
+
return runWithProgress(options.progress ?? {
|
|
51233
|
+
name: "act()",
|
|
51234
|
+
timeout: options.params.options?.timeout ?? 0
|
|
51235
|
+
}, (progress) => actWithProgress(options, progress));
|
|
51236
|
+
}
|
|
51237
|
+
async function actWithProgress({ params, page, model, clientLLMGenerate, logger, systemPrompt = "", selfHeal = false, domSettleTimeoutMs, cache, gateway }, progress) {
|
|
51235
51238
|
const { instruction: actInstruction, options } = params;
|
|
51236
51239
|
const variables = options?.variables;
|
|
51237
|
-
const timeout = options?.timeout;
|
|
51238
|
-
const ensureTimeRemaining = createTimeoutGuard(timeout, (ms) => new TimeoutError("act()", ms));
|
|
51239
51240
|
let operationUsage = zeroStagehandResultUsage();
|
|
51240
51241
|
const recordUsage = (response) => {
|
|
51241
51242
|
operationUsage = aggregateUsage(operationUsage, usageFromInference(response));
|
|
@@ -51248,11 +51249,11 @@ async function act({ params, page, model, clientLLMGenerate, logger, systemPromp
|
|
|
51248
51249
|
systemPrompt,
|
|
51249
51250
|
selfHeal,
|
|
51250
51251
|
domSettleTimeoutMs,
|
|
51251
|
-
|
|
51252
|
+
progress,
|
|
51252
51253
|
gateway,
|
|
51253
51254
|
recordUsage
|
|
51254
51255
|
};
|
|
51255
|
-
|
|
51256
|
+
progress.throwIfStopped();
|
|
51256
51257
|
if (typeof actInstruction !== "string") return actResult(await takeDeterministicAction({
|
|
51257
51258
|
action: actInstruction,
|
|
51258
51259
|
variables,
|
|
@@ -51263,8 +51264,8 @@ async function act({ params, page, model, clientLLMGenerate, logger, systemPromp
|
|
|
51263
51264
|
focusLocator: options?.locator,
|
|
51264
51265
|
ignoreLocators: options?.ignoreLocators
|
|
51265
51266
|
};
|
|
51266
|
-
await waitForDomNetworkQuiet(page.mainFrame(), logger, domSettleTimeoutMs);
|
|
51267
|
-
|
|
51267
|
+
await waitForDomNetworkQuiet(page.mainFrame(), logger, domSettleTimeoutMs, progress);
|
|
51268
|
+
progress.throwIfStopped();
|
|
51268
51269
|
return await withCache({
|
|
51269
51270
|
method: "act",
|
|
51270
51271
|
page,
|
|
@@ -51273,6 +51274,7 @@ async function act({ params, page, model, clientLLMGenerate, logger, systemPromp
|
|
|
51273
51274
|
bypass: shouldBypassCacheForLocatorScope(options),
|
|
51274
51275
|
context: cache,
|
|
51275
51276
|
logger,
|
|
51277
|
+
progress,
|
|
51276
51278
|
onHit: (value) => replayCachedActions(value, instruction, variables, context),
|
|
51277
51279
|
execute: async () => {
|
|
51278
51280
|
const result = await runActPipeline();
|
|
@@ -51289,9 +51291,9 @@ async function act({ params, page, model, clientLLMGenerate, logger, systemPromp
|
|
|
51289
51291
|
}
|
|
51290
51292
|
});
|
|
51291
51293
|
async function runActPipeline() {
|
|
51292
|
-
const { combinedTree, combinedXpathMap } = await page.captureSnapshot(snapshotOptions);
|
|
51294
|
+
const { combinedTree, combinedXpathMap } = await page.captureSnapshot(snapshotOptions, progress);
|
|
51293
51295
|
const actPrompt = buildActPrompt(instruction, Object.values(SupportedUnderstudyAction), variables);
|
|
51294
|
-
|
|
51296
|
+
progress.throwIfStopped();
|
|
51295
51297
|
const firstInference = await getActionFromLLM({
|
|
51296
51298
|
instruction: actPrompt,
|
|
51297
51299
|
domElements: combinedTree,
|
|
@@ -51307,18 +51309,18 @@ async function act({ params, page, model, clientLLMGenerate, logger, systemPromp
|
|
|
51307
51309
|
actions: []
|
|
51308
51310
|
}, operationUsage);
|
|
51309
51311
|
}
|
|
51310
|
-
|
|
51312
|
+
progress.throwIfStopped();
|
|
51311
51313
|
const firstResult = await takeDeterministicAction({
|
|
51312
51314
|
action: firstInference.action,
|
|
51313
51315
|
variables,
|
|
51314
51316
|
context
|
|
51315
51317
|
});
|
|
51316
51318
|
if (!firstInference.response.twoStep) return actResult(firstResult, operationUsage);
|
|
51317
|
-
|
|
51318
|
-
const { combinedTree: nextTree, combinedXpathMap: nextXpathMap } = await page.captureSnapshot(snapshotOptions);
|
|
51319
|
+
progress.throwIfStopped();
|
|
51320
|
+
const { combinedTree: nextTree, combinedXpathMap: nextXpathMap } = await page.captureSnapshot(snapshotOptions, progress);
|
|
51319
51321
|
const changedTree = diffCombinedTrees(combinedTree, nextTree);
|
|
51320
51322
|
const secondInstruction = buildStepTwoPrompt(instruction, describeAction(firstInference.action), Object.values(SupportedUnderstudyAction).filter((action) => action !== SupportedUnderstudyAction.SELECT_OPTION_FROM_DROPDOWN), variables);
|
|
51321
|
-
|
|
51323
|
+
progress.throwIfStopped();
|
|
51322
51324
|
const secondInference = await getActionFromLLM({
|
|
51323
51325
|
instruction: secondInstruction,
|
|
51324
51326
|
domElements: changedTree.trim() ? changedTree : nextTree,
|
|
@@ -51326,7 +51328,7 @@ async function act({ params, page, model, clientLLMGenerate, logger, systemPromp
|
|
|
51326
51328
|
context
|
|
51327
51329
|
});
|
|
51328
51330
|
if (!secondInference.action) return actResult(firstResult, operationUsage);
|
|
51329
|
-
|
|
51331
|
+
progress.throwIfStopped();
|
|
51330
51332
|
const secondResult = await takeDeterministicAction({
|
|
51331
51333
|
action: secondInference.action,
|
|
51332
51334
|
variables,
|
|
@@ -51369,12 +51371,15 @@ async function replayCachedActions(value, instruction, variables, context) {
|
|
|
51369
51371
|
});
|
|
51370
51372
|
}
|
|
51371
51373
|
async function getActionFromLLM({ instruction, domElements, xpathMap, context }) {
|
|
51372
|
-
const response = await act$1({
|
|
51374
|
+
const response = await context.progress.run("waiting for act inference", () => act$1({
|
|
51373
51375
|
instruction,
|
|
51374
51376
|
domElements,
|
|
51375
|
-
generate: (input) =>
|
|
51377
|
+
generate: (input) => {
|
|
51378
|
+
context.progress.throwIfStopped();
|
|
51379
|
+
return generate(context.model, input, context.clientLLMGenerate, context.gateway);
|
|
51380
|
+
},
|
|
51376
51381
|
userProvidedInstructions: context.systemPrompt
|
|
51377
|
-
});
|
|
51382
|
+
}));
|
|
51378
51383
|
context.recordUsage(response);
|
|
51379
51384
|
context.logger.info("Act inference completed", {
|
|
51380
51385
|
category: "action",
|
|
@@ -51391,7 +51396,7 @@ async function getActionFromLLM({ instruction, domElements, xpathMap, context })
|
|
|
51391
51396
|
} : { response };
|
|
51392
51397
|
}
|
|
51393
51398
|
async function takeDeterministicAction({ action, variables, context }) {
|
|
51394
|
-
context.
|
|
51399
|
+
context.progress.throwIfStopped();
|
|
51395
51400
|
const method = action.method?.trim();
|
|
51396
51401
|
if (!method || method === "not-supported") {
|
|
51397
51402
|
context.logger.error("Action has no supported method", {
|
|
@@ -51408,10 +51413,11 @@ async function takeDeterministicAction({ action, variables, context }) {
|
|
|
51408
51413
|
const placeholderArgs = Array.isArray(action.arguments) ? [...action.arguments] : [];
|
|
51409
51414
|
const resolvedArgs = substituteVariablesInArguments(action.arguments, variables) ?? [];
|
|
51410
51415
|
try {
|
|
51411
|
-
context.
|
|
51412
|
-
await performUnderstudyMethod(context.page, context.page.mainFrame(), method, action.selector, resolvedArgs, context.logger, context.domSettleTimeoutMs);
|
|
51416
|
+
context.progress.throwIfStopped();
|
|
51417
|
+
await performUnderstudyMethod(context.page, context.page.mainFrame(), method, action.selector, resolvedArgs, context.logger, context.progress, context.domSettleTimeoutMs);
|
|
51413
51418
|
return successfulActionResult(action, method, action.selector, placeholderArgs);
|
|
51414
51419
|
} catch (error) {
|
|
51420
|
+
context.progress.throwIfStopped();
|
|
51415
51421
|
if (error instanceof TimeoutError) throw error;
|
|
51416
51422
|
const message = error instanceof Error ? error.message : String(error);
|
|
51417
51423
|
if (!context.selfHeal) return {
|
|
@@ -51437,8 +51443,8 @@ async function takeDeterministicAction({ action, variables, context }) {
|
|
|
51437
51443
|
async function selfHealAction({ action, method, resolvedArgs, placeholderArgs, context }) {
|
|
51438
51444
|
const actionInstruction = action.description ? action.description.toLowerCase().startsWith(method.toLowerCase()) ? action.description : `${method} ${action.description}` : method;
|
|
51439
51445
|
try {
|
|
51440
|
-
context.
|
|
51441
|
-
const { combinedTree, combinedXpathMap } = await context.page.captureSnapshot({});
|
|
51446
|
+
context.progress.throwIfStopped();
|
|
51447
|
+
const { combinedTree, combinedXpathMap } = await context.page.captureSnapshot({}, context.progress);
|
|
51442
51448
|
const inferenceResult = await getActionFromLLM({
|
|
51443
51449
|
instruction: buildActPrompt(actionInstruction, Object.values(SupportedUnderstudyAction), {}),
|
|
51444
51450
|
domElements: combinedTree,
|
|
@@ -51452,10 +51458,11 @@ async function selfHealAction({ action, method, resolvedArgs, placeholderArgs, c
|
|
|
51452
51458
|
actions: []
|
|
51453
51459
|
};
|
|
51454
51460
|
const selector = inferenceResult.action?.selector ?? action.selector;
|
|
51455
|
-
context.
|
|
51456
|
-
await performUnderstudyMethod(context.page, context.page.mainFrame(), method, selector, resolvedArgs, context.logger, context.domSettleTimeoutMs);
|
|
51461
|
+
context.progress.throwIfStopped();
|
|
51462
|
+
await performUnderstudyMethod(context.page, context.page.mainFrame(), method, selector, resolvedArgs, context.logger, context.progress, context.domSettleTimeoutMs);
|
|
51457
51463
|
return successfulActionResult(action, method, selector, placeholderArgs);
|
|
51458
51464
|
} catch (error) {
|
|
51465
|
+
context.progress.throwIfStopped();
|
|
51459
51466
|
if (error instanceof TimeoutError) throw error;
|
|
51460
51467
|
return {
|
|
51461
51468
|
success: false,
|
|
@@ -51555,9 +51562,14 @@ function transformUrlStringsToNumericIds(schema) {
|
|
|
51555
51562
|
const [finalSchema, urlPaths] = transformSchema(schema, []);
|
|
51556
51563
|
return [finalSchema, urlPaths];
|
|
51557
51564
|
}
|
|
51558
|
-
async function extract(
|
|
51565
|
+
async function extract(options) {
|
|
51566
|
+
return runWithProgress(options.progress ?? {
|
|
51567
|
+
name: "extract()",
|
|
51568
|
+
timeout: options.params.options?.timeout ?? 0
|
|
51569
|
+
}, (progress) => extractWithProgress(options, progress));
|
|
51570
|
+
}
|
|
51571
|
+
async function extractWithProgress({ params, page, model, clientLLMGenerate, logger, systemPrompt = "", cache, gateway }, progress) {
|
|
51559
51572
|
const { instruction, options } = params;
|
|
51560
|
-
const ensureTimeRemaining = createTimeoutGuard(options?.timeout, (ms) => new TimeoutError("extract()", ms));
|
|
51561
51573
|
if (options?.screenshot) return (await runExtraction()).result;
|
|
51562
51574
|
return await withCache({
|
|
51563
51575
|
method: "extract",
|
|
@@ -51567,6 +51579,7 @@ async function extract({ params, page, model, clientLLMGenerate, logger, systemP
|
|
|
51567
51579
|
bypass: shouldBypassCacheForLocatorScope(options),
|
|
51568
51580
|
context: cache,
|
|
51569
51581
|
logger,
|
|
51582
|
+
progress,
|
|
51570
51583
|
onHit: (value) => ({
|
|
51571
51584
|
data: json$1().parse(value),
|
|
51572
51585
|
metadata: {
|
|
@@ -51577,21 +51590,17 @@ async function extract({ params, page, model, clientLLMGenerate, logger, systemP
|
|
|
51577
51590
|
execute: () => runExtraction()
|
|
51578
51591
|
});
|
|
51579
51592
|
async function runExtraction() {
|
|
51580
|
-
|
|
51593
|
+
progress.throwIfStopped();
|
|
51581
51594
|
const { combinedTree, combinedUrlMap } = await page.captureSnapshot({
|
|
51582
51595
|
focusLocator: options?.locator,
|
|
51583
51596
|
ignoreLocators: options?.ignoreLocators
|
|
51584
|
-
});
|
|
51585
|
-
|
|
51586
|
-
const screenshot = options?.screenshot ? await (
|
|
51587
|
-
|
|
51588
|
-
|
|
51589
|
-
|
|
51590
|
-
|
|
51591
|
-
});
|
|
51592
|
-
ensureTimeRemaining();
|
|
51593
|
-
return image;
|
|
51594
|
-
})() : void 0;
|
|
51597
|
+
}, progress);
|
|
51598
|
+
progress.throwIfStopped();
|
|
51599
|
+
const screenshot = options?.screenshot ? await page.screenshot({
|
|
51600
|
+
fullPage: false,
|
|
51601
|
+
type: "png"
|
|
51602
|
+
}, progress) : void 0;
|
|
51603
|
+
progress.throwIfStopped();
|
|
51595
51604
|
logger.info(screenshot ? "Starting extraction using an accessibility snapshot and viewport screenshot" : "Starting extraction using an accessibility snapshot", {
|
|
51596
51605
|
category: "extraction",
|
|
51597
51606
|
instruction
|
|
@@ -51605,16 +51614,16 @@ async function extract({ params, page, model, clientLLMGenerate, logger, systemP
|
|
|
51605
51614
|
data: bytesToBase64(screenshot),
|
|
51606
51615
|
mimeType: "image/png"
|
|
51607
51616
|
} : void 0;
|
|
51608
|
-
|
|
51617
|
+
progress.throwIfStopped();
|
|
51609
51618
|
const extractionResponse = await extract$1({
|
|
51610
51619
|
instruction,
|
|
51611
51620
|
domElements: combinedTree,
|
|
51612
51621
|
schema: transformedSchema,
|
|
51613
|
-
generate: (input) => generate(model, input, clientLLMGenerate, gateway),
|
|
51622
|
+
generate: (input) => progress.run("waiting for extract inference", () => generate(model, input, clientLLMGenerate, gateway)),
|
|
51614
51623
|
userProvidedInstructions: systemPrompt,
|
|
51615
51624
|
screenshot: screenshotContent
|
|
51616
51625
|
});
|
|
51617
|
-
|
|
51626
|
+
progress.throwIfStopped();
|
|
51618
51627
|
const { metadata: { completed }, prompt_tokens, completion_tokens, reasoning_tokens, cached_input_tokens, inference_time_ms, ...rest } = extractionResponse;
|
|
51619
51628
|
let output = rest;
|
|
51620
51629
|
const idToUrl = combinedUrlMap ?? {};
|
|
@@ -51652,9 +51661,14 @@ async function extract({ params, page, model, clientLLMGenerate, logger, systemP
|
|
|
51652
51661
|
//#endregion
|
|
51653
51662
|
//#region services/observeService.ts
|
|
51654
51663
|
var DEFAULT_OBSERVE_INSTRUCTION = "Find elements that can be used for any future actions in the page. These may be navigation links, related pages, section/subsection links, buttons, or other interactive elements. Be comprehensive: if there are multiple elements that may be relevant for future actions, return all of them.";
|
|
51655
|
-
async function observe(
|
|
51664
|
+
async function observe(options) {
|
|
51665
|
+
return runWithProgress(options.progress ?? {
|
|
51666
|
+
name: "observe()",
|
|
51667
|
+
timeout: options.params.options?.timeout ?? 0
|
|
51668
|
+
}, (progress) => observeWithProgress(options, progress));
|
|
51669
|
+
}
|
|
51670
|
+
async function observeWithProgress({ params, page, model, clientLLMGenerate, logger, systemPrompt = "", cache, gateway }, progress) {
|
|
51656
51671
|
const { instruction, options } = params;
|
|
51657
|
-
const ensureTimeRemaining = createTimeoutGuard(options?.timeout, (ms) => new TimeoutError("observe()", ms));
|
|
51658
51672
|
const effectiveInstruction = instruction ?? DEFAULT_OBSERVE_INSTRUCTION;
|
|
51659
51673
|
logger.info("Starting observation", {
|
|
51660
51674
|
category: "observation",
|
|
@@ -51668,6 +51682,7 @@ async function observe({ params, page, model, clientLLMGenerate, logger, systemP
|
|
|
51668
51682
|
bypass: shouldBypassCacheForLocatorScope(options),
|
|
51669
51683
|
context: cache,
|
|
51670
51684
|
logger,
|
|
51685
|
+
progress,
|
|
51671
51686
|
onHit: (value) => {
|
|
51672
51687
|
const actions = normalizeCachedActions(value);
|
|
51673
51688
|
if (actions.length === 0) throw new Error("Cached observe value contained no usable actions");
|
|
@@ -51682,22 +51697,22 @@ async function observe({ params, page, model, clientLLMGenerate, logger, systemP
|
|
|
51682
51697
|
execute: () => runObservation()
|
|
51683
51698
|
});
|
|
51684
51699
|
async function runObservation() {
|
|
51685
|
-
|
|
51700
|
+
progress.throwIfStopped();
|
|
51686
51701
|
const { combinedTree, combinedXpathMap } = await page.captureSnapshot({
|
|
51687
51702
|
focusLocator: options?.locator,
|
|
51688
51703
|
ignoreLocators: options?.ignoreLocators
|
|
51689
|
-
});
|
|
51690
|
-
|
|
51704
|
+
}, progress);
|
|
51705
|
+
progress.throwIfStopped();
|
|
51691
51706
|
logger.debug("Captured accessibility snapshot for observation", { category: "observation" });
|
|
51692
51707
|
const observation = await observe$1({
|
|
51693
51708
|
instruction: effectiveInstruction,
|
|
51694
51709
|
domElements: combinedTree,
|
|
51695
|
-
generate: (input) => generate(model, input, clientLLMGenerate, gateway),
|
|
51710
|
+
generate: (input) => progress.run("waiting for observe inference", () => generate(model, input, clientLLMGenerate, gateway)),
|
|
51696
51711
|
userProvidedInstructions: systemPrompt,
|
|
51697
51712
|
supportedActions: Object.values(SupportedUnderstudyAction),
|
|
51698
51713
|
variables: options?.variables
|
|
51699
51714
|
});
|
|
51700
|
-
|
|
51715
|
+
progress.throwIfStopped();
|
|
51701
51716
|
const xpathMap = combinedXpathMap ?? {};
|
|
51702
51717
|
const actions = [];
|
|
51703
51718
|
for (const element of observation.elements) {
|
|
@@ -51738,7 +51753,7 @@ async function observe({ params, page, model, clientLLMGenerate, logger, systemP
|
|
|
51738
51753
|
arguments: resolvedArguments
|
|
51739
51754
|
});
|
|
51740
51755
|
}
|
|
51741
|
-
|
|
51756
|
+
progress.throwIfStopped();
|
|
51742
51757
|
logger.info("Observation completed", {
|
|
51743
51758
|
category: "observation",
|
|
51744
51759
|
promptTokens: observation.prompt_tokens,
|
|
@@ -54370,7 +54385,7 @@ var WebTracerProvider = class extends BasicTracerProvider {
|
|
|
54370
54385
|
};
|
|
54371
54386
|
var package_default = {
|
|
54372
54387
|
name: "@browserbasehq/stagehand-extension",
|
|
54373
|
-
version: "1.1.0-alpha-
|
|
54388
|
+
version: "1.1.0-alpha-c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a",
|
|
54374
54389
|
"private": true,
|
|
54375
54390
|
type: "module",
|
|
54376
54391
|
scripts: {
|
|
@@ -56316,11 +56331,13 @@ var Page = class Page {
|
|
|
56316
56331
|
await this.ensureCursorScript();
|
|
56317
56332
|
this.cursorEnabled = true;
|
|
56318
56333
|
}
|
|
56319
|
-
async updateCursor(x, y) {
|
|
56334
|
+
async updateCursor(x, y, progress) {
|
|
56320
56335
|
if (!this.cursorEnabled) return;
|
|
56321
56336
|
try {
|
|
56322
|
-
await this.mainFrameWrapper.evaluateInLocatorWorld(`globalThis.__stagehandLocatorScripts.moveCursorOverlay(${Math.round(x)}, ${Math.round(y)})
|
|
56323
|
-
} catch {
|
|
56337
|
+
await this.mainFrameWrapper.evaluateInLocatorWorld(`globalThis.__stagehandLocatorScripts.moveCursorOverlay(${Math.round(x)}, ${Math.round(y)})`, progress);
|
|
56338
|
+
} catch {
|
|
56339
|
+
progress?.throwIfStopped();
|
|
56340
|
+
}
|
|
56324
56341
|
}
|
|
56325
56342
|
async addInitScript(script, arg) {
|
|
56326
56343
|
const source = await normalizeInitScriptSource(script, arg, "page.addInitScript");
|
|
@@ -57462,32 +57479,32 @@ var Page = class Page {
|
|
|
57462
57479
|
button: "none"
|
|
57463
57480
|
});
|
|
57464
57481
|
}
|
|
57465
|
-
async scroll(x, y, deltaX, deltaY) {
|
|
57466
|
-
await this.updateCursor(x, y);
|
|
57467
|
-
await this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57482
|
+
async scroll(x, y, deltaX, deltaY, progress) {
|
|
57483
|
+
await runLocatorStep(progress, "updating cursor", () => this.updateCursor(x, y, progress));
|
|
57484
|
+
await runLocatorStep(progress, "scrolling page", () => this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57468
57485
|
type: "mouseMoved",
|
|
57469
57486
|
x,
|
|
57470
57487
|
y,
|
|
57471
57488
|
button: "none"
|
|
57472
|
-
});
|
|
57473
|
-
await this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57489
|
+
}));
|
|
57490
|
+
await runLocatorStep(progress, "scrolling page", () => this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57474
57491
|
type: "mouseWheel",
|
|
57475
57492
|
x,
|
|
57476
57493
|
y,
|
|
57477
57494
|
button: "none",
|
|
57478
57495
|
deltaX,
|
|
57479
57496
|
deltaY
|
|
57480
|
-
});
|
|
57497
|
+
}));
|
|
57481
57498
|
}
|
|
57482
57499
|
/**
|
|
57483
57500
|
* Drag from (fromX, fromY) to (toX, toY) using mouse events.
|
|
57484
57501
|
* Sends mouseMoved → mousePressed → mouseMoved (route or steps) → mouseReleased.
|
|
57485
57502
|
*/
|
|
57486
|
-
async dragAndDrop(fromX, fromY, toX, toY, options) {
|
|
57503
|
+
async dragAndDrop(fromX, fromY, toX, toY, options, progress) {
|
|
57487
57504
|
const button = options?.button ?? "left";
|
|
57488
57505
|
const steps = Math.max(1, Math.floor(options?.steps ?? 1));
|
|
57489
57506
|
const delay = Math.max(0, options?.delay ?? 0);
|
|
57490
|
-
const sleep = (ms) => new Promise((r) => ms > 0 ? setTimeout(r, ms) : r());
|
|
57507
|
+
const sleep = (ms) => progress ? progress.delay(ms) : new Promise((r) => ms > 0 ? setTimeout(r, ms) : r());
|
|
57491
57508
|
const buttonMask = (b) => {
|
|
57492
57509
|
switch (b) {
|
|
57493
57510
|
case "left": return 1;
|
|
@@ -57496,57 +57513,79 @@ var Page = class Page {
|
|
|
57496
57513
|
default: return 1;
|
|
57497
57514
|
}
|
|
57498
57515
|
};
|
|
57499
|
-
await this.updateCursor(fromX, fromY);
|
|
57500
|
-
await this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57516
|
+
await runLocatorStep(progress, "updating cursor", () => this.updateCursor(fromX, fromY, progress));
|
|
57517
|
+
await runLocatorStep(progress, "dragging mouse", () => this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57501
57518
|
type: "mouseMoved",
|
|
57502
57519
|
x: fromX,
|
|
57503
57520
|
y: fromY,
|
|
57504
57521
|
button: "none"
|
|
57505
|
-
});
|
|
57506
|
-
|
|
57507
|
-
|
|
57508
|
-
|
|
57509
|
-
|
|
57522
|
+
}));
|
|
57523
|
+
let pressed = false;
|
|
57524
|
+
let x = fromX;
|
|
57525
|
+
let y = fromY;
|
|
57526
|
+
const release = () => this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57527
|
+
type: "mouseReleased",
|
|
57528
|
+
x,
|
|
57529
|
+
y,
|
|
57510
57530
|
button,
|
|
57511
57531
|
buttons: buttonMask(button),
|
|
57512
57532
|
clickCount: 1
|
|
57513
57533
|
});
|
|
57514
|
-
|
|
57515
|
-
|
|
57516
|
-
|
|
57517
|
-
|
|
57518
|
-
|
|
57519
|
-
|
|
57520
|
-
|
|
57521
|
-
|
|
57522
|
-
|
|
57523
|
-
|
|
57524
|
-
|
|
57525
|
-
|
|
57526
|
-
x: fromX + (toX - fromX) * t,
|
|
57527
|
-
y: fromY + (toY - fromY) * t
|
|
57528
|
-
};
|
|
57529
|
-
});
|
|
57530
|
-
for (const { x, y } of movementPoints) {
|
|
57531
|
-
await this.updateCursor(x, y);
|
|
57532
|
-
await this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57533
|
-
type: "mouseMoved",
|
|
57534
|
-
x,
|
|
57535
|
-
y,
|
|
57536
|
-
button,
|
|
57537
|
-
buttons: buttonMask(button)
|
|
57534
|
+
try {
|
|
57535
|
+
progress?.throwIfStopped();
|
|
57536
|
+
await runLocatorStep(progress, "pressing mouse", () => {
|
|
57537
|
+
pressed = true;
|
|
57538
|
+
return this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57539
|
+
type: "mousePressed",
|
|
57540
|
+
x: fromX,
|
|
57541
|
+
y: fromY,
|
|
57542
|
+
button,
|
|
57543
|
+
buttons: buttonMask(button),
|
|
57544
|
+
clickCount: 1
|
|
57545
|
+
});
|
|
57538
57546
|
});
|
|
57539
|
-
|
|
57547
|
+
const samePoint = (point, x, y) => point.x === x && point.y === y;
|
|
57548
|
+
const route = options?.route ?? [];
|
|
57549
|
+
let routeStart = 0;
|
|
57550
|
+
let routeEnd = route.length;
|
|
57551
|
+
while (routeStart < routeEnd && samePoint(route[routeStart], fromX, fromY)) routeStart++;
|
|
57552
|
+
while (routeEnd > routeStart && samePoint(route[routeEnd - 1], toX, toY)) routeEnd--;
|
|
57553
|
+
const movementPoints = route.length > 0 ? [...route.slice(routeStart, routeEnd), {
|
|
57554
|
+
x: toX,
|
|
57555
|
+
y: toY
|
|
57556
|
+
}] : Array.from({ length: steps }, (_, index) => {
|
|
57557
|
+
const t = (index + 1) / steps;
|
|
57558
|
+
return {
|
|
57559
|
+
x: fromX + (toX - fromX) * t,
|
|
57560
|
+
y: fromY + (toY - fromY) * t
|
|
57561
|
+
};
|
|
57562
|
+
});
|
|
57563
|
+
for (const point of movementPoints) {
|
|
57564
|
+
progress?.throwIfStopped();
|
|
57565
|
+
await runLocatorStep(progress, "updating cursor", () => this.updateCursor(point.x, point.y, progress));
|
|
57566
|
+
await runLocatorStep(progress, "dragging mouse", () => {
|
|
57567
|
+
x = point.x;
|
|
57568
|
+
y = point.y;
|
|
57569
|
+
return this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57570
|
+
type: "mouseMoved",
|
|
57571
|
+
x,
|
|
57572
|
+
y,
|
|
57573
|
+
button,
|
|
57574
|
+
buttons: buttonMask(button)
|
|
57575
|
+
});
|
|
57576
|
+
});
|
|
57577
|
+
if (delay) await sleep(delay);
|
|
57578
|
+
}
|
|
57579
|
+
await runLocatorStep(progress, "updating cursor", () => this.updateCursor(toX, toY, progress));
|
|
57580
|
+
await runLocatorStep(progress, "releasing mouse", () => {
|
|
57581
|
+
pressed = false;
|
|
57582
|
+
return release();
|
|
57583
|
+
});
|
|
57584
|
+
} finally {
|
|
57585
|
+
if (pressed) if (progress) await progress.cleanup(release);
|
|
57586
|
+
else await release().catch(() => {});
|
|
57540
57587
|
}
|
|
57541
|
-
|
|
57542
|
-
await this.mainSession.send("Input.dispatchMouseEvent", {
|
|
57543
|
-
type: "mouseReleased",
|
|
57544
|
-
x: toX,
|
|
57545
|
-
y: toY,
|
|
57546
|
-
button,
|
|
57547
|
-
buttons: buttonMask(button),
|
|
57548
|
-
clickCount: 1
|
|
57549
|
-
});
|
|
57588
|
+
progress?.throwIfStopped();
|
|
57550
57589
|
}
|
|
57551
57590
|
/**
|
|
57552
57591
|
* Type a string by dispatching keyDown/keyUp events per character.
|
|
@@ -57646,9 +57685,9 @@ var Page = class Page {
|
|
|
57646
57685
|
* For printable characters, uses the text path on keyDown; for named keys, sets key/code/VK.
|
|
57647
57686
|
* Supports key combinations with modifiers like "Cmd+A", "Ctrl+C", "Shift+Tab", etc.
|
|
57648
57687
|
*/
|
|
57649
|
-
async keyPress(key, options) {
|
|
57688
|
+
async keyPress(key, options, progress) {
|
|
57650
57689
|
const delay = Math.max(0, options?.delay ?? 0);
|
|
57651
|
-
const sleep = (ms) => new Promise((r) => ms > 0 ? setTimeout(r, ms) : r());
|
|
57690
|
+
const sleep = (ms) => progress ? progress.delay(ms) : new Promise((r) => ms > 0 ? setTimeout(r, ms) : r());
|
|
57652
57691
|
function split(keyString) {
|
|
57653
57692
|
if (keyString === "+") return ["+"];
|
|
57654
57693
|
const keys = [];
|
|
@@ -57663,13 +57702,19 @@ var Page = class Page {
|
|
|
57663
57702
|
const tokens = split(key);
|
|
57664
57703
|
const mainKey = tokens[tokens.length - 1];
|
|
57665
57704
|
const modifierKeys = tokens.slice(0, -1);
|
|
57705
|
+
const heldKeys = /* @__PURE__ */ new Set();
|
|
57666
57706
|
try {
|
|
57667
|
-
for (const
|
|
57668
|
-
|
|
57707
|
+
for (const key of [...modifierKeys, mainKey]) await runLocatorStep(progress, "pressing key", () => {
|
|
57708
|
+
heldKeys.add(key);
|
|
57709
|
+
return this.keyDown(key);
|
|
57710
|
+
});
|
|
57669
57711
|
if (delay) await sleep(delay);
|
|
57670
|
-
|
|
57671
|
-
|
|
57712
|
+
for (const key of [mainKey, ...modifierKeys.toReversed()]) await runLocatorStep(progress, "releasing key", () => {
|
|
57713
|
+
heldKeys.delete(key);
|
|
57714
|
+
return this.keyUp(key);
|
|
57715
|
+
});
|
|
57672
57716
|
} catch (error) {
|
|
57717
|
+
if (progress) await progress.cleanup(() => Promise.allSettled([...heldKeys].reverse().map((key) => this.keyUp(key))));
|
|
57673
57718
|
this._pressedModifiers.clear();
|
|
57674
57719
|
throw error;
|
|
57675
57720
|
}
|
{stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/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-c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_extension/content-script.js
RENAMED
|
File without changes
|
{stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/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.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/_generated/__init__.py
RENAMED
|
File without changes
|
{stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/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
|
|
File without changes
|
{stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/src/stagehand/browserbase_services.py
RENAMED
|
File without changes
|
{stagehand-4.2.0a0.dev1575 → stagehand-4.2.0a0.dev1577}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|