@mastra/stagehand 0.1.0-alpha.0 → 0.2.0-alpha.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/dist/index.d.cts CHANGED
@@ -108,11 +108,11 @@ declare const stagehandSchemas: {
108
108
  };
109
109
 
110
110
  /**
111
- * StagehandThreadManager - Thread isolation for StagehandBrowser
111
+ * StagehandThreadManager - Thread scope management for StagehandBrowser
112
112
  *
113
113
  * Supports two scope modes:
114
- * - 'none': All threads share the same Stagehand instance and page
115
- * - 'browser': Each thread gets its own Stagehand instance (separate browser)
114
+ * - 'shared': All threads share the same Stagehand instance and page
115
+ * - 'thread': Each thread gets its own Stagehand instance (separate browser)
116
116
  *
117
117
  * @see AgentBrowserThreadManager for the equivalent implementation.
118
118
  */
@@ -139,49 +139,23 @@ interface StagehandThreadManagerConfig extends ThreadManagerConfig {
139
139
  * Thread manager for StagehandBrowser.
140
140
  *
141
141
  * Supports two scope modes:
142
- * - 'none': All threads share the shared Stagehand instance
143
- * - 'browser': Each thread gets a dedicated Stagehand instance
142
+ * - 'shared': All threads share the shared Stagehand instance
143
+ * - 'thread': Each thread gets a dedicated Stagehand instance
144
144
  */
145
- declare class StagehandThreadManager extends ThreadManager<V3Page$1 | V3> {
146
- private sharedStagehand;
145
+ declare class StagehandThreadManager extends ThreadManager<V3> {
147
146
  protected sessions: Map<string, StagehandThreadSession>;
148
147
  private createStagehand?;
149
148
  private onBrowserCreated?;
150
- /** Map of thread ID to dedicated Stagehand instance (for 'thread' mode) */
151
- private readonly threadStagehands;
152
149
  constructor(config: StagehandThreadManagerConfig);
153
- /**
154
- * Set the shared Stagehand instance (called after browser launch).
155
- */
156
- setStagehand(instance: V3): void;
157
- /**
158
- * Clear the shared Stagehand instance (called when browser disconnects).
159
- */
160
- clearStagehand(): void;
161
150
  /**
162
151
  * Set the factory function for creating new Stagehand instances.
163
- * Required for 'browser' scope mode.
152
+ * Required for 'thread' scope mode.
164
153
  */
165
154
  setCreateStagehand(factory: () => Promise<V3>): void;
166
155
  /**
167
- * Get the shared Stagehand instance.
168
- */
169
- getSharedStagehand(): V3;
170
- /**
171
- * Get the Stagehand instance for a specific thread.
172
- * In 'shared' mode, returns the shared instance.
173
- * In 'thread' mode, returns the thread's dedicated instance.
174
- */
175
- getStagehandForThread(threadId: string): V3 | undefined;
176
- /**
177
- * Get the Stagehand page for a thread.
178
- * Returns the active page from the thread's Stagehand instance.
179
- */
180
- getPageForThread(threadId: string): V3Page$1 | undefined;
181
- /**
182
- * Get the shared manager - returns the active page or the Stagehand instance.
156
+ * Get the page for a specific thread, creating session if needed.
183
157
  */
184
- protected getSharedManager(): V3Page$1 | V3;
158
+ getPageForThread(threadId?: string): Promise<V3Page$1 | null>;
185
159
  /**
186
160
  * Create a new session for a thread.
187
161
  */
@@ -191,39 +165,18 @@ declare class StagehandThreadManager extends ThreadManager<V3Page$1 | V3> {
191
165
  */
192
166
  private restoreBrowserState;
193
167
  /**
194
- * Switch to an existing session.
195
- * For 'thread' mode, no switching needed - each thread has its own instance.
196
- * For 'shared' mode, nothing to switch.
197
- */
198
- protected switchToSession(_session: StagehandThreadSession): Promise<void>;
199
- /**
200
- * Get the manager for a specific session.
168
+ * Get the manager (Stagehand instance) for a specific session.
201
169
  */
202
- protected getManagerForSession(session: StagehandThreadSession): V3Page$1 | V3;
170
+ protected getManagerForSession(session: StagehandThreadSession): V3;
203
171
  /**
204
172
  * Destroy a session and clean up resources.
205
173
  */
206
174
  protected doDestroySession(session: StagehandThreadSession): Promise<void>;
207
175
  /**
208
- * Clean up all thread sessions.
176
+ * Destroy all sessions (called during browser close).
177
+ * doDestroySession handles closing individual Stagehand instances.
209
178
  */
210
- destroyAll(): Promise<void>;
211
- /**
212
- * Check if any thread Stagehands are still running.
213
- */
214
- hasActiveThreadStagehands(): boolean;
215
- /**
216
- * Clear all session tracking without closing browsers.
217
- * Used when browsers have been externally closed and we just need to reset state.
218
- */
219
- clearAllSessions(): void;
220
- /**
221
- * Clear a specific thread's session without closing the browser.
222
- * Used when a thread's browser has been externally closed.
223
- * Preserves the browser state for potential restoration.
224
- * @param threadId - The thread ID to clear
225
- */
226
- clearSession(threadId: string): void;
179
+ destroyAllSessions(): Promise<void>;
227
180
  }
228
181
 
229
182
  /**
@@ -239,9 +192,9 @@ type ModelConfiguration = string | {
239
192
  baseURL?: string;
240
193
  };
241
194
  /**
242
- * Configuration for StagehandBrowser
195
+ * Stagehand-specific configuration fields.
243
196
  */
244
- interface StagehandBrowserConfig extends BrowserConfig {
197
+ interface StagehandConfigExtensions {
245
198
  /**
246
199
  * Environment to run the browser in
247
200
  * - 'LOCAL': Run browser locally
@@ -285,7 +238,22 @@ interface StagehandBrowserConfig extends BrowserConfig {
285
238
  * Custom system prompt for AI operations (act, extract, observe)
286
239
  */
287
240
  systemPrompt?: string;
241
+ /**
242
+ * Whether to preserve the user data directory after the browser closes.
243
+ * By default, Stagehand may clean up temporary user data directories.
244
+ * Set to `true` to keep the profile data for future sessions.
245
+ *
246
+ * Only applicable when `profile` is provided.
247
+ *
248
+ * @default false
249
+ */
250
+ preserveUserDataDir?: boolean;
288
251
  }
252
+ /**
253
+ * Configuration for StagehandBrowser.
254
+ * Extends the base BrowserConfig with Stagehand-specific options.
255
+ */
256
+ type StagehandBrowserConfig = BrowserConfig & StagehandConfigExtensions;
289
257
  /**
290
258
  * Action returned from observe()
291
259
  */
@@ -345,31 +313,22 @@ type V3Page = NonNullable<ReturnType<NonNullable<Stagehand['context']>['activePa
345
313
  * Unlike AgentBrowser which uses refs ([ref=e1]), StagehandBrowser uses
346
314
  * natural language instructions for all interactions.
347
315
  *
348
- * Supports thread isolation via the scope config:
349
- * - 'none': All threads share the same Stagehand instance
350
- * - 'browser': Each thread gets its own Stagehand instance (separate browser)
316
+ * Supports thread scope via the scope config:
317
+ * - 'shared': All threads share the same Stagehand instance
318
+ * - 'thread': Each thread gets its own Stagehand instance (separate browser)
351
319
  */
352
320
  declare class StagehandBrowser extends MastraBrowser {
353
321
  readonly id: string;
354
322
  readonly name = "StagehandBrowser";
355
323
  readonly provider = "browserbase/stagehand";
356
- private stagehand;
324
+ /** Shared Stagehand instance (for 'shared' scope) - narrowed type from base class */
325
+ protected sharedManager: Stagehand | null;
357
326
  private stagehandConfig;
358
327
  /** Thread manager - narrowed type from base class */
359
328
  protected threadManager: StagehandThreadManager;
360
- /** Active screencast streams per thread (for reconnection on tab changes) */
361
- private activeScreencastStreams;
362
329
  /** Debounce timers per thread for tab change reconnection */
363
330
  private tabChangeDebounceTimers;
364
- /** Default key for shared scope */
365
- private static readonly SHARED_STREAM_KEY;
366
331
  constructor(config?: StagehandBrowserConfig);
367
- /**
368
- * Close a specific thread's browser session.
369
- * For 'thread' scope, this closes only that thread's Stagehand instance.
370
- * For 'shared' scope, this is a no-op (use close() to close the shared browser).
371
- */
372
- closeThreadSession(threadId: string): Promise<void>;
373
332
  /**
374
333
  * Ensure browser is ready and thread session exists.
375
334
  * For 'thread' scope, this creates a dedicated Stagehand instance for the thread.
@@ -382,37 +341,33 @@ declare class StagehandBrowser extends MastraBrowser {
382
341
  private buildStagehandOptions;
383
342
  /**
384
343
  * Create a new Stagehand instance with the current config.
385
- * Used by thread manager for 'browser' isolation mode.
344
+ * Used by thread manager for 'thread' scope.
386
345
  */
387
346
  private createStagehandInstance;
388
347
  protected doLaunch(): Promise<void>;
389
348
  /**
390
- * Set up close event listener for a Stagehand instance.
349
+ * Set up close event listener for a shared Stagehand instance.
391
350
  * Listens to both context and page close events for robust detection.
392
351
  */
393
- private setupCloseListener;
394
- /**
395
- * Set up close event listener for a thread's Stagehand instance.
396
- * Uses CDP Target.targetDestroyed events to detect when all pages are gone.
397
- */
398
- private setupCloseListenerForThread;
399
352
  /**
400
- * Handle browser disconnection for a specific thread.
401
- * Called when a thread's browser is closed externally.
353
+ * Set up a CDP-based close listener for a Stagehand instance.
354
+ *
355
+ * Tracks page targets via CDP `Target.targetCreated` / `Target.targetDestroyed`.
356
+ * When all page targets are gone the `onDisconnect` callback fires. This is more
357
+ * reliable than Playwright's `context.close` / `page.close` events which don't
358
+ * fire when Chrome is killed externally (SIGTERM/SIGKILL).
402
359
  */
403
- private handleThreadBrowserDisconnected;
360
+ private setupCloseListener;
404
361
  protected doClose(): Promise<void>;
362
+ handleBrowserDisconnected(): void;
363
+ protected handleThreadBrowserDisconnected(threadId: string): void;
364
+ closeThreadSession(threadId: string): Promise<void>;
365
+ private patchExitType;
405
366
  /**
406
367
  * Check if the browser is still alive by verifying the context and pages exist.
407
368
  * Called by base class ensureReady() to detect externally closed browsers.
408
369
  */
409
370
  protected checkBrowserAlive(): Promise<boolean>;
410
- /**
411
- * Handle browser disconnection by clearing internal state.
412
- * For 'thread' scope, only notifies the specific thread's callbacks.
413
- * For 'shared' scope, notifies all callbacks.
414
- */
415
- handleBrowserDisconnected(): void;
416
371
  /**
417
372
  * Create an error response from an exception.
418
373
  * Extends base class to add Stagehand-specific error handling.
@@ -420,10 +375,10 @@ declare class StagehandBrowser extends MastraBrowser {
420
375
  protected createErrorFromException(error: unknown, context: string): BrowserToolError;
421
376
  /**
422
377
  * Get the Stagehand instance for a thread, creating it if needed.
423
- * For 'browser' isolation, this creates a dedicated Stagehand instance.
424
- * For 'none' isolation, returns the shared instance.
378
+ * For 'thread' scope, this creates a dedicated Stagehand instance.
379
+ * For 'shared' scope, returns the shared instance.
425
380
  */
426
- private getStagehandForThread;
381
+ getManagerForThread(threadId?: string): Promise<Stagehand | null>;
427
382
  /**
428
383
  * Require a Stagehand instance for the given or current thread.
429
384
  * Throws if no instance is available.
@@ -432,15 +387,15 @@ declare class StagehandBrowser extends MastraBrowser {
432
387
  */
433
388
  private requireStagehand;
434
389
  /**
435
- * Get the current page from Stagehand v3, respecting thread isolation.
390
+ * Get the current page from Stagehand v3, respecting thread scope.
436
391
  * @param explicitThreadId - Optional thread ID to use instead of getCurrentThread()
437
392
  * Use this to avoid race conditions in concurrent tool calls.
438
393
  */
439
394
  private getPage;
440
395
  /**
441
- * Get the page for a specific thread, creating session if needed.
396
+ * Get the active page for a thread (implements abstract method from base class).
442
397
  */
443
- getPageForThread(threadId: string): Promise<V3Page | null>;
398
+ protected getActivePage(threadId?: string): Promise<V3Page | null>;
444
399
  /**
445
400
  * Get a CDP session for a specific page.
446
401
  */
@@ -522,6 +477,11 @@ declare class StagehandBrowser extends MastraBrowser {
522
477
  * Get the current browser state (all tabs and active tab index).
523
478
  */
524
479
  getBrowserState(threadId?: string): Promise<BrowserState | null>;
480
+ /**
481
+ * Get browser state for a thread (implements abstract method from base class).
482
+ * Sync version that uses existing manager lookup without creating sessions.
483
+ */
484
+ protected getBrowserStateForThread(threadId?: string): BrowserState | null;
525
485
  /**
526
486
  * Get browser state from a specific Stagehand instance.
527
487
  */
@@ -534,34 +494,27 @@ declare class StagehandBrowser extends MastraBrowser {
534
494
  * Get the active tab index.
535
495
  */
536
496
  getActiveTabIndex(threadId?: string): Promise<number>;
537
- /**
538
- * Update the browser state in the thread session.
539
- * Called on navigation, tab open/close to keep state fresh.
540
- */
541
- private updateSessionBrowserState;
542
- /**
543
- * Get the stream key for a thread (or shared key for shared scope).
544
- */
545
- private getStreamKey;
546
497
  startScreencast(options?: ScreencastOptions): Promise<ScreencastStream>;
547
498
  /**
548
499
  * Set up listeners to detect tab changes and reconnect the screencast.
549
500
  * Uses CDP Target events since Stagehand doesn't expose page lifecycle events.
550
501
  */
551
502
  private setupTabChangeDetection;
552
- /**
553
- * Reconnect the active screencast for a specific thread.
554
- */
555
- private reconnectScreencastForThread;
556
- /**
557
- * Reconnect the active screencast for the current thread.
558
- * Wrapper for reconnectScreencastForThread using getCurrentThread().
559
- */
560
- private reconnectScreencast;
561
503
  injectMouseEvent(event: MouseEventParams, threadId?: string): Promise<void>;
562
504
  injectKeyboardEvent(event: KeyboardEventParams, threadId?: string): Promise<void>;
563
505
  }
564
506
 
507
+ /**
508
+ * Extract the Chrome process PID from a Stagehand instance.
509
+ *
510
+ * Stagehand stores the chrome-launcher result in `state.chrome` after init.
511
+ * The PID is at `chrome.process?.pid ?? chrome.pid`. This isn't part of
512
+ * Stagehand's public API, so we access it via `as any`.
513
+ *
514
+ * Returns undefined if the PID can't be found (e.g. BROWSERBASE env, not yet init'd).
515
+ */
516
+ declare function getStagehandChromePid(stagehand: Stagehand): number | undefined;
517
+
565
518
  /**
566
519
  * Stagehand Tool Constants
567
520
  */
@@ -587,4 +540,4 @@ type StagehandToolName = (typeof STAGEHAND_TOOLS)[keyof typeof STAGEHAND_TOOLS];
587
540
  */
588
541
  declare function createStagehandTools(browser: StagehandBrowser): Record<string, Tool<any, any>>;
589
542
 
590
- export { type ActInput, type ActResult, type CloseInput, type ExtractInput, type ExtractResult, type ModelConfiguration, type NavigateInput, type ObserveInput, type ObserveResult, STAGEHAND_TOOLS, type StagehandAction, StagehandBrowser, type StagehandBrowserConfig, type StagehandToolName, type TabsInput, actInputSchema, closeInputSchema, createStagehandTools, extractInputSchema, navigateInputSchema, observeInputSchema, stagehandSchemas, tabsInputSchema };
543
+ export { type ActInput, type ActResult, type CloseInput, type ExtractInput, type ExtractResult, type ModelConfiguration, type NavigateInput, type ObserveInput, type ObserveResult, STAGEHAND_TOOLS, type StagehandAction, StagehandBrowser, type StagehandBrowserConfig, type StagehandToolName, type TabsInput, actInputSchema, closeInputSchema, createStagehandTools, extractInputSchema, getStagehandChromePid, navigateInputSchema, observeInputSchema, stagehandSchemas, tabsInputSchema };
package/dist/index.d.ts CHANGED
@@ -108,11 +108,11 @@ declare const stagehandSchemas: {
108
108
  };
109
109
 
110
110
  /**
111
- * StagehandThreadManager - Thread isolation for StagehandBrowser
111
+ * StagehandThreadManager - Thread scope management for StagehandBrowser
112
112
  *
113
113
  * Supports two scope modes:
114
- * - 'none': All threads share the same Stagehand instance and page
115
- * - 'browser': Each thread gets its own Stagehand instance (separate browser)
114
+ * - 'shared': All threads share the same Stagehand instance and page
115
+ * - 'thread': Each thread gets its own Stagehand instance (separate browser)
116
116
  *
117
117
  * @see AgentBrowserThreadManager for the equivalent implementation.
118
118
  */
@@ -139,49 +139,23 @@ interface StagehandThreadManagerConfig extends ThreadManagerConfig {
139
139
  * Thread manager for StagehandBrowser.
140
140
  *
141
141
  * Supports two scope modes:
142
- * - 'none': All threads share the shared Stagehand instance
143
- * - 'browser': Each thread gets a dedicated Stagehand instance
142
+ * - 'shared': All threads share the shared Stagehand instance
143
+ * - 'thread': Each thread gets a dedicated Stagehand instance
144
144
  */
145
- declare class StagehandThreadManager extends ThreadManager<V3Page$1 | V3> {
146
- private sharedStagehand;
145
+ declare class StagehandThreadManager extends ThreadManager<V3> {
147
146
  protected sessions: Map<string, StagehandThreadSession>;
148
147
  private createStagehand?;
149
148
  private onBrowserCreated?;
150
- /** Map of thread ID to dedicated Stagehand instance (for 'thread' mode) */
151
- private readonly threadStagehands;
152
149
  constructor(config: StagehandThreadManagerConfig);
153
- /**
154
- * Set the shared Stagehand instance (called after browser launch).
155
- */
156
- setStagehand(instance: V3): void;
157
- /**
158
- * Clear the shared Stagehand instance (called when browser disconnects).
159
- */
160
- clearStagehand(): void;
161
150
  /**
162
151
  * Set the factory function for creating new Stagehand instances.
163
- * Required for 'browser' scope mode.
152
+ * Required for 'thread' scope mode.
164
153
  */
165
154
  setCreateStagehand(factory: () => Promise<V3>): void;
166
155
  /**
167
- * Get the shared Stagehand instance.
168
- */
169
- getSharedStagehand(): V3;
170
- /**
171
- * Get the Stagehand instance for a specific thread.
172
- * In 'shared' mode, returns the shared instance.
173
- * In 'thread' mode, returns the thread's dedicated instance.
174
- */
175
- getStagehandForThread(threadId: string): V3 | undefined;
176
- /**
177
- * Get the Stagehand page for a thread.
178
- * Returns the active page from the thread's Stagehand instance.
179
- */
180
- getPageForThread(threadId: string): V3Page$1 | undefined;
181
- /**
182
- * Get the shared manager - returns the active page or the Stagehand instance.
156
+ * Get the page for a specific thread, creating session if needed.
183
157
  */
184
- protected getSharedManager(): V3Page$1 | V3;
158
+ getPageForThread(threadId?: string): Promise<V3Page$1 | null>;
185
159
  /**
186
160
  * Create a new session for a thread.
187
161
  */
@@ -191,39 +165,18 @@ declare class StagehandThreadManager extends ThreadManager<V3Page$1 | V3> {
191
165
  */
192
166
  private restoreBrowserState;
193
167
  /**
194
- * Switch to an existing session.
195
- * For 'thread' mode, no switching needed - each thread has its own instance.
196
- * For 'shared' mode, nothing to switch.
197
- */
198
- protected switchToSession(_session: StagehandThreadSession): Promise<void>;
199
- /**
200
- * Get the manager for a specific session.
168
+ * Get the manager (Stagehand instance) for a specific session.
201
169
  */
202
- protected getManagerForSession(session: StagehandThreadSession): V3Page$1 | V3;
170
+ protected getManagerForSession(session: StagehandThreadSession): V3;
203
171
  /**
204
172
  * Destroy a session and clean up resources.
205
173
  */
206
174
  protected doDestroySession(session: StagehandThreadSession): Promise<void>;
207
175
  /**
208
- * Clean up all thread sessions.
176
+ * Destroy all sessions (called during browser close).
177
+ * doDestroySession handles closing individual Stagehand instances.
209
178
  */
210
- destroyAll(): Promise<void>;
211
- /**
212
- * Check if any thread Stagehands are still running.
213
- */
214
- hasActiveThreadStagehands(): boolean;
215
- /**
216
- * Clear all session tracking without closing browsers.
217
- * Used when browsers have been externally closed and we just need to reset state.
218
- */
219
- clearAllSessions(): void;
220
- /**
221
- * Clear a specific thread's session without closing the browser.
222
- * Used when a thread's browser has been externally closed.
223
- * Preserves the browser state for potential restoration.
224
- * @param threadId - The thread ID to clear
225
- */
226
- clearSession(threadId: string): void;
179
+ destroyAllSessions(): Promise<void>;
227
180
  }
228
181
 
229
182
  /**
@@ -239,9 +192,9 @@ type ModelConfiguration = string | {
239
192
  baseURL?: string;
240
193
  };
241
194
  /**
242
- * Configuration for StagehandBrowser
195
+ * Stagehand-specific configuration fields.
243
196
  */
244
- interface StagehandBrowserConfig extends BrowserConfig {
197
+ interface StagehandConfigExtensions {
245
198
  /**
246
199
  * Environment to run the browser in
247
200
  * - 'LOCAL': Run browser locally
@@ -285,7 +238,22 @@ interface StagehandBrowserConfig extends BrowserConfig {
285
238
  * Custom system prompt for AI operations (act, extract, observe)
286
239
  */
287
240
  systemPrompt?: string;
241
+ /**
242
+ * Whether to preserve the user data directory after the browser closes.
243
+ * By default, Stagehand may clean up temporary user data directories.
244
+ * Set to `true` to keep the profile data for future sessions.
245
+ *
246
+ * Only applicable when `profile` is provided.
247
+ *
248
+ * @default false
249
+ */
250
+ preserveUserDataDir?: boolean;
288
251
  }
252
+ /**
253
+ * Configuration for StagehandBrowser.
254
+ * Extends the base BrowserConfig with Stagehand-specific options.
255
+ */
256
+ type StagehandBrowserConfig = BrowserConfig & StagehandConfigExtensions;
289
257
  /**
290
258
  * Action returned from observe()
291
259
  */
@@ -345,31 +313,22 @@ type V3Page = NonNullable<ReturnType<NonNullable<Stagehand['context']>['activePa
345
313
  * Unlike AgentBrowser which uses refs ([ref=e1]), StagehandBrowser uses
346
314
  * natural language instructions for all interactions.
347
315
  *
348
- * Supports thread isolation via the scope config:
349
- * - 'none': All threads share the same Stagehand instance
350
- * - 'browser': Each thread gets its own Stagehand instance (separate browser)
316
+ * Supports thread scope via the scope config:
317
+ * - 'shared': All threads share the same Stagehand instance
318
+ * - 'thread': Each thread gets its own Stagehand instance (separate browser)
351
319
  */
352
320
  declare class StagehandBrowser extends MastraBrowser {
353
321
  readonly id: string;
354
322
  readonly name = "StagehandBrowser";
355
323
  readonly provider = "browserbase/stagehand";
356
- private stagehand;
324
+ /** Shared Stagehand instance (for 'shared' scope) - narrowed type from base class */
325
+ protected sharedManager: Stagehand | null;
357
326
  private stagehandConfig;
358
327
  /** Thread manager - narrowed type from base class */
359
328
  protected threadManager: StagehandThreadManager;
360
- /** Active screencast streams per thread (for reconnection on tab changes) */
361
- private activeScreencastStreams;
362
329
  /** Debounce timers per thread for tab change reconnection */
363
330
  private tabChangeDebounceTimers;
364
- /** Default key for shared scope */
365
- private static readonly SHARED_STREAM_KEY;
366
331
  constructor(config?: StagehandBrowserConfig);
367
- /**
368
- * Close a specific thread's browser session.
369
- * For 'thread' scope, this closes only that thread's Stagehand instance.
370
- * For 'shared' scope, this is a no-op (use close() to close the shared browser).
371
- */
372
- closeThreadSession(threadId: string): Promise<void>;
373
332
  /**
374
333
  * Ensure browser is ready and thread session exists.
375
334
  * For 'thread' scope, this creates a dedicated Stagehand instance for the thread.
@@ -382,37 +341,33 @@ declare class StagehandBrowser extends MastraBrowser {
382
341
  private buildStagehandOptions;
383
342
  /**
384
343
  * Create a new Stagehand instance with the current config.
385
- * Used by thread manager for 'browser' isolation mode.
344
+ * Used by thread manager for 'thread' scope.
386
345
  */
387
346
  private createStagehandInstance;
388
347
  protected doLaunch(): Promise<void>;
389
348
  /**
390
- * Set up close event listener for a Stagehand instance.
349
+ * Set up close event listener for a shared Stagehand instance.
391
350
  * Listens to both context and page close events for robust detection.
392
351
  */
393
- private setupCloseListener;
394
- /**
395
- * Set up close event listener for a thread's Stagehand instance.
396
- * Uses CDP Target.targetDestroyed events to detect when all pages are gone.
397
- */
398
- private setupCloseListenerForThread;
399
352
  /**
400
- * Handle browser disconnection for a specific thread.
401
- * Called when a thread's browser is closed externally.
353
+ * Set up a CDP-based close listener for a Stagehand instance.
354
+ *
355
+ * Tracks page targets via CDP `Target.targetCreated` / `Target.targetDestroyed`.
356
+ * When all page targets are gone the `onDisconnect` callback fires. This is more
357
+ * reliable than Playwright's `context.close` / `page.close` events which don't
358
+ * fire when Chrome is killed externally (SIGTERM/SIGKILL).
402
359
  */
403
- private handleThreadBrowserDisconnected;
360
+ private setupCloseListener;
404
361
  protected doClose(): Promise<void>;
362
+ handleBrowserDisconnected(): void;
363
+ protected handleThreadBrowserDisconnected(threadId: string): void;
364
+ closeThreadSession(threadId: string): Promise<void>;
365
+ private patchExitType;
405
366
  /**
406
367
  * Check if the browser is still alive by verifying the context and pages exist.
407
368
  * Called by base class ensureReady() to detect externally closed browsers.
408
369
  */
409
370
  protected checkBrowserAlive(): Promise<boolean>;
410
- /**
411
- * Handle browser disconnection by clearing internal state.
412
- * For 'thread' scope, only notifies the specific thread's callbacks.
413
- * For 'shared' scope, notifies all callbacks.
414
- */
415
- handleBrowserDisconnected(): void;
416
371
  /**
417
372
  * Create an error response from an exception.
418
373
  * Extends base class to add Stagehand-specific error handling.
@@ -420,10 +375,10 @@ declare class StagehandBrowser extends MastraBrowser {
420
375
  protected createErrorFromException(error: unknown, context: string): BrowserToolError;
421
376
  /**
422
377
  * Get the Stagehand instance for a thread, creating it if needed.
423
- * For 'browser' isolation, this creates a dedicated Stagehand instance.
424
- * For 'none' isolation, returns the shared instance.
378
+ * For 'thread' scope, this creates a dedicated Stagehand instance.
379
+ * For 'shared' scope, returns the shared instance.
425
380
  */
426
- private getStagehandForThread;
381
+ getManagerForThread(threadId?: string): Promise<Stagehand | null>;
427
382
  /**
428
383
  * Require a Stagehand instance for the given or current thread.
429
384
  * Throws if no instance is available.
@@ -432,15 +387,15 @@ declare class StagehandBrowser extends MastraBrowser {
432
387
  */
433
388
  private requireStagehand;
434
389
  /**
435
- * Get the current page from Stagehand v3, respecting thread isolation.
390
+ * Get the current page from Stagehand v3, respecting thread scope.
436
391
  * @param explicitThreadId - Optional thread ID to use instead of getCurrentThread()
437
392
  * Use this to avoid race conditions in concurrent tool calls.
438
393
  */
439
394
  private getPage;
440
395
  /**
441
- * Get the page for a specific thread, creating session if needed.
396
+ * Get the active page for a thread (implements abstract method from base class).
442
397
  */
443
- getPageForThread(threadId: string): Promise<V3Page | null>;
398
+ protected getActivePage(threadId?: string): Promise<V3Page | null>;
444
399
  /**
445
400
  * Get a CDP session for a specific page.
446
401
  */
@@ -522,6 +477,11 @@ declare class StagehandBrowser extends MastraBrowser {
522
477
  * Get the current browser state (all tabs and active tab index).
523
478
  */
524
479
  getBrowserState(threadId?: string): Promise<BrowserState | null>;
480
+ /**
481
+ * Get browser state for a thread (implements abstract method from base class).
482
+ * Sync version that uses existing manager lookup without creating sessions.
483
+ */
484
+ protected getBrowserStateForThread(threadId?: string): BrowserState | null;
525
485
  /**
526
486
  * Get browser state from a specific Stagehand instance.
527
487
  */
@@ -534,34 +494,27 @@ declare class StagehandBrowser extends MastraBrowser {
534
494
  * Get the active tab index.
535
495
  */
536
496
  getActiveTabIndex(threadId?: string): Promise<number>;
537
- /**
538
- * Update the browser state in the thread session.
539
- * Called on navigation, tab open/close to keep state fresh.
540
- */
541
- private updateSessionBrowserState;
542
- /**
543
- * Get the stream key for a thread (or shared key for shared scope).
544
- */
545
- private getStreamKey;
546
497
  startScreencast(options?: ScreencastOptions): Promise<ScreencastStream>;
547
498
  /**
548
499
  * Set up listeners to detect tab changes and reconnect the screencast.
549
500
  * Uses CDP Target events since Stagehand doesn't expose page lifecycle events.
550
501
  */
551
502
  private setupTabChangeDetection;
552
- /**
553
- * Reconnect the active screencast for a specific thread.
554
- */
555
- private reconnectScreencastForThread;
556
- /**
557
- * Reconnect the active screencast for the current thread.
558
- * Wrapper for reconnectScreencastForThread using getCurrentThread().
559
- */
560
- private reconnectScreencast;
561
503
  injectMouseEvent(event: MouseEventParams, threadId?: string): Promise<void>;
562
504
  injectKeyboardEvent(event: KeyboardEventParams, threadId?: string): Promise<void>;
563
505
  }
564
506
 
507
+ /**
508
+ * Extract the Chrome process PID from a Stagehand instance.
509
+ *
510
+ * Stagehand stores the chrome-launcher result in `state.chrome` after init.
511
+ * The PID is at `chrome.process?.pid ?? chrome.pid`. This isn't part of
512
+ * Stagehand's public API, so we access it via `as any`.
513
+ *
514
+ * Returns undefined if the PID can't be found (e.g. BROWSERBASE env, not yet init'd).
515
+ */
516
+ declare function getStagehandChromePid(stagehand: Stagehand): number | undefined;
517
+
565
518
  /**
566
519
  * Stagehand Tool Constants
567
520
  */
@@ -587,4 +540,4 @@ type StagehandToolName = (typeof STAGEHAND_TOOLS)[keyof typeof STAGEHAND_TOOLS];
587
540
  */
588
541
  declare function createStagehandTools(browser: StagehandBrowser): Record<string, Tool<any, any>>;
589
542
 
590
- export { type ActInput, type ActResult, type CloseInput, type ExtractInput, type ExtractResult, type ModelConfiguration, type NavigateInput, type ObserveInput, type ObserveResult, STAGEHAND_TOOLS, type StagehandAction, StagehandBrowser, type StagehandBrowserConfig, type StagehandToolName, type TabsInput, actInputSchema, closeInputSchema, createStagehandTools, extractInputSchema, navigateInputSchema, observeInputSchema, stagehandSchemas, tabsInputSchema };
543
+ export { type ActInput, type ActResult, type CloseInput, type ExtractInput, type ExtractResult, type ModelConfiguration, type NavigateInput, type ObserveInput, type ObserveResult, STAGEHAND_TOOLS, type StagehandAction, StagehandBrowser, type StagehandBrowserConfig, type StagehandToolName, type TabsInput, actInputSchema, closeInputSchema, createStagehandTools, extractInputSchema, getStagehandChromePid, navigateInputSchema, observeInputSchema, stagehandSchemas, tabsInputSchema };