@browserbasehq/stagehand 4.1.0 → 4.1.1-alpha-e9cb6aaf166da8342018ec8d3f9e5290955ea953
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/README.md +399 -92
- package/dist/assets/stagehand-extension.zip +0 -0
- package/dist/extension/service-worker.js +525 -398
- package/dist/index.mjs +30 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,8 +9,14 @@
|
|
|
9
9
|
</ul>
|
|
10
10
|
</div>
|
|
11
11
|
<p align="center">
|
|
12
|
-
<strong>Stagehand is the SDK
|
|
13
|
-
|
|
12
|
+
<strong>Stagehand is the SDK to extract data and interact with any site on the web.</strong><br>
|
|
13
|
+
Playwright was built for testing. Stagehand is built for agents, in TypeScript, Python, and Go.
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="https://docs.stagehand.dev"><strong>Docs</strong></a> ·
|
|
18
|
+
<a href="https://docs.stagehand.dev/v4/first-steps/quickstart"><strong>Quickstart</strong></a> ·
|
|
19
|
+
<a href="https://github.com/browserbase/stagehand/stargazers"><strong>⭐ Star this repo</strong></a>
|
|
14
20
|
</p>
|
|
15
21
|
|
|
16
22
|
<p align="center">
|
|
@@ -26,123 +32,443 @@
|
|
|
26
32
|
<img alt="Discord Community" src="media/light_discord.svg" />
|
|
27
33
|
</picture>
|
|
28
34
|
</a>
|
|
29
|
-
</p>
|
|
30
|
-
|
|
31
|
-
<p align="center">
|
|
32
|
-
<a href="https://trendshift.io/repositories/12122" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12122" alt="browserbase%2Fstagehand | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
|
33
|
-
</p>
|
|
34
|
-
|
|
35
|
-
<p align="center">
|
|
36
35
|
<a href="https://deepwiki.com/browserbase/stagehand">
|
|
37
36
|
<img alt="Ask DeepWiki" src="https://deepwiki.com/badge.svg" />
|
|
38
37
|
</a>
|
|
39
38
|
</p>
|
|
40
39
|
|
|
41
|
-
##
|
|
40
|
+
## AI that uses the browser like humans.
|
|
41
|
+
|
|
42
|
+
Sign in once, keep the session, and pull structured data out the other side.
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { localBrowser, Stagehand } from "@browserbasehq/stagehand";
|
|
46
|
+
import { z } from "zod/v4";
|
|
47
|
+
|
|
48
|
+
// Cookies persist in ./browser-data, so the next run starts already signed in
|
|
49
|
+
const browser = await localBrowser.launch({ userDataDir: "./browser-data" });
|
|
50
|
+
const stagehand = await Stagehand.create({
|
|
51
|
+
browser,
|
|
52
|
+
model: { modelName: "openai/gpt-5.4-mini", apiKey: process.env.OPENAI_API_KEY },
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const [page] = await browser.context.pages();
|
|
56
|
+
await page.goto("https://app.example.com/login");
|
|
57
|
+
|
|
58
|
+
// observe() returns real selectors, so credentials never reach the model
|
|
59
|
+
const { data: email } = await stagehand.observe("find the email input");
|
|
60
|
+
const { data: password } = await stagehand.observe("find the password input");
|
|
61
|
+
await page.locator(email[0].selector).fill(process.env.APP_EMAIL!);
|
|
62
|
+
await page.locator(password[0].selector).fill(process.env.APP_PASSWORD!);
|
|
42
63
|
|
|
43
|
-
|
|
64
|
+
// act() self-heals when the site redesigns its form
|
|
65
|
+
await stagehand.act("click the sign in button");
|
|
66
|
+
await stagehand.act("open the billing page");
|
|
67
|
+
|
|
68
|
+
// extract() returns schema-validated data
|
|
69
|
+
const { data } = await stagehand.extract(
|
|
70
|
+
"extract every invoice in the table",
|
|
71
|
+
z.object({
|
|
72
|
+
invoices: z.array(z.object({ number: z.string(), amount: z.number(), paid: z.boolean() })),
|
|
73
|
+
}),
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
console.log(data.invoices);
|
|
77
|
+
|
|
78
|
+
await stagehand.close();
|
|
79
|
+
await browser.close();
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
<details>
|
|
83
|
+
<summary><b>Python</b></summary>
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import asyncio
|
|
87
|
+
import os
|
|
88
|
+
|
|
89
|
+
from pydantic import BaseModel
|
|
90
|
+
from stagehand import Stagehand, local_browser
|
|
44
91
|
|
|
45
|
-
## Why Stagehand?
|
|
46
92
|
|
|
47
|
-
|
|
93
|
+
class Invoice(BaseModel):
|
|
94
|
+
number: str
|
|
95
|
+
amount: float
|
|
96
|
+
paid: bool
|
|
48
97
|
|
|
49
|
-
Agents use fewer tokens, recover when websites change, and complete tasks more reliably. With a complete browser driver across TypeScript, Python, and Go, Stagehand delivers the flexibility of AI without sacrificing the speed, control, determinism, reliability, and observability required in production.
|
|
50
98
|
|
|
51
|
-
|
|
99
|
+
class Invoices(BaseModel):
|
|
100
|
+
invoices: list[Invoice]
|
|
52
101
|
|
|
53
|
-
The Playwright-style methods you and your agents already know and love (`goto`, `click`, `locator`, `screenshot`).
|
|
54
102
|
|
|
55
|
-
|
|
103
|
+
async def main() -> None:
|
|
104
|
+
# Cookies persist in ./browser-data, so the next run starts already signed in
|
|
105
|
+
browser = await local_browser.launch(user_data_dir="./browser-data")
|
|
106
|
+
try:
|
|
107
|
+
stagehand = await Stagehand.create(
|
|
108
|
+
browser=browser,
|
|
109
|
+
model="openai/gpt-5.4-mini",
|
|
110
|
+
model_api_key=os.environ["OPENAI_API_KEY"],
|
|
111
|
+
)
|
|
112
|
+
try:
|
|
113
|
+
page = (await browser.context.pages())[0]
|
|
114
|
+
await page.goto("https://app.example.com/login")
|
|
56
115
|
|
|
57
|
-
|
|
116
|
+
# observe() returns real selectors, so credentials never reach the model
|
|
117
|
+
email = await stagehand.observe("find the email input")
|
|
118
|
+
password = await stagehand.observe("find the password input")
|
|
119
|
+
await page.locator(email.data[0].selector).fill(os.environ["APP_EMAIL"])
|
|
120
|
+
await page.locator(password.data[0].selector).fill(os.environ["APP_PASSWORD"])
|
|
58
121
|
|
|
59
|
-
|
|
122
|
+
# act() self-heals when the site redesigns its form
|
|
123
|
+
await stagehand.act("click the sign in button")
|
|
124
|
+
await stagehand.act("open the billing page")
|
|
60
125
|
|
|
61
|
-
|
|
126
|
+
# extract() returns schema-validated data
|
|
127
|
+
result = await stagehand.extract(
|
|
128
|
+
"extract every invoice in the table",
|
|
129
|
+
Invoices,
|
|
130
|
+
)
|
|
131
|
+
print(result.data.invoices)
|
|
132
|
+
finally:
|
|
133
|
+
await stagehand.close()
|
|
134
|
+
finally:
|
|
135
|
+
await browser.close()
|
|
62
136
|
|
|
63
|
-
### 4. Self-healing primitives
|
|
64
137
|
|
|
65
|
-
|
|
138
|
+
asyncio.run(main())
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
</details>
|
|
142
|
+
|
|
143
|
+
<details>
|
|
144
|
+
<summary><b>Go</b></summary>
|
|
145
|
+
|
|
146
|
+
```go
|
|
147
|
+
package main
|
|
148
|
+
|
|
149
|
+
import (
|
|
150
|
+
"context"
|
|
151
|
+
"errors"
|
|
152
|
+
"fmt"
|
|
153
|
+
"log"
|
|
154
|
+
"os"
|
|
155
|
+
|
|
156
|
+
stagehand "github.com/browserbase/stagehand/packages/sdk-go/v4"
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
type invoice struct {
|
|
160
|
+
Number string `json:"number"`
|
|
161
|
+
Amount float64 `json:"amount"`
|
|
162
|
+
Paid bool `json:"paid"`
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
type invoices struct {
|
|
166
|
+
Invoices []invoice `json:"invoices"`
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
func main() {
|
|
170
|
+
if err := run(context.Background()); err != nil {
|
|
171
|
+
log.Fatal(err)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
func run(ctx context.Context) (err error) {
|
|
176
|
+
// Cookies persist in ./browser-data, so the next run starts already signed in
|
|
177
|
+
browser, err := stagehand.LaunchLocalBrowser(ctx, &stagehand.LocalBrowserLaunchOptions{
|
|
178
|
+
UserDataDir: "./browser-data",
|
|
179
|
+
})
|
|
180
|
+
if err != nil {
|
|
181
|
+
return err
|
|
182
|
+
}
|
|
183
|
+
defer func() { err = errors.Join(err, browser.Close(ctx)) }()
|
|
184
|
+
|
|
185
|
+
modelAPIKey := os.Getenv("OPENAI_API_KEY")
|
|
186
|
+
client, err := stagehand.Create(ctx, stagehand.CreateOptions{
|
|
187
|
+
Browser: browser,
|
|
188
|
+
Model: &stagehand.ModelConfig{
|
|
189
|
+
ModelName: "openai/gpt-5.4-mini",
|
|
190
|
+
APIKey: &modelAPIKey,
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
if err != nil {
|
|
194
|
+
return err
|
|
195
|
+
}
|
|
196
|
+
defer func() { err = errors.Join(err, client.Close(ctx)) }()
|
|
197
|
+
|
|
198
|
+
browserContext, err := browser.Context()
|
|
199
|
+
if err != nil {
|
|
200
|
+
return err
|
|
201
|
+
}
|
|
202
|
+
pages, err := browserContext.Pages(ctx)
|
|
203
|
+
if err != nil {
|
|
204
|
+
return err
|
|
205
|
+
}
|
|
206
|
+
page := pages[0]
|
|
207
|
+
if _, err := page.Goto(ctx, "https://app.example.com/login", nil); err != nil {
|
|
208
|
+
return err
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Observe returns real selectors, so credentials never reach the model
|
|
212
|
+
emailInstruction := "find the email input"
|
|
213
|
+
email, err := client.Observe(ctx, &emailInstruction, nil)
|
|
214
|
+
if err != nil {
|
|
215
|
+
return err
|
|
216
|
+
}
|
|
217
|
+
if err := page.Locator(email.Data[0].Selector).Fill(ctx, os.Getenv("APP_EMAIL")); err != nil {
|
|
218
|
+
return err
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
passwordInstruction := "find the password input"
|
|
222
|
+
password, err := client.Observe(ctx, &passwordInstruction, nil)
|
|
223
|
+
if err != nil {
|
|
224
|
+
return err
|
|
225
|
+
}
|
|
226
|
+
if err := page.Locator(password.Data[0].Selector).Fill(ctx, os.Getenv("APP_PASSWORD")); err != nil {
|
|
227
|
+
return err
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Act self-heals when the site redesigns its form
|
|
231
|
+
if _, err := client.Act(ctx, stagehand.ActInstruction("click the sign in button"), nil); err != nil {
|
|
232
|
+
return err
|
|
233
|
+
}
|
|
234
|
+
if _, err := client.Act(ctx, stagehand.ActInstruction("open the billing page"), nil); err != nil {
|
|
235
|
+
return err
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Extract returns data decoded into a Go type
|
|
239
|
+
extracted, err := stagehand.Extract[invoices](
|
|
240
|
+
ctx,
|
|
241
|
+
client,
|
|
242
|
+
"extract every invoice in the table",
|
|
243
|
+
nil,
|
|
244
|
+
)
|
|
245
|
+
if err != nil {
|
|
246
|
+
return err
|
|
247
|
+
}
|
|
248
|
+
fmt.Println(extracted.Data.Invoices)
|
|
249
|
+
|
|
250
|
+
return nil
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
</details>
|
|
255
|
+
|
|
256
|
+
## Install
|
|
66
257
|
|
|
67
|
-
|
|
258
|
+
```bash
|
|
259
|
+
pnpm add @browserbasehq/stagehand 'zod@~4.4.3'
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
<details>
|
|
263
|
+
<summary><b>Python</b></summary>
|
|
68
264
|
|
|
69
|
-
|
|
265
|
+
```bash
|
|
266
|
+
pip install stagehand
|
|
267
|
+
```
|
|
70
268
|
|
|
71
|
-
|
|
269
|
+
</details>
|
|
72
270
|
|
|
73
|
-
|
|
271
|
+
<details>
|
|
272
|
+
<summary><b>Go</b></summary>
|
|
74
273
|
|
|
75
|
-
|
|
274
|
+
```bash
|
|
275
|
+
go get github.com/browserbase/stagehand/packages/sdk-go/v4@v4.0.0
|
|
276
|
+
```
|
|
76
277
|
|
|
77
|
-
|
|
278
|
+
</details>
|
|
279
|
+
|
|
280
|
+
Local runs need [Chrome](https://www.google.com/chrome/) installed. Full setup: [Quickstart](https://docs.stagehand.dev/v4/first-steps/quickstart).
|
|
281
|
+
|
|
282
|
+
## Why Stagehand
|
|
283
|
+
|
|
284
|
+
<table>
|
|
285
|
+
<tr>
|
|
286
|
+
<td><strong>Familiar APIs</strong></td>
|
|
287
|
+
<td>The Playwright-style methods you and your agents already know: <code>goto</code>, <code>click</code>, <code>locator</code>, <code>screenshot</code>.</td>
|
|
288
|
+
</tr>
|
|
289
|
+
<tr>
|
|
290
|
+
<td><strong>Token efficiency</strong></td>
|
|
291
|
+
<td>Hybrid accessibility-tree trimming gives agents exactly the page context they need and nothing more.</td>
|
|
292
|
+
</tr>
|
|
293
|
+
<tr>
|
|
294
|
+
<td><strong>Faster in production</strong></td>
|
|
295
|
+
<td>Stagehand runs as an extension next to the browser, cutting round-trip latency on every action.</td>
|
|
296
|
+
</tr>
|
|
297
|
+
<tr>
|
|
298
|
+
<td><strong>Self-healing</strong></td>
|
|
299
|
+
<td><code>act</code>, <code>observe</code>, and <code>extract</code> refresh how an action happens when the site changes underneath it.</td>
|
|
300
|
+
</tr>
|
|
301
|
+
<tr>
|
|
302
|
+
<td><strong>Built for agents</strong></td>
|
|
303
|
+
<td>WebMCP, clipboard support, batch commands, deep locators for nested iframes and closed Shadow DOMs, OTel traces.</td>
|
|
304
|
+
</tr>
|
|
305
|
+
<tr>
|
|
306
|
+
<td><strong>Three languages</strong></td>
|
|
307
|
+
<td>One complete browser driver across TypeScript, Python, and Go.</td>
|
|
308
|
+
</tr>
|
|
309
|
+
</table>
|
|
310
|
+
|
|
311
|
+
## Run it on Browserbase
|
|
312
|
+
|
|
313
|
+
Point the same script at [Browserbase](https://www.browserbase.com) and get 2x faster execution than Playwright cloud equivalent browsers. Configure the [Model Gateway](https://docs.stagehand.dev/v4/configuration/models#model-gateway) so you never wire up a provider, and enable [server-side caching](https://docs.stagehand.dev/v4/best-practices/caching) to cache repeated actions.
|
|
78
314
|
|
|
79
315
|
```typescript
|
|
80
316
|
import { browserbase, Stagehand } from "@browserbasehq/stagehand";
|
|
81
|
-
import { z } from "zod/v4";
|
|
82
317
|
|
|
83
|
-
const
|
|
318
|
+
const browser = await browserbase.launch({ apiKey: process.env.BROWSERBASE_API_KEY! });
|
|
84
319
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
});
|
|
320
|
+
// No model configuration: the Model Gateway picks the cheapest model for each action
|
|
321
|
+
// cache: true: identical calls come back from Browserbase, no tokens spent
|
|
322
|
+
const stagehand = await Stagehand.create({ browser, cache: true });
|
|
323
|
+
```
|
|
88
324
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
model: {
|
|
92
|
-
modelName: "openai/gpt-5.4-mini",
|
|
93
|
-
apiKey: OPENAI_API_KEY,
|
|
94
|
-
},
|
|
95
|
-
});
|
|
325
|
+
<details>
|
|
326
|
+
<summary><b>Python</b></summary>
|
|
96
327
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
328
|
+
```python
|
|
329
|
+
import os
|
|
330
|
+
|
|
331
|
+
from stagehand import Stagehand, browserbase
|
|
100
332
|
|
|
101
|
-
|
|
102
|
-
await stagehand.act("click on the stagehand repo");
|
|
333
|
+
browser = await browserbase.launch(api_key=os.environ["BROWSERBASE_API_KEY"])
|
|
103
334
|
|
|
104
|
-
|
|
105
|
-
|
|
335
|
+
# No model configuration: the Model Gateway picks the cheapest model for each action
|
|
336
|
+
# cache=True: identical calls come back from Browserbase, no tokens spent
|
|
337
|
+
stagehand = await Stagehand.create(browser=browser, cache=True)
|
|
338
|
+
```
|
|
106
339
|
|
|
107
|
-
|
|
108
|
-
|
|
340
|
+
</details>
|
|
341
|
+
|
|
342
|
+
<details>
|
|
343
|
+
<summary><b>Go</b></summary>
|
|
344
|
+
|
|
345
|
+
```go
|
|
346
|
+
browser, err := stagehand.LaunchBrowserbase(ctx, stagehand.BrowserbaseLaunchOptions{
|
|
347
|
+
APIKey: os.Getenv("BROWSERBASE_API_KEY"),
|
|
348
|
+
})
|
|
349
|
+
if err != nil {
|
|
350
|
+
return err
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// No model configuration: the Model Gateway picks the cheapest model for each action
|
|
354
|
+
// CacheEnabled(true): identical calls come back from Browserbase, no tokens spent
|
|
355
|
+
cache := stagehand.CacheEnabled(true)
|
|
356
|
+
client, err := stagehand.Create(ctx, stagehand.CreateOptions{
|
|
357
|
+
Browser: browser,
|
|
358
|
+
Cache: &cache,
|
|
359
|
+
})
|
|
360
|
+
if err != nil {
|
|
361
|
+
return err
|
|
362
|
+
}
|
|
363
|
+
```
|
|
109
364
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
365
|
+
</details>
|
|
366
|
+
|
|
367
|
+
[Verified mode](https://docs.browserbase.com/platform/identity/verified-customization), [residential proxies](https://docs.browserbase.com/platform/identity/proxies), [persistent contexts](https://docs.browserbase.com/platform/browser/core-features/contexts), and [session recordings](https://docs.browserbase.com/platform/browser/observability/session-replay) come with it. [Get an API key](https://www.browserbase.com/overview) and learn how to configure your browser [here](https://docs.stagehand.dev/v4/configuration/browser).
|
|
368
|
+
|
|
369
|
+
## Give your coding agent a browser
|
|
370
|
+
|
|
371
|
+
The hosted Browserbase [MCP server](https://docs.stagehand.dev/integrations/mcp/setup) puts `navigate`, `act`, `observe`, and `extract` in any MCP client — no install, no local browser.
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
claude mcp add --transport http browserbase https://mcp.browserbase.com/mcp \
|
|
375
|
+
--header "Authorization: Bearer $BROWSERBASE_API_KEY"
|
|
120
376
|
```
|
|
121
377
|
|
|
122
|
-
|
|
378
|
+
<details>
|
|
379
|
+
<summary><b>Cursor, Codex, and other MCP clients</b></summary>
|
|
380
|
+
|
|
381
|
+
```json
|
|
382
|
+
{
|
|
383
|
+
"mcpServers": {
|
|
384
|
+
"browserbase": {
|
|
385
|
+
"url": "https://mcp.browserbase.com/mcp",
|
|
386
|
+
"headers": { "Authorization": "Bearer YOUR_BROWSERBASE_API_KEY" }
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
</details>
|
|
393
|
+
|
|
394
|
+
## Search and fetch without a browser
|
|
123
395
|
|
|
124
|
-
|
|
396
|
+
[Fetch](https://docs.stagehand.dev/v4/add-ons/fetch) lets you grab the content of any URL as markdown. [Search](https://docs.stagehand.dev/v4/add-ons/search) provides fast, token-efficient web search results.
|
|
397
|
+
Both as a lightweight complement to browser sessions.
|
|
125
398
|
|
|
126
399
|
```typescript
|
|
127
|
-
|
|
128
|
-
|
|
400
|
+
import { browserbase } from "@browserbasehq/stagehand";
|
|
401
|
+
|
|
402
|
+
const { results } = await browserbase.search({
|
|
403
|
+
apiKey: process.env.BROWSERBASE_API_KEY!,
|
|
129
404
|
query: "browser agent frameworks",
|
|
130
405
|
numResults: 5,
|
|
131
406
|
});
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
407
|
+
|
|
408
|
+
const fetched = await browserbase.fetch({
|
|
409
|
+
apiKey: process.env.BROWSERBASE_API_KEY!,
|
|
410
|
+
url: results[0].url,
|
|
135
411
|
format: "markdown",
|
|
136
412
|
});
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## Documentation
|
|
140
|
-
|
|
141
|
-
Visit [docs.stagehand.dev](https://docs.stagehand.dev) to view the full documentation.
|
|
142
413
|
|
|
143
|
-
|
|
414
|
+
console.log(fetched.content);
|
|
415
|
+
```
|
|
144
416
|
|
|
145
|
-
|
|
417
|
+
## Docs and resources
|
|
418
|
+
|
|
419
|
+
<table>
|
|
420
|
+
<tr>
|
|
421
|
+
<td><a href="https://docs.stagehand.dev/v4/first-steps/quickstart">Quickstart</a></td>
|
|
422
|
+
<td>Empty directory to working automation in three steps</td>
|
|
423
|
+
</tr>
|
|
424
|
+
<tr>
|
|
425
|
+
<td><a href="https://docs.stagehand.dev/v4/reference/page">page</a> · <a href="https://docs.stagehand.dev/v4/reference/locator">locator</a></td>
|
|
426
|
+
<td>Playwright-style browser and element APIs</td>
|
|
427
|
+
</tr>
|
|
428
|
+
<tr>
|
|
429
|
+
<td><a href="https://docs.stagehand.dev/v4/basics/webmcp">WebMCP</a></td>
|
|
430
|
+
<td>Discover and invoke WebMCP tools exposed by web pages</td>
|
|
431
|
+
</tr>
|
|
432
|
+
<tr>
|
|
433
|
+
<td><a href="https://docs.stagehand.dev/v4/basics/act">act</a> · <a href="https://docs.stagehand.dev/v4/basics/extract">extract</a> · <a href="https://docs.stagehand.dev/v4/basics/observe">observe</a></td>
|
|
434
|
+
<td>Browser actions and data extraction with natural language</td>
|
|
435
|
+
</tr>
|
|
436
|
+
<tr>
|
|
437
|
+
<td><a href="https://docs.stagehand.dev/v4/add-ons/search">Search</a> · <a href="https://docs.stagehand.dev/v4/add-ons/fetch">Fetch</a></td>
|
|
438
|
+
<td>Web search and page content without a browser</td>
|
|
439
|
+
</tr>
|
|
440
|
+
<tr>
|
|
441
|
+
<td><a href="https://docs.stagehand.dev/v4/migrations/playwright">Migrate from Playwright</a></td>
|
|
442
|
+
<td>Port an existing suite</td>
|
|
443
|
+
</tr>
|
|
444
|
+
<tr>
|
|
445
|
+
<td><a href="https://docs.stagehand.dev/v4/integrations/overview">Integrations</a></td>
|
|
446
|
+
<td>CrewAI, Mastra, Deep Agents, Vercel AI SDK, Claude Code, Codex</td>
|
|
447
|
+
</tr>
|
|
448
|
+
<tr>
|
|
449
|
+
<td><a href="./packages/sdk-python/README.md">Python SDK</a> · <a href="./packages/sdk-go/README.md">Go SDK</a></td>
|
|
450
|
+
<td>Language-specific guides</td>
|
|
451
|
+
</tr>
|
|
452
|
+
<tr>
|
|
453
|
+
<td><a href="https://deepwiki.com/browserbase/stagehand">Ask DeepWiki</a></td>
|
|
454
|
+
<td>Ask questions about this codebase</td>
|
|
455
|
+
</tr>
|
|
456
|
+
</table>
|
|
457
|
+
|
|
458
|
+
## Join the community
|
|
459
|
+
|
|
460
|
+
Stagehand is built in the open, and the fastest way to shape it is to show up.
|
|
461
|
+
|
|
462
|
+
- **[⭐ Star this repo](https://github.com/browserbase/stagehand/stargazers)** — it is how most people find Stagehand
|
|
463
|
+
- **[💬 Join the Discord](https://discord.gg/stagehand)** — questions, support, and what we are building next
|
|
464
|
+
- **[🐛 Open an issue](https://github.com/browserbase/stagehand/issues)** — bug reports are the most useful contribution
|
|
465
|
+
- **[𝕏 Follow @stagehanddev](https://x.com/stagehanddev)** — releases and demos
|
|
466
|
+
|
|
467
|
+
### Contributing
|
|
468
|
+
|
|
469
|
+
We're focused on improving reliability, extensibility, speed, and cost, in that order. **Bug fixes and small improvements are the best way to get started.** For anything larger, reach out to [Miguel Gonzalez](https://x.com/miguel_gonzf) or [Paul Klein](https://x.com/pk_iv) on [Discord](https://discord.gg/stagehand) first so we can make sure it lands.
|
|
470
|
+
|
|
471
|
+
Stagehand is a TypeScript, Python, and Go monorepo driven by [`just`](https://github.com/casey/just):
|
|
146
472
|
|
|
147
473
|
```bash
|
|
148
474
|
git clone https://github.com/browserbase/stagehand.git
|
|
@@ -150,32 +476,13 @@ cd stagehand
|
|
|
150
476
|
just install
|
|
151
477
|
just generate
|
|
152
478
|
just build
|
|
153
|
-
```
|
|
154
479
|
|
|
155
|
-
Stagehand is best when you have an API key for an LLM provider and Browserbase credentials. Export them so they're available on `process.env`:
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
480
|
export OPENAI_API_KEY="your-openai-api-key"
|
|
159
|
-
export BROWSERBASE_API_KEY="your-browserbase-api-key"
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Then run any of the scripts in [`packages/sdk-ts/examples`](./packages/sdk-ts/examples):
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
481
|
just example act # runs packages/sdk-ts/examples/act.ts
|
|
166
482
|
```
|
|
167
483
|
|
|
168
484
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full TypeScript, Python, and Go setup.
|
|
169
485
|
|
|
170
|
-
## Contributing
|
|
171
|
-
|
|
172
|
-
> [!NOTE]
|
|
173
|
-
> We highly value contributions to Stagehand! For questions or support, please join our [Discord community](https://discord.gg/stagehand).
|
|
174
|
-
|
|
175
|
-
We're focused on improving reliability, extensibility, speed, and cost in that order of priority. If you're interested in contributing, **bug fixes and small improvements are the best way to get started**. For more involved features, we strongly recommend reaching out to [Miguel Gonzalez](https://x.com/miguel_gonzf) or [Paul Klein](https://x.com/pk_iv) in our [Discord community](https://discord.gg/stagehand) before starting to ensure that your contribution aligns with our goals.
|
|
176
|
-
|
|
177
|
-
<!-- For more information, please see our [CONTRIBUTING.md](CONTRIBUTING.md) -->
|
|
178
|
-
|
|
179
486
|
## Acknowledgements
|
|
180
487
|
|
|
181
488
|
We'd like to thank the following people for their major contributions to Stagehand:
|
|
Binary file
|