@crawlee/stagehand 3.15.4-beta.39
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/LICENSE.md +201 -0
- package/README.md +153 -0
- package/index.d.ts +58 -0
- package/index.d.ts.map +1 -0
- package/index.js +64 -0
- package/index.js.map +1 -0
- package/index.mjs +101 -0
- package/internals/stagehand-controller.d.ts +55 -0
- package/internals/stagehand-controller.d.ts.map +1 -0
- package/internals/stagehand-controller.js +146 -0
- package/internals/stagehand-controller.js.map +1 -0
- package/internals/stagehand-crawler.d.ts +419 -0
- package/internals/stagehand-crawler.d.ts.map +1 -0
- package/internals/stagehand-crawler.js +174 -0
- package/internals/stagehand-crawler.js.map +1 -0
- package/internals/stagehand-launcher.d.ts +80 -0
- package/internals/stagehand-launcher.d.ts.map +1 -0
- package/internals/stagehand-launcher.js +92 -0
- package/internals/stagehand-launcher.js.map +1 -0
- package/internals/stagehand-plugin.d.ts +63 -0
- package/internals/stagehand-plugin.d.ts.map +1 -0
- package/internals/stagehand-plugin.js +181 -0
- package/internals/stagehand-plugin.js.map +1 -0
- package/internals/utils/stagehand-utils.d.ts +25 -0
- package/internals/utils/stagehand-utils.d.ts.map +1 -0
- package/internals/utils/stagehand-utils.js +120 -0
- package/internals/utils/stagehand-utils.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StagehandCrawler = void 0;
|
|
4
|
+
exports.createStagehandRouter = createStagehandRouter;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const browser_1 = require("@crawlee/browser");
|
|
7
|
+
const ow_1 = tslib_1.__importDefault(require("ow"));
|
|
8
|
+
const stagehand_launcher_1 = require("./stagehand-launcher");
|
|
9
|
+
const stagehand_utils_1 = require("./utils/stagehand-utils");
|
|
10
|
+
/**
|
|
11
|
+
* StagehandCrawler provides AI-powered web crawling using Browserbase's Stagehand library.
|
|
12
|
+
*
|
|
13
|
+
* It extends {@apilink BrowserCrawler} and adds natural language interaction capabilities:
|
|
14
|
+
* - `page.act()` - Perform actions using natural language
|
|
15
|
+
* - `page.extract()` - Extract structured data with AI
|
|
16
|
+
* - `page.observe()` - Get AI-suggested actions
|
|
17
|
+
* - `page.agent()` - Create autonomous agents for complex workflows
|
|
18
|
+
*
|
|
19
|
+
* The crawler automatically applies anti-blocking features including browser fingerprinting,
|
|
20
|
+
* making it suitable for crawling sites with bot protection like Cloudflare.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { StagehandCrawler } from '@crawlee/stagehand';
|
|
25
|
+
* import { z } from 'zod';
|
|
26
|
+
*
|
|
27
|
+
* const crawler = new StagehandCrawler({
|
|
28
|
+
* stagehandOptions: {
|
|
29
|
+
* env: 'LOCAL',
|
|
30
|
+
* model: 'openai/gpt-4.1-mini',
|
|
31
|
+
* verbose: 1,
|
|
32
|
+
* },
|
|
33
|
+
* maxConcurrency: 3,
|
|
34
|
+
* async requestHandler({ page, request, log }) {
|
|
35
|
+
* log.info(`Crawling ${request.url}`);
|
|
36
|
+
*
|
|
37
|
+
* // Use AI to interact with the page
|
|
38
|
+
* await page.act('Click the Products link');
|
|
39
|
+
* await page.act('Scroll to load more items');
|
|
40
|
+
*
|
|
41
|
+
* // Extract structured data
|
|
42
|
+
* const products = await page.extract(
|
|
43
|
+
* 'Get all product names and prices',
|
|
44
|
+
* z.object({
|
|
45
|
+
* items: z.array(z.object({
|
|
46
|
+
* name: z.string(),
|
|
47
|
+
* price: z.number(),
|
|
48
|
+
* })),
|
|
49
|
+
* })
|
|
50
|
+
* );
|
|
51
|
+
*
|
|
52
|
+
* log.info(`Found ${products.items.length} products`);
|
|
53
|
+
* },
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* await crawler.run(['https://example.com']);
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
class StagehandCrawler extends browser_1.BrowserCrawler {
|
|
60
|
+
/**
|
|
61
|
+
* Creates a new instance of StagehandCrawler.
|
|
62
|
+
*
|
|
63
|
+
* @param options - Crawler configuration options
|
|
64
|
+
*/
|
|
65
|
+
constructor(options = {}, config = browser_1.Configuration.getGlobalConfig()) {
|
|
66
|
+
const { stagehandOptions = {}, launchContext = {}, browserPoolOptions = {}, ...browserCrawlerOptions } = options;
|
|
67
|
+
// Validate options
|
|
68
|
+
(0, ow_1.default)(options, 'StagehandCrawlerOptions', ow_1.default.object.exactShape(StagehandCrawler.optionsShape));
|
|
69
|
+
// Create launcher with Stagehand plugin
|
|
70
|
+
const launcher = new stagehand_launcher_1.StagehandLauncher({
|
|
71
|
+
...launchContext,
|
|
72
|
+
stagehandOptions,
|
|
73
|
+
}, config);
|
|
74
|
+
// Initialize BrowserCrawler with Stagehand plugin and fingerprinting enabled
|
|
75
|
+
super({
|
|
76
|
+
...browserCrawlerOptions,
|
|
77
|
+
launchContext,
|
|
78
|
+
browserPoolOptions: {
|
|
79
|
+
...browserPoolOptions,
|
|
80
|
+
browserPlugins: [launcher.createBrowserPlugin()],
|
|
81
|
+
// Enable fingerprinting by default for anti-blocking
|
|
82
|
+
useFingerprints: browserPoolOptions.useFingerprints ?? true,
|
|
83
|
+
},
|
|
84
|
+
}, config);
|
|
85
|
+
Object.defineProperty(this, "config", {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
configurable: true,
|
|
88
|
+
writable: true,
|
|
89
|
+
value: config
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Overrides the request handler to enhance the page with Stagehand AI methods.
|
|
94
|
+
*
|
|
95
|
+
* The pattern here is:
|
|
96
|
+
* 1. Store the original userProvidedRequestHandler
|
|
97
|
+
* 2. Replace it with a wrapper that enhances the page first
|
|
98
|
+
* 3. Call super (which creates page/browserController, then calls our wrapper)
|
|
99
|
+
* 4. Our wrapper enhances the page and calls the original handler
|
|
100
|
+
* 5. Restore the original handler
|
|
101
|
+
*
|
|
102
|
+
* This is similar to how PlaywrightCrawler adds utility methods via registerUtilsToContext,
|
|
103
|
+
* but we need to actually transform the page object to add Stagehand AI methods.
|
|
104
|
+
*/
|
|
105
|
+
async _runRequestHandler(crawlingContext) {
|
|
106
|
+
// Store the original handler (could be this.requestHandler or this.router)
|
|
107
|
+
const originalHandler = this.userProvidedRequestHandler;
|
|
108
|
+
// Replace with a wrapper that enhances the page before calling the user's handler
|
|
109
|
+
this.userProvidedRequestHandler = async (ctx) => {
|
|
110
|
+
// Get Stagehand instance from controller
|
|
111
|
+
const stagehand = ctx.browserController.getStagehand();
|
|
112
|
+
ctx.stagehand = stagehand;
|
|
113
|
+
// Enhance page with AI methods (page.act(), page.extract(), etc.)
|
|
114
|
+
ctx.page = (0, stagehand_utils_1.enhancePageWithStagehand)(ctx.page, stagehand);
|
|
115
|
+
// Call the original user handler
|
|
116
|
+
return originalHandler(ctx);
|
|
117
|
+
};
|
|
118
|
+
try {
|
|
119
|
+
// Call parent - this creates the page and eventually calls our wrapped handler
|
|
120
|
+
await super._runRequestHandler(crawlingContext);
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
// Restore original handler
|
|
124
|
+
this.userProvidedRequestHandler = originalHandler;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Navigation handler for Stagehand crawler.
|
|
129
|
+
* Uses standard Playwright navigation.
|
|
130
|
+
*/
|
|
131
|
+
async _navigationHandler(crawlingContext, gotoOptions) {
|
|
132
|
+
// Use standard page.goto for navigation
|
|
133
|
+
return crawlingContext.page.goto(crawlingContext.request.url, gotoOptions);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.StagehandCrawler = StagehandCrawler;
|
|
137
|
+
Object.defineProperty(StagehandCrawler, "optionsShape", {
|
|
138
|
+
enumerable: true,
|
|
139
|
+
configurable: true,
|
|
140
|
+
writable: true,
|
|
141
|
+
value: {
|
|
142
|
+
...browser_1.BrowserCrawler.optionsShape,
|
|
143
|
+
stagehandOptions: ow_1.default.optional.object,
|
|
144
|
+
browserPoolOptions: ow_1.default.optional.object,
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
/**
|
|
148
|
+
* Creates a new router for StagehandCrawler with type-safe route handlers.
|
|
149
|
+
*
|
|
150
|
+
* @param options - Router options
|
|
151
|
+
* @returns Configured router instance
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const router = createStagehandRouter();
|
|
156
|
+
*
|
|
157
|
+
* router.addHandler('product', async ({ page, request, log }) => {
|
|
158
|
+
* log.info(`Processing product: ${request.url}`);
|
|
159
|
+
* const data = await page.extract('Get product info', schema);
|
|
160
|
+
* });
|
|
161
|
+
*
|
|
162
|
+
* router.addDefaultHandler(async ({ page, enqueueLinks }) => {
|
|
163
|
+
* await enqueueLinks({ globs: ['https://example.com/products/*'] });
|
|
164
|
+
* });
|
|
165
|
+
*
|
|
166
|
+
* const crawler = new StagehandCrawler({
|
|
167
|
+
* requestHandler: router,
|
|
168
|
+
* });
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
function createStagehandRouter(routes) {
|
|
172
|
+
return browser_1.Router.create(routes);
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=stagehand-crawler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stagehand-crawler.js","sourceRoot":"","sources":["../../src/internals/stagehand-crawler.ts"],"names":[],"mappings":";;;AA+eA,sDAKC;;AA9dD,8CAAyE;AAEzE,oDAAoB;AAMpB,6DAAyD;AAEzD,6DAAmE;AA2RnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,MAAa,gBAAiB,SAAQ,wBAIrC;IAOG;;;;OAIG;IACH,YACI,UAAmC,EAAE,EACnB,SAAS,uBAAa,CAAC,eAAe,EAAE;QAE1D,MAAM,EACF,gBAAgB,GAAG,EAAE,EACrB,aAAa,GAAG,EAAE,EAClB,kBAAkB,GAAG,EAAE,EACvB,GAAG,qBAAqB,EAC3B,GAAG,OAAO,CAAC;QAEZ,mBAAmB;QACnB,IAAA,YAAE,EAAC,OAAO,EAAE,yBAAyB,EAAE,YAAE,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC;QAE5F,wCAAwC;QACxC,MAAM,QAAQ,GAAG,IAAI,sCAAiB,CAClC;YACI,GAAG,aAAa;YAChB,gBAAgB;SACnB,EACD,MAAM,CACT,CAAC;QAEF,6EAA6E;QAC7E,KAAK,CACD;YACI,GAAG,qBAAqB;YACxB,aAAa;YACb,kBAAkB,EAAE;gBAChB,GAAG,kBAAkB;gBACrB,cAAc,EAAE,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC;gBAChD,qDAAqD;gBACrD,eAAe,EAAE,kBAAkB,CAAC,eAAe,IAAI,IAAI;aAC9D;SACJ,EACD,MAAM,CACT,CAAC;QAlCF;;;;mBAAkB,MAAM;WAAkC;IAmC9D,CAAC;IAED;;;;;;;;;;;;OAYG;IACgB,KAAK,CAAC,kBAAkB,CAAC,eAAyC;QACjF,2EAA2E;QAC3E,MAAM,eAAe,GAAG,IAAI,CAAC,0BAA2B,CAAC;QAEzD,kFAAkF;QAClF,IAAI,CAAC,0BAA0B,GAAG,KAAK,EAAE,GAAQ,EAAE,EAAE;YACjD,yCAAyC;YACzC,MAAM,SAAS,GAAI,GAAG,CAAC,iBAAyC,CAAC,YAAY,EAAE,CAAC;YAChF,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;YAE1B,kEAAkE;YAClE,GAAG,CAAC,IAAI,GAAG,IAAA,0CAAwB,EAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAkB,CAAC;YAE1E,iCAAiC;YACjC,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC,CAAC;QAEF,IAAI,CAAC;YACD,+EAA+E;YAC/E,MAAM,KAAK,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;QACpD,CAAC;gBAAS,CAAC;YACP,2BAA2B;YAC3B,IAAI,CAAC,0BAA0B,GAAG,eAAe,CAAC;QACtD,CAAC;IACL,CAAC;IAED;;;OAGG;IACgB,KAAK,CAAC,kBAAkB,CACvC,eAAyC,EACzC,WAAiC;QAEjC,wCAAwC;QACxC,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC/E,CAAC;;AAxGL,4CAyGC;AApG6B;;;;WAAe;QACrC,GAAG,wBAAc,CAAC,YAAY;QAC9B,gBAAgB,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;QACpC,kBAAkB,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;KACzC;EAJqC,CAIpC;AAkGN;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,qBAAqB,CAGnC,MAAwC;IACtC,OAAO,gBAAM,CAAC,MAAM,CAAU,MAAM,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { BrowserLaunchContext } from '@crawlee/browser';
|
|
2
|
+
import { BrowserLauncher, Configuration } from '@crawlee/browser';
|
|
3
|
+
import type { BrowserType, LaunchOptions } from 'playwright';
|
|
4
|
+
import type { StagehandOptions } from './stagehand-crawler';
|
|
5
|
+
import { StagehandPlugin } from './stagehand-plugin';
|
|
6
|
+
/**
|
|
7
|
+
* Launch context for Stagehand crawler with AI-specific options.
|
|
8
|
+
*/
|
|
9
|
+
export interface StagehandLaunchContext extends BrowserLaunchContext<LaunchOptions, BrowserType> {
|
|
10
|
+
/**
|
|
11
|
+
* Playwright launch options.
|
|
12
|
+
* These will be passed to Stagehand's localBrowserLaunchOptions after fingerprinting is applied.
|
|
13
|
+
*/
|
|
14
|
+
launchOptions?: LaunchOptions & Parameters<BrowserType['launchPersistentContext']>[1];
|
|
15
|
+
/**
|
|
16
|
+
* Stagehand-specific configuration for AI operations.
|
|
17
|
+
*/
|
|
18
|
+
stagehandOptions?: StagehandOptions;
|
|
19
|
+
/**
|
|
20
|
+
* URL to a HTTP proxy server. It must define the port number,
|
|
21
|
+
* and it may also contain proxy username and password.
|
|
22
|
+
*
|
|
23
|
+
* Example: `http://bob:pass123@proxy.example.com:1234`.
|
|
24
|
+
*/
|
|
25
|
+
proxyUrl?: string;
|
|
26
|
+
/**
|
|
27
|
+
* If `true` and `executablePath` is not set,
|
|
28
|
+
* Playwright will launch full Google Chrome browser available on the machine
|
|
29
|
+
* rather than the bundled Chromium.
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
useChrome?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* With this option selected, all pages will be opened in a new incognito browser context.
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
useIncognitoPages?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Sets the User Data Directory path.
|
|
40
|
+
* The user data directory contains profile data such as history, bookmarks, and cookies.
|
|
41
|
+
*/
|
|
42
|
+
userDataDir?: string;
|
|
43
|
+
/**
|
|
44
|
+
* By default this function uses `require("playwright").chromium`.
|
|
45
|
+
* If you want to use a different browser you can pass it by this property.
|
|
46
|
+
*/
|
|
47
|
+
launcher?: BrowserType;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* StagehandLauncher is based on BrowserLauncher and creates StagehandPlugin instances.
|
|
51
|
+
* It manages the lifecycle of Stagehand browsers with fingerprinting and anti-blocking features.
|
|
52
|
+
*
|
|
53
|
+
* @ignore
|
|
54
|
+
*/
|
|
55
|
+
export declare class StagehandLauncher extends BrowserLauncher<StagehandPlugin> {
|
|
56
|
+
readonly config: Configuration;
|
|
57
|
+
protected static optionsShape: {
|
|
58
|
+
launcher: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
59
|
+
launchContextOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
60
|
+
stagehandOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
61
|
+
proxyUrl: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
62
|
+
useChrome: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
63
|
+
useIncognitoPages: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
64
|
+
browserPerProxy: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
65
|
+
experimentalContainers: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
66
|
+
userDataDir: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
67
|
+
launchOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
68
|
+
userAgent: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
69
|
+
};
|
|
70
|
+
private readonly stagehandOptions;
|
|
71
|
+
/**
|
|
72
|
+
* All StagehandLauncher parameters are passed via the launchContext object.
|
|
73
|
+
*/
|
|
74
|
+
constructor(launchContext?: StagehandLaunchContext, config?: Configuration);
|
|
75
|
+
/**
|
|
76
|
+
* Creates a new StagehandPlugin instance with resolved options.
|
|
77
|
+
*/
|
|
78
|
+
createBrowserPlugin(): StagehandPlugin;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=stagehand-launcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stagehand-launcher.d.ts","sourceRoot":"","sources":["../../src/internals/stagehand-launcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB,CAAC,aAAa,EAAE,WAAW,CAAC;IAC5F;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtF;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,eAAe,CAAC,eAAe,CAAC;aAe7C,MAAM;IAd5B,iBAA0B,YAAY;;;;;;;;;;;;MAKpC;IAEF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IAEpD;;OAEG;gBAEC,aAAa,GAAE,sBAA2B,EACxB,MAAM,gBAAkC;IAoC9D;;OAEG;IACM,mBAAmB,IAAI,eAAe;CAQlD"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StagehandLauncher = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const browser_1 = require("@crawlee/browser");
|
|
6
|
+
const ow_1 = tslib_1.__importDefault(require("ow"));
|
|
7
|
+
const stagehand_plugin_1 = require("./stagehand-plugin");
|
|
8
|
+
/**
|
|
9
|
+
* StagehandLauncher is based on BrowserLauncher and creates StagehandPlugin instances.
|
|
10
|
+
* It manages the lifecycle of Stagehand browsers with fingerprinting and anti-blocking features.
|
|
11
|
+
*
|
|
12
|
+
* @ignore
|
|
13
|
+
*/
|
|
14
|
+
class StagehandLauncher extends browser_1.BrowserLauncher {
|
|
15
|
+
/**
|
|
16
|
+
* All StagehandLauncher parameters are passed via the launchContext object.
|
|
17
|
+
*/
|
|
18
|
+
constructor(launchContext = {}, config = browser_1.Configuration.getGlobalConfig()) {
|
|
19
|
+
(0, ow_1.default)(launchContext, 'StagehandLaunchContext', ow_1.default.object.exactShape(StagehandLauncher.optionsShape));
|
|
20
|
+
const { launcher = browser_1.BrowserLauncher.requireLauncherOrThrow('playwright', 'apify/actor-node-playwright-*').chromium, stagehandOptions = {}, } = launchContext;
|
|
21
|
+
const { launchOptions = {}, ...rest } = launchContext;
|
|
22
|
+
// Call super first before initializing properties
|
|
23
|
+
super({
|
|
24
|
+
...rest,
|
|
25
|
+
launchOptions: {
|
|
26
|
+
...launchOptions,
|
|
27
|
+
executablePath: getDefaultExecutablePath(launchContext, config),
|
|
28
|
+
},
|
|
29
|
+
launcher,
|
|
30
|
+
}, config);
|
|
31
|
+
Object.defineProperty(this, "config", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
writable: true,
|
|
35
|
+
value: config
|
|
36
|
+
});
|
|
37
|
+
Object.defineProperty(this, "stagehandOptions", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
writable: true,
|
|
41
|
+
value: void 0
|
|
42
|
+
});
|
|
43
|
+
this.stagehandOptions = {
|
|
44
|
+
env: 'LOCAL',
|
|
45
|
+
model: 'openai/gpt-4.1-mini',
|
|
46
|
+
...stagehandOptions,
|
|
47
|
+
};
|
|
48
|
+
this.Plugin = stagehand_plugin_1.StagehandPlugin;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new StagehandPlugin instance with resolved options.
|
|
52
|
+
*/
|
|
53
|
+
createBrowserPlugin() {
|
|
54
|
+
return new stagehand_plugin_1.StagehandPlugin(this.launcher, {
|
|
55
|
+
...this.otherLaunchContextProps,
|
|
56
|
+
proxyUrl: this.proxyUrl,
|
|
57
|
+
launchOptions: this.createLaunchOptions(),
|
|
58
|
+
stagehandOptions: this.stagehandOptions, // Set AFTER to override any unresolved options
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.StagehandLauncher = StagehandLauncher;
|
|
63
|
+
Object.defineProperty(StagehandLauncher, "optionsShape", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: {
|
|
68
|
+
...browser_1.BrowserLauncher.optionsShape,
|
|
69
|
+
launcher: ow_1.default.optional.object,
|
|
70
|
+
launchContextOptions: ow_1.default.optional.object,
|
|
71
|
+
stagehandOptions: ow_1.default.optional.object,
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
/**
|
|
75
|
+
* Gets the default executable path for the browser.
|
|
76
|
+
* @ignore
|
|
77
|
+
*/
|
|
78
|
+
function getDefaultExecutablePath(launchContext, config) {
|
|
79
|
+
const pathFromPlaywrightImage = config.get('defaultBrowserPath');
|
|
80
|
+
const { launchOptions = {} } = launchContext;
|
|
81
|
+
if (launchOptions.executablePath) {
|
|
82
|
+
return launchOptions.executablePath;
|
|
83
|
+
}
|
|
84
|
+
if (launchContext.useChrome) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
if (pathFromPlaywrightImage) {
|
|
88
|
+
return pathFromPlaywrightImage;
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=stagehand-launcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stagehand-launcher.js","sourceRoot":"","sources":["../../src/internals/stagehand-launcher.ts"],"names":[],"mappings":";;;;AACA,8CAAkE;AAClE,oDAAoB;AAIpB,yDAAqD;AAoDrD;;;;;GAKG;AACH,MAAa,iBAAkB,SAAQ,yBAAgC;IAUnE;;OAEG;IACH,YACI,gBAAwC,EAAE,EACxB,SAAS,uBAAa,CAAC,eAAe,EAAE;QAE1D,IAAA,YAAE,EAAC,aAAa,EAAE,wBAAwB,EAAE,YAAE,CAAC,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC;QAElG,MAAM,EACF,QAAQ,GAAG,yBAAe,CAAC,sBAAsB,CAC7C,YAAY,EACZ,+BAA+B,CAClC,CAAC,QAAQ,EACV,gBAAgB,GAAG,EAAE,GACxB,GAAG,aAAa,CAAC;QAElB,MAAM,EAAE,aAAa,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,aAAa,CAAC;QAEtD,kDAAkD;QAClD,KAAK,CACD;YACI,GAAG,IAAI;YACP,aAAa,EAAE;gBACX,GAAG,aAAa;gBAChB,cAAc,EAAE,wBAAwB,CAAC,aAAa,EAAE,MAAM,CAAC;aAClE;YACD,QAAQ;SACX,EACD,MAAM,CACT,CAAC;QAzBF;;;;mBAAkB,MAAM;WAAkC;QAP7C;;;;;WAAmC;QAkChD,IAAI,CAAC,gBAAgB,GAAG;YACpB,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,qBAAqB;YAC5B,GAAG,gBAAgB;SACtB,CAAC;QAEF,IAAI,CAAC,MAAM,GAAG,kCAAe,CAAC;IAClC,CAAC;IAED;;OAEG;IACM,mBAAmB;QACxB,OAAO,IAAI,kCAAe,CAAC,IAAI,CAAC,QAAuB,EAAE;YACrD,GAAG,IAAI,CAAC,uBAAuB;YAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,aAAa,EAAE,IAAI,CAAC,mBAAmB,EAAE;YACzC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,+CAA+C;SAC3F,CAAC,CAAC;IACP,CAAC;;AA7DL,8CA8DC;AA7D6B;;;;WAAe;QACrC,GAAG,yBAAe,CAAC,YAAY;QAC/B,QAAQ,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;QAC5B,oBAAoB,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;QACxC,gBAAgB,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;KACvC;EALqC,CAKpC;AA0DN;;;GAGG;AACH,SAAS,wBAAwB,CAAC,aAAqC,EAAE,MAAqB;IAC1F,MAAM,uBAAuB,GAAG,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACjE,MAAM,EAAE,aAAa,GAAG,EAAE,EAAE,GAAG,aAAa,CAAC;IAE7C,IAAI,aAAa,CAAC,cAAc,EAAE,CAAC;QAC/B,OAAO,aAAa,CAAC,cAAc,CAAC;IACxC,CAAC;IAED,IAAI,aAAa,CAAC,SAAS,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,uBAAuB,EAAE,CAAC;QAC1B,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Stagehand } from '@browserbasehq/stagehand';
|
|
2
|
+
import type { BrowserController, BrowserPluginOptions, LaunchContext } from '@crawlee/browser-pool';
|
|
3
|
+
import { BrowserPlugin } from '@crawlee/browser-pool';
|
|
4
|
+
import type { Browser as PlaywrightBrowser, BrowserType, LaunchOptions } from 'playwright';
|
|
5
|
+
import type { StagehandOptions } from './stagehand-crawler';
|
|
6
|
+
/**
|
|
7
|
+
* Options for StagehandPlugin initialization.
|
|
8
|
+
*/
|
|
9
|
+
export interface StagehandPluginOptions extends BrowserPluginOptions<LaunchOptions> {
|
|
10
|
+
/**
|
|
11
|
+
* Stagehand-specific configuration options.
|
|
12
|
+
*/
|
|
13
|
+
stagehandOptions?: StagehandOptions;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* StagehandPlugin integrates Stagehand with Crawlee's BrowserPool.
|
|
17
|
+
*
|
|
18
|
+
* Architecture:
|
|
19
|
+
* - Stagehand launches and manages the browser
|
|
20
|
+
* - We connect Playwright to the same browser via CDP to get a compatible handle
|
|
21
|
+
* - AI operations (extract, act, observe) pass the specific page via the `page` option
|
|
22
|
+
* for correct concurrent page support
|
|
23
|
+
*
|
|
24
|
+
* Limitations:
|
|
25
|
+
* - Only Chromium is supported (Stagehand uses CDP)
|
|
26
|
+
* - Some fingerprinting options may not be fully applied (Stagehand controls browser launch)
|
|
27
|
+
*
|
|
28
|
+
* @ignore
|
|
29
|
+
*/
|
|
30
|
+
export declare class StagehandPlugin extends BrowserPlugin<BrowserType, LaunchOptions, PlaywrightBrowser> {
|
|
31
|
+
readonly stagehandOptions: StagehandOptions;
|
|
32
|
+
private readonly stagehandInstances;
|
|
33
|
+
constructor(library: BrowserType, options?: StagehandPluginOptions);
|
|
34
|
+
/**
|
|
35
|
+
* Launches a browser using Stagehand and connects Playwright to it via CDP.
|
|
36
|
+
*/
|
|
37
|
+
protected _launch(launchContext: LaunchContext<BrowserType>): Promise<PlaywrightBrowser>;
|
|
38
|
+
/**
|
|
39
|
+
* Cleans up Stagehand instance when browser disconnects.
|
|
40
|
+
*/
|
|
41
|
+
private _cleanupStagehand;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a controller for the Stagehand browser.
|
|
44
|
+
*/
|
|
45
|
+
protected _createController(): BrowserController<BrowserType, LaunchOptions, PlaywrightBrowser>;
|
|
46
|
+
/**
|
|
47
|
+
* Adds proxy configuration to launch options.
|
|
48
|
+
*/
|
|
49
|
+
protected _addProxyToLaunchOptions(launchContext: LaunchContext<BrowserType>): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Determines if this is a Chromium-based browser.
|
|
52
|
+
*/
|
|
53
|
+
protected _isChromiumBasedBrowser(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Augments launch errors with helpful context.
|
|
56
|
+
*/
|
|
57
|
+
private _augmentLaunchError;
|
|
58
|
+
/**
|
|
59
|
+
* Gets the Stagehand instance for a given browser.
|
|
60
|
+
*/
|
|
61
|
+
getStagehandForBrowser(browser: PlaywrightBrowser): Stagehand | undefined;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=stagehand-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stagehand-plugin.d.ts","sourceRoot":"","sources":["../../src/internals/stagehand-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAuB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,OAAO,IAAI,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAQ3F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB,CAAC,aAAa,CAAC;IAC/E;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACvC;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAgB,SAAQ,aAAa,CAAC,WAAW,EAAE,aAAa,EAAE,iBAAiB,CAAC;IAC7F,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAwD;gBAE/E,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,sBAA2B;IAKtE;;OAEG;cACa,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA6E9F;;OAEG;YACW,iBAAiB;IAY/B;;OAEG;IACH,SAAS,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,WAAW,EAAE,aAAa,EAAE,iBAAiB,CAAC;IAI/F;;OAEG;cACa,wBAAwB,CAAC,aAAa,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlG;;OAEG;IACH,SAAS,CAAC,uBAAuB,IAAI,OAAO;IAK5C;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyB3B;;OAEG;IACH,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,GAAG,SAAS;CAG5E"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StagehandPlugin = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const browser_pool_1 = require("@crawlee/browser-pool");
|
|
6
|
+
// Stagehand is built on CDP (Chrome DevTools Protocol), which only works with Chromium-based browsers.
|
|
7
|
+
// Firefox and WebKit are not supported by Stagehand.
|
|
8
|
+
const playwright_1 = require("playwright");
|
|
9
|
+
const log_1 = tslib_1.__importDefault(require("@apify/log"));
|
|
10
|
+
const stagehand_controller_1 = require("./stagehand-controller");
|
|
11
|
+
/**
|
|
12
|
+
* StagehandPlugin integrates Stagehand with Crawlee's BrowserPool.
|
|
13
|
+
*
|
|
14
|
+
* Architecture:
|
|
15
|
+
* - Stagehand launches and manages the browser
|
|
16
|
+
* - We connect Playwright to the same browser via CDP to get a compatible handle
|
|
17
|
+
* - AI operations (extract, act, observe) pass the specific page via the `page` option
|
|
18
|
+
* for correct concurrent page support
|
|
19
|
+
*
|
|
20
|
+
* Limitations:
|
|
21
|
+
* - Only Chromium is supported (Stagehand uses CDP)
|
|
22
|
+
* - Some fingerprinting options may not be fully applied (Stagehand controls browser launch)
|
|
23
|
+
*
|
|
24
|
+
* @ignore
|
|
25
|
+
*/
|
|
26
|
+
class StagehandPlugin extends browser_pool_1.BrowserPlugin {
|
|
27
|
+
constructor(library, options = {}) {
|
|
28
|
+
super(library, options);
|
|
29
|
+
Object.defineProperty(this, "stagehandOptions", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "stagehandInstances", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: new WeakMap()
|
|
40
|
+
});
|
|
41
|
+
this.stagehandOptions = options.stagehandOptions ?? {};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Launches a browser using Stagehand and connects Playwright to it via CDP.
|
|
45
|
+
*/
|
|
46
|
+
async _launch(launchContext) {
|
|
47
|
+
const { launchOptions = {}, proxyUrl } = launchContext;
|
|
48
|
+
// Import Stagehand dynamically to avoid peer dependency issues
|
|
49
|
+
const { Stagehand } = await import('@browserbasehq/stagehand');
|
|
50
|
+
const isLocal = this.stagehandOptions.env === 'LOCAL' || !this.stagehandOptions.env;
|
|
51
|
+
// Use anonymizeProxy to handle proxy authentication transparently
|
|
52
|
+
const [anonymizedProxyUrl, closeAnonymizedProxy] = await (0, browser_pool_1.anonymizeProxySugar)(proxyUrl);
|
|
53
|
+
// Build model configuration
|
|
54
|
+
// For LOCAL env, we merge apiKey into the model config since Stagehand expects it there
|
|
55
|
+
let modelConfig = this.stagehandOptions.model;
|
|
56
|
+
if (isLocal && this.stagehandOptions.apiKey) {
|
|
57
|
+
const modelName = typeof modelConfig === 'string' ? modelConfig : modelConfig?.modelName;
|
|
58
|
+
modelConfig = {
|
|
59
|
+
...(typeof modelConfig === 'object' ? modelConfig : {}),
|
|
60
|
+
...(modelName ? { modelName } : {}),
|
|
61
|
+
apiKey: this.stagehandOptions.apiKey,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Build Stagehand configuration by spreading our options and adding launch options
|
|
65
|
+
const stagehandConfig = {
|
|
66
|
+
...this.stagehandOptions,
|
|
67
|
+
env: this.stagehandOptions.env ?? 'LOCAL',
|
|
68
|
+
model: modelConfig,
|
|
69
|
+
localBrowserLaunchOptions: isLocal
|
|
70
|
+
? {
|
|
71
|
+
headless: launchOptions.headless,
|
|
72
|
+
args: launchOptions.args,
|
|
73
|
+
executablePath: launchOptions.executablePath,
|
|
74
|
+
proxy: anonymizedProxyUrl ? { server: anonymizedProxyUrl } : launchOptions.proxy,
|
|
75
|
+
viewport: launchOptions.viewport,
|
|
76
|
+
}
|
|
77
|
+
: undefined,
|
|
78
|
+
};
|
|
79
|
+
const stagehand = new Stagehand(stagehandConfig);
|
|
80
|
+
try {
|
|
81
|
+
// Initialize Stagehand (launches browser)
|
|
82
|
+
await stagehand.init();
|
|
83
|
+
// Get CDP URL and connect Playwright to the same browser
|
|
84
|
+
const cdpUrl = stagehand.connectURL();
|
|
85
|
+
if (!cdpUrl) {
|
|
86
|
+
throw new Error('Failed to get CDP URL from Stagehand');
|
|
87
|
+
}
|
|
88
|
+
const browser = await playwright_1.chromium.connectOverCDP(cdpUrl);
|
|
89
|
+
// Store the Stagehand instance for AI operations
|
|
90
|
+
this.stagehandInstances.set(browser, stagehand);
|
|
91
|
+
// Handle browser disconnection - cleanup both Stagehand and anonymized proxy
|
|
92
|
+
browser.on('disconnected', async () => {
|
|
93
|
+
await this._cleanupStagehand(browser);
|
|
94
|
+
await closeAnonymizedProxy();
|
|
95
|
+
});
|
|
96
|
+
return browser;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
// Clean up on failure
|
|
100
|
+
await stagehand.close().catch(() => { });
|
|
101
|
+
await closeAnonymizedProxy();
|
|
102
|
+
const augmentedError = this._augmentLaunchError(error, launchContext);
|
|
103
|
+
log_1.default.error('Stagehand browser launch failed', { message: augmentedError.message });
|
|
104
|
+
throw augmentedError;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Cleans up Stagehand instance when browser disconnects.
|
|
109
|
+
*/
|
|
110
|
+
async _cleanupStagehand(browser) {
|
|
111
|
+
const stagehand = this.stagehandInstances.get(browser);
|
|
112
|
+
if (stagehand) {
|
|
113
|
+
try {
|
|
114
|
+
await stagehand.close();
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Ignore cleanup errors
|
|
118
|
+
}
|
|
119
|
+
this.stagehandInstances.delete(browser);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Creates a controller for the Stagehand browser.
|
|
124
|
+
*/
|
|
125
|
+
_createController() {
|
|
126
|
+
return new stagehand_controller_1.StagehandController(this, this.stagehandInstances);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Adds proxy configuration to launch options.
|
|
130
|
+
*/
|
|
131
|
+
async _addProxyToLaunchOptions(launchContext) {
|
|
132
|
+
launchContext.launchOptions ?? (launchContext.launchOptions = {});
|
|
133
|
+
const { launchOptions, proxyUrl } = launchContext;
|
|
134
|
+
if (proxyUrl) {
|
|
135
|
+
const url = new URL(proxyUrl);
|
|
136
|
+
launchOptions.proxy = {
|
|
137
|
+
server: url.origin,
|
|
138
|
+
username: decodeURIComponent(url.username),
|
|
139
|
+
password: decodeURIComponent(url.password),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Determines if this is a Chromium-based browser.
|
|
145
|
+
*/
|
|
146
|
+
_isChromiumBasedBrowser() {
|
|
147
|
+
const name = this.library?.name?.();
|
|
148
|
+
return name === 'chromium';
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Augments launch errors with helpful context.
|
|
152
|
+
*/
|
|
153
|
+
_augmentLaunchError(error, launchContext) {
|
|
154
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
155
|
+
const model = this.stagehandOptions.model;
|
|
156
|
+
let helpText = '';
|
|
157
|
+
if (typeof model === 'string') {
|
|
158
|
+
const modelStr = model.toLowerCase();
|
|
159
|
+
if (modelStr.startsWith('openai/')) {
|
|
160
|
+
helpText += '\nNote: OpenAI models require apiKey option or OPENAI_API_KEY environment variable.';
|
|
161
|
+
}
|
|
162
|
+
else if (modelStr.startsWith('anthropic/')) {
|
|
163
|
+
helpText += '\nNote: Anthropic models require apiKey option or ANTHROPIC_API_KEY environment variable.';
|
|
164
|
+
}
|
|
165
|
+
else if (modelStr.startsWith('google/')) {
|
|
166
|
+
helpText += '\nNote: Google models require apiKey option or GOOGLE_API_KEY environment variable.';
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return new Error(`Stagehand browser launch failed: ${message}\n` +
|
|
170
|
+
`Executable path: ${launchContext.launchOptions?.executablePath ?? 'default'}\n` +
|
|
171
|
+
`Model: ${model}${helpText}`, { cause: error });
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Gets the Stagehand instance for a given browser.
|
|
175
|
+
*/
|
|
176
|
+
getStagehandForBrowser(browser) {
|
|
177
|
+
return this.stagehandInstances.get(browser);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.StagehandPlugin = StagehandPlugin;
|
|
181
|
+
//# sourceMappingURL=stagehand-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stagehand-plugin.js","sourceRoot":"","sources":["../../src/internals/stagehand-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Stagehand } from '@browserbasehq/stagehand';
|
|
2
|
+
import type { Page } from 'playwright';
|
|
3
|
+
import type { StagehandPage } from '../stagehand-crawler';
|
|
4
|
+
/**
|
|
5
|
+
* Enhances a Playwright Page with Stagehand AI methods.
|
|
6
|
+
* Adds page.act(), page.extract(), page.observe(), and page.agent() methods.
|
|
7
|
+
*
|
|
8
|
+
* The key feature is that each AI method passes the specific page to Stagehand,
|
|
9
|
+
* allowing multiple pages to use AI operations concurrently without interference.
|
|
10
|
+
*
|
|
11
|
+
* @param page - The Playwright page to enhance
|
|
12
|
+
* @param stagehand - The Stagehand instance to bind methods from
|
|
13
|
+
* @returns The enhanced page with AI methods
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const enhancedPage = enhancePageWithStagehand(page, stagehand);
|
|
18
|
+
* await enhancedPage.act('Click the button');
|
|
19
|
+
* const data = await enhancedPage.extract('Get title', schema);
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @ignore
|
|
23
|
+
*/
|
|
24
|
+
export declare function enhancePageWithStagehand(page: Page, stagehand: Stagehand): StagehandPage;
|
|
25
|
+
//# sourceMappingURL=stagehand-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stagehand-utils.d.ts","sourceRoot":"","sources":["../../../src/internals/utils/stagehand-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2D,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACnH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAgC1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,GAAG,aAAa,CA2ExF"}
|