@crawlee/stagehand 4.0.0-beta.99 → 4.0.0-rc.0
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.
- package/index.d.ts +2 -0
- package/index.js +5 -1
- package/index.mjs +26 -8
- package/internals/stagehand-browser-pool.d.ts +63 -0
- package/internals/stagehand-browser-pool.js +55 -0
- package/internals/stagehand-controller.d.ts +1 -2
- package/internals/stagehand-controller.js +7 -7
- package/internals/stagehand-crawler.d.ts +131 -106
- package/internals/stagehand-crawler.js +33 -19
- package/internals/stagehand-launcher.d.ts +27 -16
- package/internals/stagehand-launcher.js +13 -12
- package/internals/stagehand-plugin.d.ts +5 -5
- package/internals/stagehand-plugin.js +12 -12
- package/package.json +11 -16
package/index.d.ts
CHANGED
|
@@ -51,6 +51,8 @@
|
|
|
51
51
|
*/
|
|
52
52
|
export * from '@crawlee/browser';
|
|
53
53
|
export { StagehandCrawler, createStagehandRouter } from './internals/stagehand-crawler';
|
|
54
|
+
export { stagehandBrowserPool, remoteStagehandBrowserPool } from './internals/stagehand-browser-pool';
|
|
55
|
+
export type { StagehandBrowserPool, StagehandBrowserPoolOptions, RemoteStagehandBrowserPoolOptions, } from './internals/stagehand-browser-pool';
|
|
54
56
|
export type { StagehandOptions, StagehandPage, StagehandCrawlingContext, StagehandHook, StagehandRequestHandler, StagehandGotoOptions, StagehandCrawlerOptions, } from './internals/stagehand-crawler';
|
|
55
57
|
export type { StagehandLaunchContext } from './internals/stagehand-launcher';
|
|
56
58
|
export * as stagehandUtils from './internals/utils/stagehand-utils';
|
package/index.js
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
* @module @crawlee/stagehand
|
|
52
52
|
*/
|
|
53
53
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
-
exports.stagehandUtils = exports.createStagehandRouter = exports.StagehandCrawler = void 0;
|
|
54
|
+
exports.stagehandUtils = exports.remoteStagehandBrowserPool = exports.stagehandBrowserPool = exports.createStagehandRouter = exports.StagehandCrawler = void 0;
|
|
55
55
|
const tslib_1 = require("tslib");
|
|
56
56
|
// Re-export everything from @crawlee/browser for convenience
|
|
57
57
|
tslib_1.__exportStar(require("@crawlee/browser"), exports);
|
|
@@ -59,5 +59,9 @@ tslib_1.__exportStar(require("@crawlee/browser"), exports);
|
|
|
59
59
|
var stagehand_crawler_1 = require("./internals/stagehand-crawler");
|
|
60
60
|
Object.defineProperty(exports, "StagehandCrawler", { enumerable: true, get: function () { return stagehand_crawler_1.StagehandCrawler; } });
|
|
61
61
|
Object.defineProperty(exports, "createStagehandRouter", { enumerable: true, get: function () { return stagehand_crawler_1.createStagehandRouter; } });
|
|
62
|
+
// Export the browser pool factories, which are how a pool with non-default options reaches the crawler
|
|
63
|
+
var stagehand_browser_pool_1 = require("./internals/stagehand-browser-pool");
|
|
64
|
+
Object.defineProperty(exports, "stagehandBrowserPool", { enumerable: true, get: function () { return stagehand_browser_pool_1.stagehandBrowserPool; } });
|
|
65
|
+
Object.defineProperty(exports, "remoteStagehandBrowserPool", { enumerable: true, get: function () { return stagehand_browser_pool_1.remoteStagehandBrowserPool; } });
|
|
62
66
|
// Export utilities as namespace
|
|
63
67
|
exports.stagehandUtils = tslib_1.__importStar(require("./internals/utils/stagehand-utils"));
|
package/index.mjs
CHANGED
|
@@ -3,13 +3,13 @@ import mod from "./index.js";
|
|
|
3
3
|
export default mod;
|
|
4
4
|
export const API_PROCESSED_REQUESTS_DELAY_MILLIS = mod.API_PROCESSED_REQUESTS_DELAY_MILLIS;
|
|
5
5
|
export const ApifyLogAdapter = mod.ApifyLogAdapter;
|
|
6
|
+
export const ArgumentValidationError = mod.ArgumentValidationError;
|
|
6
7
|
export const AutoscaledPool = mod.AutoscaledPool;
|
|
7
8
|
export const BLOCKED_STATUS_CODES = mod.BLOCKED_STATUS_CODES;
|
|
8
9
|
export const BaseCrawleeLogger = mod.BaseCrawleeLogger;
|
|
9
10
|
export const BasicCrawler = mod.BasicCrawler;
|
|
10
11
|
export const BrowserCrawler = mod.BrowserCrawler;
|
|
11
12
|
export const BrowserLauncher = mod.BrowserLauncher;
|
|
12
|
-
export const ClientLoadSignal = mod.ClientLoadSignal;
|
|
13
13
|
export const ConcurrencySystem = mod.ConcurrencySystem;
|
|
14
14
|
export const Configuration = mod.Configuration;
|
|
15
15
|
export const ContextPipeline = mod.ContextPipeline;
|
|
@@ -46,19 +46,19 @@ export const NavigationSkippedError = mod.NavigationSkippedError;
|
|
|
46
46
|
export const NonRetryableError = mod.NonRetryableError;
|
|
47
47
|
export const OwnedOrInjected = mod.OwnedOrInjected;
|
|
48
48
|
export const PERSIST_STATE_KEY = mod.PERSIST_STATE_KEY;
|
|
49
|
+
export const PersistentRateLimitError = mod.PersistentRateLimitError;
|
|
49
50
|
export const ProxyConfiguration = mod.ProxyConfiguration;
|
|
50
|
-
export const PseudoUrl = mod.PseudoUrl;
|
|
51
51
|
export const QUERY_HEAD_BUFFER = mod.QUERY_HEAD_BUFFER;
|
|
52
52
|
export const QUERY_HEAD_MIN_LENGTH = mod.QUERY_HEAD_MIN_LENGTH;
|
|
53
53
|
export const REQUESTS_PERSISTENCE_KEY = mod.REQUESTS_PERSISTENCE_KEY;
|
|
54
54
|
export const RecoverableState = mod.RecoverableState;
|
|
55
55
|
export const Request = mod.Request;
|
|
56
56
|
export const RequestHandlerError = mod.RequestHandlerError;
|
|
57
|
-
export const RequestHandlerResult = mod.RequestHandlerResult;
|
|
58
57
|
export const RequestList = mod.RequestList;
|
|
59
58
|
export const RequestManagerTandem = mod.RequestManagerTandem;
|
|
60
59
|
export const RequestQueue = mod.RequestQueue;
|
|
61
60
|
export const RequestState = mod.RequestState;
|
|
61
|
+
export const RequestThrottledError = mod.RequestThrottledError;
|
|
62
62
|
export const RequestValidationError = mod.RequestValidationError;
|
|
63
63
|
export const RetryRequestError = mod.RetryRequestError;
|
|
64
64
|
export const Router = mod.Router;
|
|
@@ -73,21 +73,27 @@ export const SitemapRequestLoader = mod.SitemapRequestLoader;
|
|
|
73
73
|
export const SnapshotStore = mod.SnapshotStore;
|
|
74
74
|
export const Snapshotter = mod.Snapshotter;
|
|
75
75
|
export const StagehandCrawler = mod.StagehandCrawler;
|
|
76
|
+
export const StateValidationError = mod.StateValidationError;
|
|
76
77
|
export const Statistics = mod.Statistics;
|
|
78
|
+
export const StorageBackendLoadSignal = mod.StorageBackendLoadSignal;
|
|
77
79
|
export const StorageInstanceManager = mod.StorageInstanceManager;
|
|
78
80
|
export const StorageStatsTracker = mod.StorageStatsTracker;
|
|
81
|
+
export const StorageTransaction = mod.StorageTransaction;
|
|
79
82
|
export const SystemStatus = mod.SystemStatus;
|
|
83
|
+
export const ThrottlingRequestManager = mod.ThrottlingRequestManager;
|
|
84
|
+
export const activeStorageTransaction = mod.activeStorageTransaction;
|
|
80
85
|
export const applyRequestTransform = mod.applyRequestTransform;
|
|
86
|
+
export const assertBrowserPoolNotConfigured = mod.assertBrowserPoolNotConfigured;
|
|
81
87
|
export const assertJsonSerializable = mod.assertJsonSerializable;
|
|
82
88
|
export const bindMethodsToServiceLocator = mod.bindMethodsToServiceLocator;
|
|
83
|
-
export const browserCrawlerEnqueueLinks = mod.browserCrawlerEnqueueLinks;
|
|
84
89
|
export const browserPoolCookieToToughCookie = mod.browserPoolCookieToToughCookie;
|
|
85
|
-
export const
|
|
90
|
+
export const buildEnqueueStrategyPatterns = mod.buildEnqueueStrategyPatterns;
|
|
86
91
|
export const coerceBoolean = mod.coerceBoolean;
|
|
87
92
|
export const coerceNumber = mod.coerceNumber;
|
|
88
93
|
export const constructGlobObjectsFromGlobs = mod.constructGlobObjectsFromGlobs;
|
|
89
|
-
export const constructRegExpObjectsFromPseudoUrls = mod.constructRegExpObjectsFromPseudoUrls;
|
|
90
94
|
export const constructRegExpObjectsFromRegExps = mod.constructRegExpObjectsFromRegExps;
|
|
95
|
+
export const constructUrlPatternObjects = mod.constructUrlPatternObjects;
|
|
96
|
+
export const convertStateSync = mod.convertStateSync;
|
|
91
97
|
export const cookieStringToToughCookie = mod.cookieStringToToughCookie;
|
|
92
98
|
export const crawleeConfigFields = mod.crawleeConfigFields;
|
|
93
99
|
export const createBasicRouter = mod.createBasicRouter;
|
|
@@ -96,9 +102,10 @@ export const createDualIterable = mod.createDualIterable;
|
|
|
96
102
|
export const createRequestDebugInfo = mod.createRequestDebugInfo;
|
|
97
103
|
export const createRequestOptions = mod.createRequestOptions;
|
|
98
104
|
export const createStagehandRouter = mod.createStagehandRouter;
|
|
105
|
+
export const createStorageTransaction = mod.createStorageTransaction;
|
|
106
|
+
export const currentStorageTransaction = mod.currentStorageTransaction;
|
|
99
107
|
export const defaultRoute = mod.defaultRoute;
|
|
100
108
|
export const deserializeArray = mod.deserializeArray;
|
|
101
|
-
export const enqueueLinks = mod.enqueueLinks;
|
|
102
109
|
export const evaluateLoadSignalSample = mod.evaluateLoadSignalSample;
|
|
103
110
|
export const extractUrlsFromPage = mod.extractUrlsFromPage;
|
|
104
111
|
export const field = mod.field;
|
|
@@ -111,20 +118,31 @@ export const inspectValue = mod.inspectValue;
|
|
|
111
118
|
export const log = mod.log;
|
|
112
119
|
export const mergeCookies = mod.mergeCookies;
|
|
113
120
|
export const navigationDeadlineKey = mod.navigationDeadlineKey;
|
|
121
|
+
export const operationRejectedInTransaction = mod.operationRejectedInTransaction;
|
|
122
|
+
export const parseArgument = mod.parseArgument;
|
|
123
|
+
export const parseRetryAfterHeader = mod.parseRetryAfterHeader;
|
|
114
124
|
export const parseValue = mod.parseValue;
|
|
115
125
|
export const purgeDefaultStorages = mod.purgeDefaultStorages;
|
|
126
|
+
export const rejectOperationInTransaction = mod.rejectOperationInTransaction;
|
|
116
127
|
export const remainingNavigationWindowMillis = mod.remainingNavigationWindowMillis;
|
|
128
|
+
export const remoteStagehandBrowserPool = mod.remoteStagehandBrowserPool;
|
|
117
129
|
export const resolveBaseUrlForEnqueueLinksFiltering = mod.resolveBaseUrlForEnqueueLinksFiltering;
|
|
118
130
|
export const resolveStorageIdentifier = mod.resolveStorageIdentifier;
|
|
131
|
+
export const schemas = mod.schemas;
|
|
119
132
|
export const serializeArray = mod.serializeArray;
|
|
120
133
|
export const serializeValue = mod.serializeValue;
|
|
121
134
|
export const serviceLocator = mod.serviceLocator;
|
|
135
|
+
export const snapshotValue = mod.snapshotValue;
|
|
136
|
+
export const stagehandBrowserPool = mod.stagehandBrowserPool;
|
|
122
137
|
export const stagehandUtils = mod.stagehandUtils;
|
|
138
|
+
export const supportsDomainThrottling = mod.supportsDomainThrottling;
|
|
123
139
|
export const toughCookieToBrowserPoolCookie = mod.toughCookieToBrowserPoolCookie;
|
|
124
140
|
export const tryAbsoluteURL = mod.tryAbsoluteURL;
|
|
125
141
|
export const updateEnqueueLinksPatternCache = mod.updateEnqueueLinksPatternCache;
|
|
142
|
+
export const urlPatternSchema = mod.urlPatternSchema;
|
|
126
143
|
export const useState = mod.useState;
|
|
127
144
|
export const validateGlobPattern = mod.validateGlobPattern;
|
|
128
145
|
export const validateUserData = mod.validateUserData;
|
|
129
146
|
export const validators = mod.validators;
|
|
130
|
-
export const
|
|
147
|
+
export const withDirectStorageAccess = mod.withDirectStorageAccess;
|
|
148
|
+
export const withStorageTransaction = mod.withStorageTransaction;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Configuration } from '@crawlee/browser';
|
|
2
|
+
import type { BrowserPool, BrowserPoolHooks, BrowserPoolOptions, RemoteBrowserPool, RemoteBrowserPoolOptions } from '@crawlee/browser-pool';
|
|
3
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
4
|
+
import type { Page } from 'playwright';
|
|
5
|
+
import type { StagehandOptions } from './stagehand-crawler';
|
|
6
|
+
import type { StagehandLaunchContext } from './stagehand-launcher';
|
|
7
|
+
import type { StagehandPlugin } from './stagehand-plugin';
|
|
8
|
+
/** A {@link BrowserPool} of Stagehand browsers, as built by {@link stagehandBrowserPool}. */
|
|
9
|
+
export type StagehandBrowserPool = BrowserPool<{
|
|
10
|
+
browserPlugins: [StagehandPlugin];
|
|
11
|
+
}, [StagehandPlugin]>;
|
|
12
|
+
export interface StagehandBrowserPoolOptions extends Omit<BrowserPoolOptions, 'browserPlugins'>, BrowserPoolHooks<ReturnType<StagehandPlugin['createController']>, ReturnType<StagehandPlugin['createLaunchContext']>, Page> {
|
|
13
|
+
/** How to launch the browser: which Playwright browser type, proxy, user data dir, ... */
|
|
14
|
+
launchContext?: StagehandLaunchContext;
|
|
15
|
+
/** Stagehand configuration for the AI behavior and Browserbase integration. */
|
|
16
|
+
stagehandOptions?: StagehandOptions;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to run the browser in headless mode. Shorthand for `launchContext.launchOptions.headless`.
|
|
19
|
+
* Defaults to `true`, and can also be set via {@link Configuration}.
|
|
20
|
+
*/
|
|
21
|
+
headless?: boolean;
|
|
22
|
+
/** Configuration to read the browser defaults from. Defaults to the global configuration. */
|
|
23
|
+
configuration?: Configuration;
|
|
24
|
+
}
|
|
25
|
+
export interface RemoteStagehandBrowserPoolOptions extends Pick<StagehandBrowserPoolOptions, 'launchContext' | 'stagehandOptions' | 'headless' | 'configuration'>, Omit<RemoteBrowserPoolOptions, 'browserPlugins'> {
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Builds a {@link BrowserPool} of Stagehand browsers to pass to a {@link StagehandCrawler} as its
|
|
29
|
+
* {@link BrowserCrawlerOptions.browserPool|`browserPool`}.
|
|
30
|
+
*
|
|
31
|
+
* It accepts every {@link BrowserPoolOptions|`BrowserPool` option} plus the crawler's own `launchContext`,
|
|
32
|
+
* `stagehandOptions` and `headless`, and derives the browser plugin from them - so a pool built here always
|
|
33
|
+
* matches the crawler it is given to, and configuring one never means assembling a {@link StagehandPlugin}
|
|
34
|
+
* by hand.
|
|
35
|
+
*
|
|
36
|
+
* **Example usage:**
|
|
37
|
+
*
|
|
38
|
+
* ```javascript
|
|
39
|
+
* const crawler = new StagehandCrawler({
|
|
40
|
+
* browserPool: stagehandBrowserPool({
|
|
41
|
+
* maxOpenPagesPerBrowser: 1,
|
|
42
|
+
* stagehandOptions: { env: 'LOCAL', model: 'openai/gpt-4.1-mini' },
|
|
43
|
+
* }),
|
|
44
|
+
* requestHandler: async ({ page }) => { ... },
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* The returned pool is *not* torn down by the crawler, which is what makes it shareable between crawlers.
|
|
49
|
+
*
|
|
50
|
+
* @category Browser management
|
|
51
|
+
*/
|
|
52
|
+
export declare function stagehandBrowserPool(options?: StagehandBrowserPoolOptions): StagehandBrowserPool;
|
|
53
|
+
/**
|
|
54
|
+
* The {@link RemoteBrowserPool} counterpart of {@link stagehandBrowserPool}: connects to a remote browser
|
|
55
|
+
* service with a Stagehand plugin derived from `launchContext` and `stagehandOptions`.
|
|
56
|
+
*
|
|
57
|
+
* A {@link StagehandCrawler} accepts the same connection details directly via
|
|
58
|
+
* {@link BrowserCrawlerOptions.remoteBrowser|`remoteBrowser`}; reach for this factory when you also need to
|
|
59
|
+
* tune the wrapping pool, or to share one remote pool between crawlers.
|
|
60
|
+
*
|
|
61
|
+
* @category Browser management
|
|
62
|
+
*/
|
|
63
|
+
export declare function remoteStagehandBrowserPool(options: RemoteStagehandBrowserPoolOptions): RemoteBrowserPool<Page>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stagehandBrowserPool = stagehandBrowserPool;
|
|
4
|
+
exports.remoteStagehandBrowserPool = remoteStagehandBrowserPool;
|
|
5
|
+
const stagehand_launcher_1 = require("./stagehand-launcher");
|
|
6
|
+
/**
|
|
7
|
+
* Builds a {@link BrowserPool} of Stagehand browsers to pass to a {@link StagehandCrawler} as its
|
|
8
|
+
* {@link BrowserCrawlerOptions.browserPool|`browserPool`}.
|
|
9
|
+
*
|
|
10
|
+
* It accepts every {@link BrowserPoolOptions|`BrowserPool` option} plus the crawler's own `launchContext`,
|
|
11
|
+
* `stagehandOptions` and `headless`, and derives the browser plugin from them - so a pool built here always
|
|
12
|
+
* matches the crawler it is given to, and configuring one never means assembling a {@link StagehandPlugin}
|
|
13
|
+
* by hand.
|
|
14
|
+
*
|
|
15
|
+
* **Example usage:**
|
|
16
|
+
*
|
|
17
|
+
* ```javascript
|
|
18
|
+
* const crawler = new StagehandCrawler({
|
|
19
|
+
* browserPool: stagehandBrowserPool({
|
|
20
|
+
* maxOpenPagesPerBrowser: 1,
|
|
21
|
+
* stagehandOptions: { env: 'LOCAL', model: 'openai/gpt-4.1-mini' },
|
|
22
|
+
* }),
|
|
23
|
+
* requestHandler: async ({ page }) => { ... },
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* The returned pool is *not* torn down by the crawler, which is what makes it shareable between crawlers.
|
|
28
|
+
*
|
|
29
|
+
* @category Browser management
|
|
30
|
+
*/
|
|
31
|
+
function stagehandBrowserPool(options = {}) {
|
|
32
|
+
const { launchContext, stagehandOptions, headless, configuration, ...poolOptions } = options;
|
|
33
|
+
return stagehandLauncher(launchContext, stagehandOptions, headless, configuration).createBrowserPool(poolOptions);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The {@link RemoteBrowserPool} counterpart of {@link stagehandBrowserPool}: connects to a remote browser
|
|
37
|
+
* service with a Stagehand plugin derived from `launchContext` and `stagehandOptions`.
|
|
38
|
+
*
|
|
39
|
+
* A {@link StagehandCrawler} accepts the same connection details directly via
|
|
40
|
+
* {@link BrowserCrawlerOptions.remoteBrowser|`remoteBrowser`}; reach for this factory when you also need to
|
|
41
|
+
* tune the wrapping pool, or to share one remote pool between crawlers.
|
|
42
|
+
*
|
|
43
|
+
* @category Browser management
|
|
44
|
+
*/
|
|
45
|
+
function remoteStagehandBrowserPool(options) {
|
|
46
|
+
const { launchContext, stagehandOptions, headless, configuration, ...remoteOptions } = options;
|
|
47
|
+
return stagehandLauncher(launchContext, stagehandOptions, headless, configuration).createRemoteBrowserPool(remoteOptions);
|
|
48
|
+
}
|
|
49
|
+
function stagehandLauncher(launchContext = {}, stagehandOptions = {}, headless, configuration) {
|
|
50
|
+
return new stagehand_launcher_1.StagehandLauncher({
|
|
51
|
+
...launchContext,
|
|
52
|
+
stagehandOptions,
|
|
53
|
+
...(headless == null ? {} : { launchOptions: { ...launchContext.launchOptions, headless } }),
|
|
54
|
+
}, configuration);
|
|
55
|
+
}
|
|
@@ -18,8 +18,7 @@ import type { StagehandPlugin } from './stagehand-plugin';
|
|
|
18
18
|
* @ignore
|
|
19
19
|
*/
|
|
20
20
|
export declare class StagehandController extends BrowserController<BrowserType, LaunchOptions, PlaywrightBrowser> {
|
|
21
|
-
private
|
|
22
|
-
private readonly stagehandInstances;
|
|
21
|
+
#private;
|
|
23
22
|
constructor(browserPlugin: StagehandPlugin, stagehandInstances: WeakMap<PlaywrightBrowser, Stagehand>);
|
|
24
23
|
/**
|
|
25
24
|
* Gets the Stagehand instance associated with this controller's browser.
|
|
@@ -18,23 +18,23 @@ const utils_1 = require("@crawlee/utils");
|
|
|
18
18
|
* @ignore
|
|
19
19
|
*/
|
|
20
20
|
class StagehandController extends browser_pool_1.BrowserController {
|
|
21
|
-
stagehand = null;
|
|
22
|
-
stagehandInstances;
|
|
21
|
+
#stagehand = null;
|
|
22
|
+
#stagehandInstances;
|
|
23
23
|
constructor(browserPlugin, stagehandInstances) {
|
|
24
24
|
super(browserPlugin);
|
|
25
|
-
this
|
|
25
|
+
this.#stagehandInstances = stagehandInstances;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Gets the Stagehand instance associated with this controller's browser.
|
|
29
29
|
*/
|
|
30
30
|
getStagehand() {
|
|
31
|
-
if (!this
|
|
32
|
-
this
|
|
33
|
-
if (!this
|
|
31
|
+
if (!this.#stagehand) {
|
|
32
|
+
this.#stagehand = this.#stagehandInstances.get(this.browser);
|
|
33
|
+
if (!this.#stagehand) {
|
|
34
34
|
throw new Error('Stagehand instance not found for browser');
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
return this
|
|
37
|
+
return this.#stagehand;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* Creates a new page using the browser's default context.
|
|
@@ -4,9 +4,8 @@ import { BrowserCrawler } from '@crawlee/browser';
|
|
|
4
4
|
import type { Dictionary } from '@crawlee/types';
|
|
5
5
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
6
6
|
import type { LaunchOptions, Page, Response } from 'playwright';
|
|
7
|
-
import
|
|
7
|
+
import { z } from 'zod';
|
|
8
8
|
import type { StagehandLaunchContext } from './stagehand-launcher';
|
|
9
|
-
import type { StagehandPlugin } from './stagehand-plugin';
|
|
10
9
|
/**
|
|
11
10
|
* Stagehand-specific configuration options.
|
|
12
11
|
*/
|
|
@@ -172,7 +171,7 @@ export interface StagehandPage extends Page {
|
|
|
172
171
|
* Goto options for StagehandCrawler navigation.
|
|
173
172
|
*/
|
|
174
173
|
export type StagehandGotoOptions = NonNullable<Parameters<Page['goto']>[1]>;
|
|
175
|
-
export interface StagehandCrawlingContext<UserData extends Dictionary =
|
|
174
|
+
export interface StagehandCrawlingContext<UserData extends Dictionary = any> extends BrowserCrawlingContext<StagehandPage, Response, UserData, StagehandGotoOptions> {
|
|
176
175
|
/**
|
|
177
176
|
* Enhanced Playwright page with Stagehand AI methods.
|
|
178
177
|
* Use page.act(), page.extract(), page.observe(), page.agent() for AI-powered operations.
|
|
@@ -187,8 +186,7 @@ export interface StagehandCrawlingContext<UserData extends Dictionary = Dictiona
|
|
|
187
186
|
/**
|
|
188
187
|
* Hook function for StagehandCrawler.
|
|
189
188
|
*/
|
|
190
|
-
export
|
|
191
|
-
}
|
|
189
|
+
export type StagehandHook<UserData extends Dictionary = any> = BrowserHook<StagehandCrawlingContext<UserData>>;
|
|
192
190
|
/**
|
|
193
191
|
* Request handler for StagehandCrawler.
|
|
194
192
|
*/
|
|
@@ -197,9 +195,7 @@ export interface StagehandRequestHandler extends RequestHandler<LoadedContext<St
|
|
|
197
195
|
/**
|
|
198
196
|
* Options for StagehandCrawler.
|
|
199
197
|
*/
|
|
200
|
-
export interface StagehandCrawlerOptions<ContextExtension = Dictionary<never>, ExtendedContext extends StagehandCrawlingContext = StagehandCrawlingContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<StagehandCrawlingContext['request']
|
|
201
|
-
browserPlugins: [StagehandPlugin];
|
|
202
|
-
}, Routes> {
|
|
198
|
+
export interface StagehandCrawlerOptions<ContextExtension = Dictionary<never>, ExtendedContext extends StagehandCrawlingContext = StagehandCrawlingContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<StagehandCrawlingContext['request']>>, StatisticStateExtension extends object = {}> extends BrowserCrawlerOptions<StagehandPage, Response, StagehandCrawlingContext, ContextExtension, ExtendedContext, Routes, StatisticStateExtension> {
|
|
203
199
|
/**
|
|
204
200
|
* Stagehand-specific configuration options.
|
|
205
201
|
* These options configure the AI behavior and Browserbase integration.
|
|
@@ -209,6 +205,11 @@ export interface StagehandCrawlerOptions<ContextExtension = Dictionary<never>, E
|
|
|
209
205
|
* Launch context with Stagehand-specific options.
|
|
210
206
|
*/
|
|
211
207
|
launchContext?: StagehandLaunchContext;
|
|
208
|
+
/**
|
|
209
|
+
* Whether to run browser in headless mode. Defaults to `true`.
|
|
210
|
+
* Can be also set via {@link Configuration}.
|
|
211
|
+
*/
|
|
212
|
+
headless?: boolean;
|
|
212
213
|
/**
|
|
213
214
|
* Function that is called to process each request.
|
|
214
215
|
*
|
|
@@ -257,11 +258,11 @@ export interface StagehandCrawlerOptions<ContextExtension = Dictionary<never>, E
|
|
|
257
258
|
/**
|
|
258
259
|
* Async functions that are sequentially evaluated before the navigation.
|
|
259
260
|
*/
|
|
260
|
-
preNavigationHooks?:
|
|
261
|
+
preNavigationHooks?: BrowserHook<StagehandCrawlingContext<GetUserDataFromRequest<ExtendedContext['request']>>, ContextExtension>[];
|
|
261
262
|
/**
|
|
262
263
|
* Async functions that are sequentially evaluated after the navigation.
|
|
263
264
|
*/
|
|
264
|
-
postNavigationHooks?:
|
|
265
|
+
postNavigationHooks?: BrowserHook<StagehandCrawlingContext<GetUserDataFromRequest<ExtendedContext['request']>>, ContextExtension>[];
|
|
265
266
|
}
|
|
266
267
|
/**
|
|
267
268
|
* StagehandCrawler provides AI-powered web crawling using Browserbase's Stagehand library.
|
|
@@ -312,107 +313,131 @@ export interface StagehandCrawlerOptions<ContextExtension = Dictionary<never>, E
|
|
|
312
313
|
* await crawler.run(['https://example.com']);
|
|
313
314
|
* ```
|
|
314
315
|
*/
|
|
315
|
-
export declare class StagehandCrawler<ContextExtension = Dictionary<never>, ExtendedContext extends StagehandCrawlingContext = StagehandCrawlingContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<StagehandCrawlingContext['request']
|
|
316
|
-
browserPlugins: [StagehandPlugin];
|
|
317
|
-
}, LaunchOptions, StagehandCrawlingContext, ContextExtension, ExtendedContext, Routes> {
|
|
316
|
+
export declare class StagehandCrawler<ContextExtension = Dictionary<never>, ExtendedContext extends StagehandCrawlingContext = StagehandCrawlingContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<StagehandCrawlingContext['request']>>, StatisticStateExtension extends object = {}> extends BrowserCrawler<StagehandPage, Response, LaunchOptions, StagehandCrawlingContext, ContextExtension, ExtendedContext, Routes, StatisticStateExtension> {
|
|
318
317
|
protected static optionsShape: {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
additionalHttpErrorStatusCodes: import("ow").ArrayPredicate<number>;
|
|
377
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
378
|
-
ignoreHttpErrorStatusCodes: import("ow").ArrayPredicate<number>;
|
|
379
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
380
|
-
blockedStatusCodes: import("ow").ArrayPredicate<number>;
|
|
381
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
382
|
-
retryOnBlocked: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
383
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
384
|
-
respectRobotsTxtFile: import("ow").AnyPredicate<boolean | object>;
|
|
385
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
386
|
-
onSkippedRequest: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
387
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
388
|
-
httpClient: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
389
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
390
|
-
configuration: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
391
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
392
|
-
storageBackend: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
393
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
394
|
-
eventManager: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
395
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
396
|
-
logger: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
397
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
398
|
-
minConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
399
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
400
|
-
maxConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
401
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
402
|
-
maxRequestsPerMinute: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
403
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
404
|
-
keepAlive: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
405
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
406
|
-
statisticsOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
407
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
408
|
-
id: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
318
|
+
stagehandOptions: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
319
|
+
headless: z.ZodOptional<z.ZodBoolean>;
|
|
320
|
+
navigationTimeoutSecs: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
321
|
+
preNavigationHooks: z.ZodDefault<z.ZodCustom<unknown[], unknown[]>>;
|
|
322
|
+
postNavigationHooks: z.ZodDefault<z.ZodCustom<unknown[], unknown[]>>;
|
|
323
|
+
launchContext: z.ZodDefault<z.ZodCustom<Dictionary, Dictionary>>;
|
|
324
|
+
browserPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
325
|
+
browserPoolBuilder: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
326
|
+
remoteBrowser: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
327
|
+
saveResponseCookies: z.ZodDefault<z.ZodBoolean>;
|
|
328
|
+
proxyConfiguration: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
329
|
+
ignoreIframes: z.ZodDefault<z.ZodBoolean>;
|
|
330
|
+
ignoreShadowRoots: z.ZodDefault<z.ZodBoolean>;
|
|
331
|
+
contextPipelineBuilder: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
332
|
+
extendContext: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
333
|
+
requestList: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
334
|
+
requestQueue: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
335
|
+
requestManager: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
336
|
+
requestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
337
|
+
requestHandlerTimeoutSecs: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
338
|
+
errorHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
339
|
+
failedRequestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
340
|
+
maxRequestRetries: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
341
|
+
sameDomainDelaySecs: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
342
|
+
maxRequestsPerCrawl: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
343
|
+
maxCrawlDepth: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
344
|
+
taskLoopOptions: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
345
|
+
concurrencySystem: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
346
|
+
sessionPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
347
|
+
statusMessageLoggingInterval: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
348
|
+
statusMessageCallback: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
349
|
+
additionalHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
350
|
+
ignoreHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
351
|
+
blockedStatusCodes: z.ZodOptional<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
352
|
+
retryOnBlocked: z.ZodDefault<z.ZodBoolean>;
|
|
353
|
+
respectRobotsTxtFile: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodCustom<Dictionary, Dictionary>]>>;
|
|
354
|
+
transactionalStorage: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
355
|
+
requestQueue: z.ZodOptional<z.ZodEnum<{
|
|
356
|
+
deferred: "deferred";
|
|
357
|
+
writeThrough: "writeThrough";
|
|
358
|
+
}>>;
|
|
359
|
+
}, z.core.$strict>]>>;
|
|
360
|
+
onSkippedRequest: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
361
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
362
|
+
httpClient: z.ZodOptional<z.ZodCustom<import("@crawlee/http-client").BaseHttpClient, import("@crawlee/http-client").BaseHttpClient>>;
|
|
363
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
364
|
+
configuration: z.ZodOptional<z.ZodCustom<import("@crawlee/browser").Configuration, import("@crawlee/browser").Configuration>>;
|
|
365
|
+
storageBackend: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
366
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
367
|
+
eventManager: z.ZodOptional<z.ZodCustom<import("@crawlee/browser").EventManager, import("@crawlee/browser").EventManager>>;
|
|
368
|
+
logger: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
369
|
+
minConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
370
|
+
maxConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
371
|
+
maxRequestsPerMinute: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
372
|
+
keepAlive: z.ZodOptional<z.ZodBoolean>;
|
|
373
|
+
statistics: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
374
|
+
id: z.ZodOptional<z.ZodString>;
|
|
409
375
|
};
|
|
376
|
+
protected static optionsSchema: z.ZodObject<{
|
|
377
|
+
stagehandOptions: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
378
|
+
headless: z.ZodOptional<z.ZodBoolean>;
|
|
379
|
+
navigationTimeoutSecs: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
380
|
+
preNavigationHooks: z.ZodDefault<z.ZodCustom<unknown[], unknown[]>>;
|
|
381
|
+
postNavigationHooks: z.ZodDefault<z.ZodCustom<unknown[], unknown[]>>;
|
|
382
|
+
launchContext: z.ZodDefault<z.ZodCustom<Dictionary, Dictionary>>;
|
|
383
|
+
browserPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
384
|
+
browserPoolBuilder: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
385
|
+
remoteBrowser: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
386
|
+
saveResponseCookies: z.ZodDefault<z.ZodBoolean>;
|
|
387
|
+
proxyConfiguration: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
388
|
+
ignoreIframes: z.ZodDefault<z.ZodBoolean>;
|
|
389
|
+
ignoreShadowRoots: z.ZodDefault<z.ZodBoolean>;
|
|
390
|
+
contextPipelineBuilder: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
391
|
+
extendContext: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
392
|
+
requestList: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
393
|
+
requestQueue: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
394
|
+
requestManager: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
395
|
+
requestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
396
|
+
requestHandlerTimeoutSecs: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
397
|
+
errorHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
398
|
+
failedRequestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
399
|
+
maxRequestRetries: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
400
|
+
sameDomainDelaySecs: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
401
|
+
maxRequestsPerCrawl: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
402
|
+
maxCrawlDepth: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
403
|
+
taskLoopOptions: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
404
|
+
concurrencySystem: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
405
|
+
sessionPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
406
|
+
statusMessageLoggingInterval: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
407
|
+
statusMessageCallback: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
408
|
+
additionalHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
409
|
+
ignoreHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
410
|
+
blockedStatusCodes: z.ZodOptional<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
411
|
+
retryOnBlocked: z.ZodDefault<z.ZodBoolean>;
|
|
412
|
+
respectRobotsTxtFile: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodCustom<Dictionary, Dictionary>]>>;
|
|
413
|
+
transactionalStorage: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
414
|
+
requestQueue: z.ZodOptional<z.ZodEnum<{
|
|
415
|
+
deferred: "deferred";
|
|
416
|
+
writeThrough: "writeThrough";
|
|
417
|
+
}>>;
|
|
418
|
+
}, z.core.$strict>]>>;
|
|
419
|
+
onSkippedRequest: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
420
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
421
|
+
httpClient: z.ZodOptional<z.ZodCustom<import("@crawlee/http-client").BaseHttpClient, import("@crawlee/http-client").BaseHttpClient>>;
|
|
422
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
423
|
+
configuration: z.ZodOptional<z.ZodCustom<import("@crawlee/browser").Configuration, import("@crawlee/browser").Configuration>>;
|
|
424
|
+
storageBackend: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
425
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
426
|
+
eventManager: z.ZodOptional<z.ZodCustom<import("@crawlee/browser").EventManager, import("@crawlee/browser").EventManager>>;
|
|
427
|
+
logger: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
428
|
+
minConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
429
|
+
maxConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
430
|
+
maxRequestsPerMinute: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
431
|
+
keepAlive: z.ZodOptional<z.ZodBoolean>;
|
|
432
|
+
statistics: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
433
|
+
id: z.ZodOptional<z.ZodString>;
|
|
434
|
+
}, z.core.$strict>;
|
|
410
435
|
/**
|
|
411
436
|
* Creates a new instance of StagehandCrawler.
|
|
412
437
|
*
|
|
413
438
|
* @param options - Crawler configuration options
|
|
414
439
|
*/
|
|
415
|
-
constructor(options?: StagehandCrawlerOptions<ContextExtension, ExtendedContext, Routes>);
|
|
440
|
+
constructor(options?: StagehandCrawlerOptions<ContextExtension, ExtendedContext, Routes, StatisticStateExtension>);
|
|
416
441
|
protected buildContextPipeline(): ContextPipeline<CrawlingContext, StagehandCrawlingContext>;
|
|
417
442
|
/**
|
|
418
443
|
* Resolves the {@link StagehandController} that owns the given page, or
|
|
@@ -432,7 +457,7 @@ export declare class StagehandCrawler<ContextExtension = Dictionary<never>, Exte
|
|
|
432
457
|
* Navigation handler for Stagehand crawler.
|
|
433
458
|
* Uses standard Playwright navigation.
|
|
434
459
|
*/
|
|
435
|
-
protected
|
|
460
|
+
protected navigationHandler(crawlingContext: StagehandCrawlingContext, gotoOptions: StagehandGotoOptions): Promise<Response | null>;
|
|
436
461
|
}
|
|
437
462
|
/**
|
|
438
463
|
* Creates a new router for StagehandCrawler with type-safe route handlers.
|
|
@@ -450,7 +475,7 @@ export declare class StagehandCrawler<ContextExtension = Dictionary<never>, Exte
|
|
|
450
475
|
* });
|
|
451
476
|
*
|
|
452
477
|
* router.addDefaultHandler(async ({ page, enqueueLinks }) => {
|
|
453
|
-
* await enqueueLinks({
|
|
478
|
+
* await enqueueLinks({ include: ['https://example.com/products/*'] });
|
|
454
479
|
* });
|
|
455
480
|
*
|
|
456
481
|
* const crawler = new StagehandCrawler({
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StagehandCrawler = void 0;
|
|
4
4
|
exports.createStagehandRouter = createStagehandRouter;
|
|
5
|
-
const tslib_1 = require("tslib");
|
|
6
5
|
const browser_1 = require("@crawlee/browser");
|
|
7
|
-
const
|
|
8
|
-
const
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const stagehand_browser_pool_1 = require("./stagehand-browser-pool");
|
|
9
8
|
const stagehand_utils_1 = require("./utils/stagehand-utils");
|
|
10
9
|
/**
|
|
11
10
|
* StagehandCrawler provides AI-powered web crawling using Browserbase's Stagehand library.
|
|
@@ -59,31 +58,46 @@ const stagehand_utils_1 = require("./utils/stagehand-utils");
|
|
|
59
58
|
class StagehandCrawler extends browser_1.BrowserCrawler {
|
|
60
59
|
static optionsShape = {
|
|
61
60
|
...browser_1.BrowserCrawler.optionsShape,
|
|
62
|
-
stagehandOptions:
|
|
63
|
-
|
|
61
|
+
stagehandOptions: browser_1.schemas.anyObject.optional(),
|
|
62
|
+
headless: zod_1.z.boolean().optional(),
|
|
64
63
|
};
|
|
64
|
+
static optionsSchema = zod_1.z.strictObject(StagehandCrawler.optionsShape);
|
|
65
65
|
/**
|
|
66
66
|
* Creates a new instance of StagehandCrawler.
|
|
67
67
|
*
|
|
68
68
|
* @param options - Crawler configuration options
|
|
69
69
|
*/
|
|
70
70
|
constructor(options = {}) {
|
|
71
|
-
(0,
|
|
72
|
-
const { stagehandOptions
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
browserPoolOptions.browserPlugins = [launcher.createBrowserPlugin()];
|
|
82
|
-
// Initialize BrowserCrawler with Stagehand plugin and fingerprinting enabled
|
|
71
|
+
const parsedOptions = (0, browser_1.parseArgument)(options, StagehandCrawler.optionsSchema, 'StagehandCrawlerOptions');
|
|
72
|
+
const { stagehandOptions, launchContext, headless, configuration, contextPipelineBuilder, ...browserCrawlerOptions } = parsedOptions;
|
|
73
|
+
if (options.browserPool) {
|
|
74
|
+
// The raw options, not the parsed ones: `launchContext` has a default, so by now it is always set.
|
|
75
|
+
(0, browser_1.assertBrowserPoolNotConfigured)(new.target.name, {
|
|
76
|
+
launchContext: options.launchContext,
|
|
77
|
+
stagehandOptions: options.stagehandOptions,
|
|
78
|
+
headless: options.headless,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
83
81
|
super({
|
|
84
82
|
...browserCrawlerOptions,
|
|
85
83
|
launchContext,
|
|
86
|
-
|
|
84
|
+
configuration,
|
|
85
|
+
// The pool serves plain Playwright pages - a page only becomes a `StagehandPage` further down the
|
|
86
|
+
// pipeline, once `setUpStagehand` enhances it - so its page type is narrower than the crawler's.
|
|
87
|
+
browserPoolBuilder: (remoteBrowser) => (remoteBrowser
|
|
88
|
+
? (0, stagehand_browser_pool_1.remoteStagehandBrowserPool)({
|
|
89
|
+
...remoteBrowser,
|
|
90
|
+
launchContext,
|
|
91
|
+
stagehandOptions,
|
|
92
|
+
headless,
|
|
93
|
+
configuration,
|
|
94
|
+
})
|
|
95
|
+
: (0, stagehand_browser_pool_1.stagehandBrowserPool)({
|
|
96
|
+
launchContext,
|
|
97
|
+
stagehandOptions,
|
|
98
|
+
headless,
|
|
99
|
+
configuration,
|
|
100
|
+
})),
|
|
87
101
|
contextPipelineBuilder: contextPipelineBuilder ?? (() => this.buildContextPipeline()),
|
|
88
102
|
});
|
|
89
103
|
}
|
|
@@ -123,7 +137,7 @@ class StagehandCrawler extends browser_1.BrowserCrawler {
|
|
|
123
137
|
* Navigation handler for Stagehand crawler.
|
|
124
138
|
* Uses standard Playwright navigation.
|
|
125
139
|
*/
|
|
126
|
-
async
|
|
140
|
+
async navigationHandler(crawlingContext, gotoOptions) {
|
|
127
141
|
// Use standard page.goto for navigation
|
|
128
142
|
return crawlingContext.page.goto(crawlingContext.request.url, gotoOptions);
|
|
129
143
|
}
|
|
@@ -2,6 +2,7 @@ import type { BrowserLaunchContext } from '@crawlee/browser';
|
|
|
2
2
|
import { BrowserLauncher, Configuration } from '@crawlee/browser';
|
|
3
3
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
4
4
|
import type { BrowserType, LaunchOptions } from 'playwright';
|
|
5
|
+
import { z } from 'zod';
|
|
5
6
|
import type { StagehandOptions } from './stagehand-crawler';
|
|
6
7
|
import { StagehandPlugin } from './stagehand-plugin';
|
|
7
8
|
/**
|
|
@@ -54,32 +55,42 @@ export interface StagehandLaunchContext extends BrowserLaunchContext<LaunchOptio
|
|
|
54
55
|
* @ignore
|
|
55
56
|
*/
|
|
56
57
|
export declare class StagehandLauncher extends BrowserLauncher<StagehandPlugin> {
|
|
58
|
+
#private;
|
|
57
59
|
readonly configuration: Configuration;
|
|
58
60
|
protected static optionsShape: {
|
|
59
61
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
60
|
-
launcher: import("
|
|
62
|
+
launcher: z.ZodOptional<z.ZodCustom<import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary, import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary>>;
|
|
61
63
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
62
|
-
launchContextOptions: import("
|
|
64
|
+
launchContextOptions: z.ZodOptional<z.ZodCustom<import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary, import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary>>;
|
|
63
65
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
64
|
-
stagehandOptions: import("
|
|
66
|
+
stagehandOptions: z.ZodOptional<z.ZodCustom<import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary, import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary>>;
|
|
67
|
+
proxyUrl: z.ZodOptional<z.ZodURL>;
|
|
68
|
+
useChrome: z.ZodOptional<z.ZodBoolean>;
|
|
69
|
+
useIncognitoPages: z.ZodOptional<z.ZodBoolean>;
|
|
70
|
+
browserPerProxy: z.ZodOptional<z.ZodBoolean>;
|
|
71
|
+
ignoreProxyCertificate: z.ZodOptional<z.ZodBoolean>;
|
|
72
|
+
userDataDir: z.ZodOptional<z.ZodString>;
|
|
65
73
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
useIncognitoPages: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
71
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
72
|
-
browserPerProxy: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
74
|
+
launchOptions: z.ZodOptional<z.ZodCustom<import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary, import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary>>;
|
|
75
|
+
userAgent: z.ZodOptional<z.ZodString>;
|
|
76
|
+
};
|
|
77
|
+
protected static optionsSchema: z.ZodObject<{
|
|
73
78
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
74
|
-
|
|
79
|
+
launcher: z.ZodOptional<z.ZodCustom<import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary, import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary>>;
|
|
75
80
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
76
|
-
|
|
81
|
+
launchContextOptions: z.ZodOptional<z.ZodCustom<import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary, import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary>>;
|
|
77
82
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
78
|
-
|
|
83
|
+
stagehandOptions: z.ZodOptional<z.ZodCustom<import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary, import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary>>;
|
|
84
|
+
proxyUrl: z.ZodOptional<z.ZodURL>;
|
|
85
|
+
useChrome: z.ZodOptional<z.ZodBoolean>;
|
|
86
|
+
useIncognitoPages: z.ZodOptional<z.ZodBoolean>;
|
|
87
|
+
browserPerProxy: z.ZodOptional<z.ZodBoolean>;
|
|
88
|
+
ignoreProxyCertificate: z.ZodOptional<z.ZodBoolean>;
|
|
89
|
+
userDataDir: z.ZodOptional<z.ZodString>;
|
|
79
90
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
launchOptions: z.ZodOptional<z.ZodCustom<import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary, import("@crawlee/types", { with: { "resolution-mode": "import" } }).Dictionary>>;
|
|
92
|
+
userAgent: z.ZodOptional<z.ZodString>;
|
|
93
|
+
}, z.core.$strict>;
|
|
83
94
|
/**
|
|
84
95
|
* All StagehandLauncher parameters are passed via the launchContext object.
|
|
85
96
|
*/
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StagehandLauncher = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
4
|
const browser_1 = require("@crawlee/browser");
|
|
6
|
-
const
|
|
5
|
+
const zod_1 = require("zod");
|
|
7
6
|
const stagehand_plugin_1 = require("./stagehand-plugin");
|
|
8
7
|
/**
|
|
9
8
|
* StagehandLauncher is based on BrowserLauncher and creates StagehandPlugin instances.
|
|
@@ -15,29 +14,31 @@ class StagehandLauncher extends browser_1.BrowserLauncher {
|
|
|
15
14
|
configuration;
|
|
16
15
|
static optionsShape = {
|
|
17
16
|
...browser_1.BrowserLauncher.optionsShape,
|
|
18
|
-
launcher
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
// Passthrough schemas — the launcher module object must keep its prototype through parsing.
|
|
18
|
+
launcher: browser_1.schemas.anyObject.optional(),
|
|
19
|
+
launchContextOptions: browser_1.schemas.anyObject.optional(),
|
|
20
|
+
stagehandOptions: browser_1.schemas.anyObject.optional(),
|
|
21
21
|
};
|
|
22
|
-
|
|
22
|
+
static optionsSchema = zod_1.z.strictObject(StagehandLauncher.optionsShape);
|
|
23
|
+
#stagehandOptions;
|
|
23
24
|
/**
|
|
24
25
|
* All StagehandLauncher parameters are passed via the launchContext object.
|
|
25
26
|
*/
|
|
26
27
|
constructor(launchContext = {}, configuration = browser_1.Configuration.getGlobalConfiguration()) {
|
|
27
|
-
(0,
|
|
28
|
-
const { launcher = browser_1.BrowserLauncher.requireLauncherOrThrow('playwright', 'apify/actor-node-playwright-*').chromium, stagehandOptions = {}, } =
|
|
29
|
-
const { launchOptions = {}, ...rest } =
|
|
28
|
+
const parsedContext = (0, browser_1.parseArgument)(launchContext, StagehandLauncher.optionsSchema, 'StagehandLaunchContext');
|
|
29
|
+
const { launcher = browser_1.BrowserLauncher.requireLauncherOrThrow('playwright', 'apify/actor-node-playwright-*').chromium, stagehandOptions = {}, } = parsedContext;
|
|
30
|
+
const { launchOptions = {}, ...rest } = parsedContext;
|
|
30
31
|
// Call super first before initializing properties
|
|
31
32
|
super({
|
|
32
33
|
...rest,
|
|
33
34
|
launchOptions: {
|
|
34
35
|
...launchOptions,
|
|
35
|
-
executablePath: getDefaultExecutablePath(
|
|
36
|
+
executablePath: getDefaultExecutablePath(parsedContext, configuration),
|
|
36
37
|
},
|
|
37
38
|
launcher,
|
|
38
39
|
}, configuration);
|
|
39
40
|
this.configuration = configuration;
|
|
40
|
-
this
|
|
41
|
+
this.#stagehandOptions = {
|
|
41
42
|
env: 'LOCAL',
|
|
42
43
|
model: 'openai/gpt-4.1-mini',
|
|
43
44
|
...stagehandOptions,
|
|
@@ -52,7 +53,7 @@ class StagehandLauncher extends browser_1.BrowserLauncher {
|
|
|
52
53
|
...this.otherLaunchContextProps,
|
|
53
54
|
proxyUrl: this.proxyUrl,
|
|
54
55
|
launchOptions: this.createLaunchOptions(),
|
|
55
|
-
stagehandOptions: this
|
|
56
|
+
stagehandOptions: this.#stagehandOptions, // Set AFTER to override any unresolved options
|
|
56
57
|
});
|
|
57
58
|
}
|
|
58
59
|
}
|
|
@@ -27,8 +27,8 @@ export interface StagehandPluginOptions extends BrowserPluginOptions<LaunchOptio
|
|
|
27
27
|
* - Some fingerprinting options may not be fully applied (Stagehand controls browser launch)
|
|
28
28
|
*/
|
|
29
29
|
export declare class StagehandPlugin extends BrowserPlugin<BrowserType, LaunchOptions, PlaywrightBrowser> {
|
|
30
|
+
#private;
|
|
30
31
|
readonly stagehandOptions: StagehandOptions;
|
|
31
|
-
private readonly stagehandInstances;
|
|
32
32
|
constructor(library: BrowserType, options?: StagehandPluginOptions);
|
|
33
33
|
/**
|
|
34
34
|
* Launches a browser using Stagehand and connects Playwright to it via CDP.
|
|
@@ -37,7 +37,7 @@ export declare class StagehandPlugin extends BrowserPlugin<BrowserType, LaunchOp
|
|
|
37
37
|
/**
|
|
38
38
|
* Cleans up Stagehand instance when browser disconnects.
|
|
39
39
|
*/
|
|
40
|
-
private
|
|
40
|
+
private cleanupStagehand;
|
|
41
41
|
/**
|
|
42
42
|
* Creates a controller for the Stagehand browser.
|
|
43
43
|
*/
|
|
@@ -45,15 +45,15 @@ export declare class StagehandPlugin extends BrowserPlugin<BrowserType, LaunchOp
|
|
|
45
45
|
/**
|
|
46
46
|
* Adds proxy configuration to launch options.
|
|
47
47
|
*/
|
|
48
|
-
protected
|
|
48
|
+
protected addProxyToLaunchOptions(launchContext: LaunchContext<BrowserType>): Promise<void>;
|
|
49
49
|
/**
|
|
50
50
|
* Determines if this is a Chromium-based browser.
|
|
51
51
|
*/
|
|
52
|
-
protected
|
|
52
|
+
protected isChromiumBasedBrowser(): boolean;
|
|
53
53
|
/**
|
|
54
54
|
* Augments launch errors with helpful context.
|
|
55
55
|
*/
|
|
56
|
-
private
|
|
56
|
+
private augmentLaunchError;
|
|
57
57
|
/**
|
|
58
58
|
* Gets the Stagehand instance for a given browser.
|
|
59
59
|
*/
|
|
@@ -22,7 +22,7 @@ const stagehand_controller_1 = require("./stagehand-controller");
|
|
|
22
22
|
*/
|
|
23
23
|
class StagehandPlugin extends browser_pool_1.BrowserPlugin {
|
|
24
24
|
stagehandOptions;
|
|
25
|
-
stagehandInstances = new WeakMap();
|
|
25
|
+
#stagehandInstances = new WeakMap();
|
|
26
26
|
constructor(library, options = {}) {
|
|
27
27
|
super(library, options);
|
|
28
28
|
this.stagehandOptions = options.stagehandOptions ?? {};
|
|
@@ -76,10 +76,10 @@ class StagehandPlugin extends browser_pool_1.BrowserPlugin {
|
|
|
76
76
|
}
|
|
77
77
|
const browser = await playwright_1.chromium.connectOverCDP(cdpUrl);
|
|
78
78
|
// Store the Stagehand instance for AI operations
|
|
79
|
-
this
|
|
79
|
+
this.#stagehandInstances.set(browser, stagehand);
|
|
80
80
|
// Handle browser disconnection - cleanup both Stagehand and anonymized proxy
|
|
81
81
|
browser.on('disconnected', async () => {
|
|
82
|
-
await this.
|
|
82
|
+
await this.cleanupStagehand(browser);
|
|
83
83
|
await closeAnonymizedProxy();
|
|
84
84
|
});
|
|
85
85
|
return browser;
|
|
@@ -88,7 +88,7 @@ class StagehandPlugin extends browser_pool_1.BrowserPlugin {
|
|
|
88
88
|
// Clean up on failure
|
|
89
89
|
await stagehand.close().catch(() => { });
|
|
90
90
|
await closeAnonymizedProxy();
|
|
91
|
-
const augmentedError = this.
|
|
91
|
+
const augmentedError = this.augmentLaunchError(error, launchContext);
|
|
92
92
|
core_1.serviceLocator.getLogger().error('Stagehand browser launch failed', { message: augmentedError.message });
|
|
93
93
|
throw augmentedError;
|
|
94
94
|
}
|
|
@@ -96,8 +96,8 @@ class StagehandPlugin extends browser_pool_1.BrowserPlugin {
|
|
|
96
96
|
/**
|
|
97
97
|
* Cleans up Stagehand instance when browser disconnects.
|
|
98
98
|
*/
|
|
99
|
-
async
|
|
100
|
-
const stagehand = this
|
|
99
|
+
async cleanupStagehand(browser) {
|
|
100
|
+
const stagehand = this.#stagehandInstances.get(browser);
|
|
101
101
|
if (stagehand) {
|
|
102
102
|
try {
|
|
103
103
|
await stagehand.close();
|
|
@@ -105,19 +105,19 @@ class StagehandPlugin extends browser_pool_1.BrowserPlugin {
|
|
|
105
105
|
catch {
|
|
106
106
|
// Ignore cleanup errors
|
|
107
107
|
}
|
|
108
|
-
this
|
|
108
|
+
this.#stagehandInstances.delete(browser);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
112
|
* Creates a controller for the Stagehand browser.
|
|
113
113
|
*/
|
|
114
114
|
createController() {
|
|
115
|
-
return new stagehand_controller_1.StagehandController(this, this
|
|
115
|
+
return new stagehand_controller_1.StagehandController(this, this.#stagehandInstances);
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
118
|
* Adds proxy configuration to launch options.
|
|
119
119
|
*/
|
|
120
|
-
async
|
|
120
|
+
async addProxyToLaunchOptions(launchContext) {
|
|
121
121
|
launchContext.launchOptions ??= {};
|
|
122
122
|
const { launchOptions, proxyUrl } = launchContext;
|
|
123
123
|
if (proxyUrl) {
|
|
@@ -132,14 +132,14 @@ class StagehandPlugin extends browser_pool_1.BrowserPlugin {
|
|
|
132
132
|
/**
|
|
133
133
|
* Determines if this is a Chromium-based browser.
|
|
134
134
|
*/
|
|
135
|
-
|
|
135
|
+
isChromiumBasedBrowser() {
|
|
136
136
|
const name = this.library?.name?.();
|
|
137
137
|
return name === 'chromium';
|
|
138
138
|
}
|
|
139
139
|
/**
|
|
140
140
|
* Augments launch errors with helpful context.
|
|
141
141
|
*/
|
|
142
|
-
|
|
142
|
+
augmentLaunchError(error, launchContext) {
|
|
143
143
|
const message = error instanceof Error ? error.message : String(error);
|
|
144
144
|
const model = this.stagehandOptions.model;
|
|
145
145
|
let helpText = '';
|
|
@@ -163,7 +163,7 @@ class StagehandPlugin extends browser_pool_1.BrowserPlugin {
|
|
|
163
163
|
* Gets the Stagehand instance for a given browser.
|
|
164
164
|
*/
|
|
165
165
|
getStagehandForBrowser(browser) {
|
|
166
|
-
return this
|
|
166
|
+
return this.#stagehandInstances.get(browser);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
exports.StagehandPlugin = StagehandPlugin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crawlee/stagehand",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-rc.0",
|
|
4
4
|
"description": "AI-powered web crawling with Stagehand integration for Crawlee - enables natural language browser automation with act(), extract(), and observe() methods.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.0.0"
|
|
@@ -57,18 +57,17 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@apify/timeout": "^0.4.4",
|
|
60
|
-
"@crawlee/browser": "4.0.0-
|
|
61
|
-
"@crawlee/browser-pool": "4.0.0-
|
|
62
|
-
"@crawlee/core": "4.0.0-
|
|
63
|
-
"@crawlee/types": "4.0.0-
|
|
64
|
-
"@crawlee/utils": "4.0.0-
|
|
65
|
-
"
|
|
66
|
-
"
|
|
60
|
+
"@crawlee/browser": "4.0.0-rc.0",
|
|
61
|
+
"@crawlee/browser-pool": "4.0.0-rc.0",
|
|
62
|
+
"@crawlee/core": "4.0.0-rc.0",
|
|
63
|
+
"@crawlee/types": "4.0.0-rc.0",
|
|
64
|
+
"@crawlee/utils": "4.0.0-rc.0",
|
|
65
|
+
"tslib": "^2.8.1",
|
|
66
|
+
"zod": "^4.4.3"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"@browserbasehq/stagehand": "^3.0.0",
|
|
70
|
-
"playwright": "*"
|
|
71
|
-
"zod": "^3.0.0 || ^4.0.0"
|
|
70
|
+
"playwright": "*"
|
|
72
71
|
},
|
|
73
72
|
"peerDependenciesMeta": {
|
|
74
73
|
"@browserbasehq/stagehand": {
|
|
@@ -76,15 +75,11 @@
|
|
|
76
75
|
},
|
|
77
76
|
"playwright": {
|
|
78
77
|
"optional": true
|
|
79
|
-
},
|
|
80
|
-
"zod": {
|
|
81
|
-
"optional": true
|
|
82
78
|
}
|
|
83
79
|
},
|
|
84
80
|
"devDependencies": {
|
|
85
81
|
"@browserbasehq/stagehand": "3.0.7",
|
|
86
|
-
"playwright": "^1.60.0"
|
|
87
|
-
"zod": "^4.3.5"
|
|
82
|
+
"playwright": "^1.60.0"
|
|
88
83
|
},
|
|
89
84
|
"lerna": {
|
|
90
85
|
"command": {
|
|
@@ -93,5 +88,5 @@
|
|
|
93
88
|
}
|
|
94
89
|
}
|
|
95
90
|
},
|
|
96
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "79ab33dacdacb83e0197e6516d145f3aceef80c7"
|
|
97
92
|
}
|