@mastra/stagehand 0.0.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/README.md +93 -0
- package/dist/index.cjs +1408 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +590 -0
- package/dist/index.d.ts +590 -0
- package/dist/index.js +1397 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/thread-manager.ts","../src/schemas.ts","../src/tools/constants.ts","../src/tools/act.ts","../src/tools/close.ts","../src/tools/extract.ts","../src/tools/navigate.ts","../src/tools/observe.ts","../src/tools/tabs.ts","../src/tools/index.ts","../src/stagehand-browser.ts"],"names":["ThreadManager","z","createTool","MastraBrowser","DEFAULT_THREAD_ID","stagehand","Stagehand","page","ScreencastStreamImpl"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * StagehandThreadManager - Thread isolation for StagehandBrowser\n *\n * Supports two scope modes:\n * - 'none': All threads share the same Stagehand instance and page\n * - 'browser': Each thread gets its own Stagehand instance (separate browser)\n *\n * @see AgentBrowserThreadManager for the equivalent implementation.\n */\n\nimport type { Stagehand } from '@browserbasehq/stagehand';\nimport { ThreadManager } from '@mastra/core/browser';\nimport type { BrowserState, ThreadSession, ThreadManagerConfig } from '@mastra/core/browser';\n\n// Type aliases for Stagehand v3\n// V3 is the Stagehand instance, V3Page is the page type from context.activePage()\ntype V3 = Stagehand;\ntype V3Page = NonNullable<ReturnType<NonNullable<Stagehand['context']>['activePage']>>;\n\n/**\n * Extended session info for Stagehand threads.\n */\nexport interface StagehandThreadSession extends ThreadSession {\n /** For 'thread' mode: dedicated Stagehand instance */\n stagehand?: V3;\n}\n\n/**\n * Configuration for StagehandThreadManager.\n */\nexport interface StagehandThreadManagerConfig extends ThreadManagerConfig {\n /** Function to create a new Stagehand instance (for 'thread' mode) */\n createStagehand?: () => Promise<V3>;\n /** Callback when a new browser/Stagehand instance is created for a thread */\n onBrowserCreated?: (stagehand: V3, threadId: string) => void;\n}\n\n/**\n * Thread manager for StagehandBrowser.\n *\n * Supports two scope modes:\n * - 'none': All threads share the shared Stagehand instance\n * - 'browser': Each thread gets a dedicated Stagehand instance\n */\nexport class StagehandThreadManager extends ThreadManager<V3Page | V3> {\n private sharedStagehand: V3 | null = null;\n protected override sessions: Map<string, StagehandThreadSession> = new Map();\n private createStagehand?: () => Promise<V3>;\n private onBrowserCreated?: (stagehand: V3, threadId: string) => void;\n\n /** Map of thread ID to dedicated Stagehand instance (for 'thread' mode) */\n private readonly threadStagehands = new Map<string, V3>();\n\n constructor(config: StagehandThreadManagerConfig) {\n super(config);\n this.createStagehand = config.createStagehand;\n this.onBrowserCreated = config.onBrowserCreated;\n }\n\n /**\n * Set the shared Stagehand instance (called after browser launch).\n */\n setStagehand(instance: V3): void {\n this.sharedStagehand = instance;\n }\n\n /**\n * Clear the shared Stagehand instance (called when browser disconnects).\n */\n clearStagehand(): void {\n this.sharedStagehand = null;\n }\n\n /**\n * Set the factory function for creating new Stagehand instances.\n * Required for 'browser' scope mode.\n */\n setCreateStagehand(factory: () => Promise<V3>): void {\n this.createStagehand = factory;\n }\n\n /**\n * Get the shared Stagehand instance.\n */\n getSharedStagehand(): V3 {\n if (!this.sharedStagehand) {\n throw new Error('Stagehand not initialized');\n }\n return this.sharedStagehand;\n }\n\n /**\n * Get the Stagehand instance for a specific thread.\n * In 'shared' mode, returns the shared instance.\n * In 'thread' mode, returns the thread's dedicated instance.\n */\n getStagehandForThread(threadId: string): V3 | undefined {\n if (this.scope === 'thread') {\n const session = this.sessions.get(threadId);\n return session?.stagehand;\n }\n return this.sharedStagehand ?? undefined;\n }\n\n /**\n * Get the Stagehand page for a thread.\n * Returns the active page from the thread's Stagehand instance.\n */\n getPageForThread(threadId: string): V3Page | undefined {\n const stagehand = this.getStagehandForThread(threadId);\n return stagehand?.context?.activePage();\n }\n\n /**\n * Get the shared manager - returns the active page or the Stagehand instance.\n */\n protected getSharedManager(): V3Page | V3 {\n const stagehand = this.getSharedStagehand();\n return stagehand.context.activePage() ?? stagehand;\n }\n\n /**\n * Create a new session for a thread.\n */\n protected override async createSession(threadId: string): Promise<StagehandThreadSession> {\n // Check for saved browser state before creating new session (for browser restore)\n const savedState = this.getSavedBrowserState(threadId);\n\n const session: StagehandThreadSession = {\n threadId,\n createdAt: Date.now(),\n browserState: savedState,\n };\n\n if (this.scope === 'thread') {\n // Full thread scope - create a new Stagehand instance\n if (!this.createStagehand) {\n throw new Error('createStagehand factory not set - required for thread scope');\n }\n\n this.logger?.debug?.(`Creating dedicated Stagehand instance for thread ${threadId}`);\n const stagehand = await this.createStagehand();\n session.stagehand = stagehand;\n this.threadStagehands.set(threadId, stagehand);\n\n // Restore browser state if available (before notifying parent to avoid screencast race)\n if (savedState && savedState.tabs.length > 0) {\n this.logger?.debug?.(`Restoring browser state for thread ${threadId}: ${savedState.tabs.length} tabs`);\n await this.restoreBrowserState(stagehand, savedState);\n }\n\n // Notify parent browser so it can set up close listeners\n // This is done after restoration so the screencast starts on the correct active page\n this.onBrowserCreated?.(stagehand, threadId);\n }\n // For 'shared' scope, no session setup needed - all threads share the instance\n\n return session;\n }\n\n /**\n * Restore browser state (multiple tabs) to a Stagehand instance.\n */\n private async restoreBrowserState(stagehand: V3, state: BrowserState): Promise<void> {\n try {\n const context = stagehand.context;\n if (!context) return;\n\n // Navigate first tab to first URL\n const firstTab = state.tabs[0];\n if (firstTab?.url) {\n const page = context.activePage();\n if (page) {\n await page.goto(firstTab.url, { waitUntil: 'domcontentloaded' });\n }\n }\n\n // Open additional tabs using context.newPage()\n for (let i = 1; i < state.tabs.length; i++) {\n const tab = state.tabs[i];\n if (tab?.url) {\n await context.newPage(tab.url);\n }\n }\n\n // Always switch to the correct active tab\n // (newPage() makes the new page active, so we need to switch back if needed)\n const pages = context.pages();\n const targetPage = pages[state.activeTabIndex];\n if (targetPage && targetPage !== context.activePage()) {\n context.setActivePage(targetPage);\n }\n } catch (error) {\n this.logger?.warn?.(`Failed to restore browser state: ${error}`);\n }\n }\n\n /**\n * Switch to an existing session.\n * For 'thread' mode, no switching needed - each thread has its own instance.\n * For 'shared' mode, nothing to switch.\n */\n protected override async switchToSession(_session: StagehandThreadSession): Promise<void> {\n // No-op for both modes - 'browser' has separate instances, 'none' shares everything\n }\n\n /**\n * Get the manager for a specific session.\n */\n protected override getManagerForSession(session: StagehandThreadSession): V3Page | V3 {\n if (this.scope === 'thread' && session.stagehand) {\n return session.stagehand.context.activePage() ?? session.stagehand;\n }\n return this.getSharedManager();\n }\n\n /**\n * Destroy a session and clean up resources.\n */\n protected override async doDestroySession(session: StagehandThreadSession): Promise<void> {\n if (this.scope === 'thread' && session.stagehand) {\n // Close the dedicated Stagehand instance\n try {\n await session.stagehand.close();\n this.logger?.debug?.(`Closed Stagehand instance for thread ${session.threadId}`);\n } catch (error) {\n this.logger?.warn?.(`Failed to close Stagehand for thread ${session.threadId}: ${error}`);\n }\n this.threadStagehands.delete(session.threadId);\n }\n // For 'shared' mode, nothing to clean up - all threads share the instance\n }\n\n /**\n * Clean up all thread sessions.\n */\n async destroyAll(): Promise<void> {\n // Close all dedicated Stagehand instances\n for (const [threadId, stagehand] of this.threadStagehands) {\n try {\n await stagehand.close();\n } catch {\n this.logger?.debug?.(`Failed to close Stagehand for thread: ${threadId}`);\n }\n }\n this.threadStagehands.clear();\n\n // Clear sessions\n this.sessions.clear();\n }\n\n /**\n * Check if any thread Stagehands are still running.\n */\n hasActiveThreadStagehands(): boolean {\n return this.threadStagehands.size > 0;\n }\n\n /**\n * Clear all session tracking without closing browsers.\n * Used when browsers have been externally closed and we just need to reset state.\n */\n clearAllSessions(): void {\n this.threadStagehands.clear();\n this.sessions.clear();\n }\n\n /**\n * Clear a specific thread's session without closing the browser.\n * Used when a thread's browser has been externally closed.\n * Preserves the browser state for potential restoration.\n * @param threadId - The thread ID to clear\n */\n clearSession(threadId: string): void {\n // Save the browser state before clearing so it can be restored on relaunch\n const session = this.sessions.get(threadId);\n if (session?.browserState) {\n this.savedBrowserStates.set(threadId, session.browserState);\n }\n this.threadStagehands.delete(threadId);\n this.sessions.delete(threadId);\n }\n}\n","/**\n * Stagehand Tool Schemas\n *\n * AI-powered browser tools using natural language instructions.\n * These are fundamentally different from the deterministic AgentBrowser tools.\n */\n\nimport { z } from 'zod';\n\n// =============================================================================\n// Core AI Tools\n// =============================================================================\n\n/**\n * stagehand_act - Perform an action using natural language\n */\nexport const actInputSchema = z.object({\n instruction: z.string().describe('Natural language instruction for the action (e.g., \"click the login button\")'),\n variables: z\n .record(z.string(), z.string())\n .optional()\n .describe('Variables to substitute in the instruction using %variableName% syntax'),\n useVision: z.boolean().optional().describe('Whether to use vision capabilities (default: true)'),\n timeout: z.number().optional().describe('Timeout in milliseconds'),\n});\nexport type ActInput = z.output<typeof actInputSchema>;\n\n/**\n * stagehand_extract - Extract structured data from a page\n */\nexport const extractInputSchema = z.object({\n instruction: z.string().describe('Natural language instruction for what data to extract'),\n schema: z\n .record(z.string(), z.unknown())\n .optional()\n .describe('JSON schema defining the expected data structure (optional, will return unstructured if omitted)'),\n timeout: z.number().optional().describe('Timeout in milliseconds'),\n});\nexport type ExtractInput = z.output<typeof extractInputSchema>;\n\n/**\n * stagehand_observe - Discover actionable elements on a page\n */\nexport const observeInputSchema = z.object({\n instruction: z\n .string()\n .optional()\n .describe(\n 'Natural language instruction for what to find (e.g., \"find all buttons\"). If omitted, finds all interactive elements.',\n ),\n onlyVisible: z.boolean().optional().describe('Only return visible elements (default: true)'),\n timeout: z.number().optional().describe('Timeout in milliseconds'),\n});\nexport type ObserveInput = z.output<typeof observeInputSchema>;\n\n// =============================================================================\n// Navigation & State Tools\n// =============================================================================\n\n/**\n * stagehand_navigate - Navigate to a URL\n */\nexport const navigateInputSchema = z.object({\n url: z.string().describe('The URL to navigate to'),\n waitUntil: z\n .enum(['load', 'domcontentloaded', 'networkidle'])\n .optional()\n .describe('When to consider navigation complete (default: domcontentloaded)'),\n});\nexport type NavigateInput = z.output<typeof navigateInputSchema>;\n\n/**\n * stagehand_close - Close the browser\n */\nexport const closeInputSchema = z.object({});\nexport type CloseInput = z.output<typeof closeInputSchema>;\n\n/**\n * stagehand_tabs - Manage browser tabs\n */\nexport const tabsInputSchema = z\n .object({\n action: z\n .enum(['list', 'new', 'switch', 'close'])\n .describe('Action to perform: list all tabs, open new tab, switch to tab, or close tab'),\n index: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe(\n 'Tab index for switch/close actions (0-based). Required for switch, optional for close (defaults to current).',\n ),\n url: z.string().optional().describe('URL to navigate to after opening new tab (optional, for \"new\" action only)'),\n })\n .superRefine((value, ctx) => {\n if (value.action === 'switch' && value.index === undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['index'],\n message: 'index is required when action is \"switch\"',\n });\n }\n });\nexport type TabsInput = z.output<typeof tabsInputSchema>;\n\n// =============================================================================\n// All Schemas\n// =============================================================================\n\nexport const stagehandSchemas = {\n // Core AI\n act: actInputSchema,\n extract: extractInputSchema,\n observe: observeInputSchema,\n // Navigation & State\n navigate: navigateInputSchema,\n tabs: tabsInputSchema,\n close: closeInputSchema,\n} as const;\n","/**\n * Stagehand Tool Constants\n */\n\nexport const STAGEHAND_TOOLS = {\n // Core AI\n ACT: 'stagehand_act',\n EXTRACT: 'stagehand_extract',\n OBSERVE: 'stagehand_observe',\n // Navigation & State\n NAVIGATE: 'stagehand_navigate',\n TABS: 'stagehand_tabs',\n CLOSE: 'stagehand_close',\n} as const;\n\nexport type StagehandToolName = (typeof STAGEHAND_TOOLS)[keyof typeof STAGEHAND_TOOLS];\n","/**\n * stagehand_act - Perform an action using natural language\n */\n\nimport { createTool } from '@mastra/core/tools';\nimport { actInputSchema } from '../schemas';\nimport type { StagehandBrowser } from '../stagehand-browser';\nimport { STAGEHAND_TOOLS } from './constants';\n\nexport function createActTool(browser: StagehandBrowser) {\n return createTool({\n id: STAGEHAND_TOOLS.ACT,\n description:\n 'Perform an action on the page using natural language. Examples: \"click the login button\", \"type hello into the search box\", \"scroll down\".',\n inputSchema: actInputSchema,\n execute: async (input, { agent }) => {\n const threadId = agent?.threadId;\n browser.setCurrentThread(threadId);\n await browser.ensureReady();\n return await browser.act(input, threadId);\n },\n });\n}\n","/**\n * stagehand_close - Close the browser\n */\n\nimport { createTool } from '@mastra/core/tools';\nimport { closeInputSchema } from '../schemas';\nimport type { StagehandBrowser } from '../stagehand-browser';\nimport { STAGEHAND_TOOLS } from './constants';\n\nexport function createCloseTool(browser: StagehandBrowser) {\n return createTool({\n id: STAGEHAND_TOOLS.CLOSE,\n description: 'Close the browser. Only use when done with all browsing.',\n inputSchema: closeInputSchema,\n execute: async (_input, { agent }) => {\n // For thread scope, close only the thread's session\n const threadId = agent?.threadId;\n if (browser.getScope() !== 'shared') {\n if (!threadId) {\n throw new Error('stagehand_close requires agent.threadId when browser scope is not shared');\n }\n await browser.closeThreadSession(threadId);\n return {\n success: true,\n hint: \"Thread's browser session closed. A new session will be created on next use.\",\n };\n }\n // For shared scope, close the entire browser\n await browser.close();\n return {\n success: true,\n hint: 'Browser closed. It will be re-launched automatically on next use.',\n };\n },\n });\n}\n","/**\n * stagehand_extract - Extract structured data from a page\n */\n\nimport { createTool } from '@mastra/core/tools';\nimport { extractInputSchema } from '../schemas';\nimport type { StagehandBrowser } from '../stagehand-browser';\nimport { STAGEHAND_TOOLS } from './constants';\n\nexport function createExtractTool(browser: StagehandBrowser) {\n return createTool({\n id: STAGEHAND_TOOLS.EXTRACT,\n description:\n 'Extract structured data from the page using natural language. Can optionally provide a JSON schema for the expected data structure.',\n inputSchema: extractInputSchema,\n execute: async (input, { agent }) => {\n const threadId = agent?.threadId;\n browser.setCurrentThread(threadId);\n await browser.ensureReady();\n return await browser.extract(input, threadId);\n },\n });\n}\n","/**\n * stagehand_navigate - Navigate to a URL\n */\n\nimport { createTool } from '@mastra/core/tools';\nimport { navigateInputSchema } from '../schemas';\nimport type { StagehandBrowser } from '../stagehand-browser';\nimport { STAGEHAND_TOOLS } from './constants';\n\nexport function createNavigateTool(browser: StagehandBrowser) {\n return createTool({\n id: STAGEHAND_TOOLS.NAVIGATE,\n description: 'Navigate the browser to a URL.',\n inputSchema: navigateInputSchema,\n execute: async (input, { agent }) => {\n const threadId = agent?.threadId;\n browser.setCurrentThread(threadId);\n await browser.ensureReady();\n return await browser.navigate(input, threadId);\n },\n });\n}\n","/**\n * stagehand_observe - Discover actionable elements on a page\n */\n\nimport { createTool } from '@mastra/core/tools';\nimport { observeInputSchema } from '../schemas';\nimport type { StagehandBrowser } from '../stagehand-browser';\nimport { STAGEHAND_TOOLS } from './constants';\n\nexport function createObserveTool(browser: StagehandBrowser) {\n return createTool({\n id: STAGEHAND_TOOLS.OBSERVE,\n description:\n \"Discover actionable elements on the page. Returns a list of actions that can be performed. Use this to understand what's on the page before acting.\",\n inputSchema: observeInputSchema,\n execute: async (input, { agent }) => {\n const threadId = agent?.threadId;\n browser.setCurrentThread(threadId);\n await browser.ensureReady();\n return await browser.observe(input, threadId);\n },\n });\n}\n","/**\n * stagehand_tabs - Manage browser tabs\n */\n\nimport { createTool } from '@mastra/core/tools';\nimport { tabsInputSchema } from '../schemas';\nimport type { StagehandBrowser } from '../stagehand-browser';\nimport { STAGEHAND_TOOLS } from './constants';\n\nexport function createTabsTool(browser: StagehandBrowser) {\n return createTool({\n id: STAGEHAND_TOOLS.TABS,\n description:\n 'Manage browser tabs. Actions: \"list\" shows all tabs, \"new\" opens a tab (optionally with URL), \"switch\" changes to tab by index, \"close\" closes a tab.',\n inputSchema: tabsInputSchema,\n execute: async (input, { agent }) => {\n const threadId = agent?.threadId;\n browser.setCurrentThread(threadId);\n await browser.ensureReady();\n return await browser.tabs(input, threadId);\n },\n });\n}\n","/**\n * Stagehand Tools\n *\n * Creates AI-powered browser tools bound to a StagehandBrowser instance.\n */\n\nimport type { Tool } from '@mastra/core/tools';\nimport type { StagehandBrowser } from '../stagehand-browser';\nimport { createActTool } from './act';\nimport { createCloseTool } from './close';\nimport { STAGEHAND_TOOLS } from './constants';\nimport { createExtractTool } from './extract';\nimport { createNavigateTool } from './navigate';\nimport { createObserveTool } from './observe';\nimport { createTabsTool } from './tabs';\n\nexport { STAGEHAND_TOOLS, type StagehandToolName } from './constants';\n\n/**\n * Creates all Stagehand tools bound to a StagehandBrowser instance.\n * The browser is lazily initialized on first tool use.\n */\nexport function createStagehandTools(browser: StagehandBrowser): Record<string, Tool<any, any>> {\n return {\n // Core AI\n [STAGEHAND_TOOLS.ACT]: createActTool(browser),\n [STAGEHAND_TOOLS.EXTRACT]: createExtractTool(browser),\n [STAGEHAND_TOOLS.OBSERVE]: createObserveTool(browser),\n // Navigation & State\n [STAGEHAND_TOOLS.NAVIGATE]: createNavigateTool(browser),\n [STAGEHAND_TOOLS.TABS]: createTabsTool(browser),\n [STAGEHAND_TOOLS.CLOSE]: createCloseTool(browser),\n };\n}\n","/**\n * StagehandBrowser - AI-powered browser automation using Stagehand v3\n *\n * Uses natural language instructions for browser interactions.\n * Fundamentally different from AgentBrowser's deterministic refs approach.\n *\n * Stagehand v3 is CDP-native and provides direct CDP access for screencast/input injection.\n */\n\nimport { Stagehand } from '@browserbasehq/stagehand';\nimport { MastraBrowser, ScreencastStreamImpl, DEFAULT_THREAD_ID } from '@mastra/core/browser';\nimport type {\n BrowserState,\n BrowserTabState,\n BrowserToolError,\n ScreencastOptions,\n ScreencastStream,\n MouseEventParams,\n KeyboardEventParams,\n} from '@mastra/core/browser';\nimport type { Tool } from '@mastra/core/tools';\nimport type { ActInput, ExtractInput, ObserveInput, NavigateInput, TabsInput } from './schemas';\nimport { StagehandThreadManager } from './thread-manager';\nimport { createStagehandTools } from './tools';\nimport type { StagehandBrowserConfig, StagehandAction } from './types';\n\n// Type for Stagehand v3 Page\ntype V3Page = NonNullable<ReturnType<NonNullable<Stagehand['context']>['activePage']>>;\n\n/**\n * StagehandBrowser - AI-powered browser using Stagehand v3\n *\n * Unlike AgentBrowser which uses refs ([ref=e1]), StagehandBrowser uses\n * natural language instructions for all interactions.\n *\n * Supports thread isolation via the scope config:\n * - 'none': All threads share the same Stagehand instance\n * - 'browser': Each thread gets its own Stagehand instance (separate browser)\n */\nexport class StagehandBrowser extends MastraBrowser {\n override readonly id: string;\n override readonly name = 'StagehandBrowser';\n override readonly provider = 'browserbase/stagehand';\n\n private stagehand: Stagehand | null = null;\n private stagehandConfig: StagehandBrowserConfig;\n\n /** Thread manager - narrowed type from base class */\n declare protected threadManager: StagehandThreadManager;\n\n /** Active screencast streams per thread (for reconnection on tab changes) */\n private activeScreencastStreams = new Map<string, ScreencastStreamImpl>();\n\n /** Debounce timers per thread for tab change reconnection */\n private tabChangeDebounceTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n /** Default key for shared scope */\n private static readonly SHARED_STREAM_KEY = '__shared__';\n\n constructor(config: StagehandBrowserConfig = {}) {\n super(config);\n this.id = `stagehand-${Date.now()}`;\n this.stagehandConfig = config;\n\n // Determine browser scope\n // When connecting to an external browser via cdpUrl, 'thread' scope doesn't make sense\n // because we can't spawn new browser instances - we're connecting to an existing one\n let effectiveScope = config.scope ?? 'thread';\n if (config.cdpUrl && effectiveScope === 'thread') {\n this.logger.warn?.(\n 'Browser scope \"thread\" is not supported when connecting via cdpUrl. ' +\n 'Falling back to \"shared\" (shared browser connection).',\n );\n effectiveScope = 'shared';\n }\n\n // Initialize thread manager\n this.threadManager = new StagehandThreadManager({\n scope: effectiveScope,\n logger: this.logger,\n // When a new thread session is created, notify listeners so screencast can start\n onSessionCreated: session => {\n // Trigger onBrowserReady callbacks for this specific thread\n // This allows ViewerRegistry to start screencast for just this thread\n this.notifyBrowserReady(session.threadId);\n },\n // When a new browser is created for a thread, set up close listener\n onBrowserCreated: (stagehand, threadId) => {\n this.setupCloseListenerForThread(stagehand, threadId);\n },\n });\n }\n\n /**\n * Close a specific thread's browser session.\n * For 'thread' scope, this closes only that thread's Stagehand instance.\n * For 'shared' scope, this is a no-op (use close() to close the shared browser).\n */\n async closeThreadSession(threadId: string): Promise<void> {\n await this.threadManager.destroySession(threadId);\n // Notify callbacks registered for this specific thread\n this.notifyBrowserClosed(threadId);\n }\n\n /**\n * Ensure browser is ready and thread session exists.\n * For 'thread' scope, this creates a dedicated Stagehand instance for the thread.\n */\n override async ensureReady(): Promise<void> {\n // Always ensure the factory is set before any thread operations\n // This must happen before super.ensureReady() which may trigger doLaunch()\n this.threadManager.setCreateStagehand(() => this.createStagehandInstance());\n\n // Call super first - this will trigger doLaunch() if not already launched\n await super.ensureReady();\n\n // For 'thread' scope, ensure thread session exists after browser is ready\n const scope = this.getScope();\n const threadId = this.getCurrentThread();\n if (scope === 'thread' && threadId && threadId !== DEFAULT_THREAD_ID) {\n // This will create the Stagehand instance for this thread if needed\n await this.getStagehandForThread(threadId);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n /**\n * Build Stagehand options from config.\n * Returns the configuration object expected by Stagehand constructor.\n */\n private async buildStagehandOptions(): Promise<{\n env: 'LOCAL' | 'BROWSERBASE';\n model?: string;\n selfHeal?: boolean;\n domSettleTimeoutMs?: number;\n verbose?: 0 | 1 | 2;\n systemPrompt?: string;\n apiKey?: string;\n projectId?: string;\n localBrowserLaunchOptions?: {\n cdpUrl?: string;\n headless?: boolean;\n viewport?: { width: number; height: number };\n };\n }> {\n const config = this.stagehandConfig;\n\n const stagehandOptions: {\n env: 'LOCAL' | 'BROWSERBASE';\n model?: string;\n selfHeal?: boolean;\n domSettleTimeoutMs?: number;\n verbose?: 0 | 1 | 2;\n systemPrompt?: string;\n apiKey?: string;\n projectId?: string;\n localBrowserLaunchOptions?: {\n cdpUrl?: string;\n headless?: boolean;\n viewport?: { width: number; height: number };\n };\n } = {\n env: config.env ?? 'LOCAL',\n // v3 uses \"provider/model\" format\n model: typeof config.model === 'string' ? config.model : config.model?.modelName,\n selfHeal: config.selfHeal ?? true,\n domSettleTimeoutMs: config.domSettleTimeout,\n verbose: (config.verbose ?? 1) as 0 | 1 | 2,\n systemPrompt: config.systemPrompt,\n };\n\n // Handle Browserbase configuration\n if (config.env === 'BROWSERBASE') {\n if (config.apiKey) {\n stagehandOptions.apiKey = config.apiKey;\n }\n if (config.projectId) {\n stagehandOptions.projectId = config.projectId;\n }\n }\n\n // Handle CDP URL for local browser with custom endpoint\n // Stagehand requires a WebSocket URL, so resolve HTTP URLs to WebSocket URLs\n if (config.cdpUrl && config.env !== 'BROWSERBASE') {\n const resolvedUrl = await this.resolveCdpUrl(config.cdpUrl);\n const wsUrl = await this.resolveWebSocketUrl(resolvedUrl);\n stagehandOptions.localBrowserLaunchOptions = {\n cdpUrl: wsUrl,\n headless: config.headless,\n viewport: config.viewport,\n };\n } else if (config.env !== 'BROWSERBASE') {\n stagehandOptions.localBrowserLaunchOptions = {\n headless: config.headless,\n viewport: config.viewport,\n };\n }\n\n return stagehandOptions;\n }\n\n /**\n * Create a new Stagehand instance with the current config.\n * Used by thread manager for 'browser' isolation mode.\n */\n private async createStagehandInstance(): Promise<Stagehand> {\n const stagehandOptions = await this.buildStagehandOptions();\n const stagehand = new Stagehand(stagehandOptions);\n await stagehand.init();\n return stagehand;\n }\n\n protected override async doLaunch(): Promise<void> {\n const scope = this.getScope();\n\n // Set up the thread manager's factory function for creating new Stagehand instances\n this.threadManager.setCreateStagehand(() => this.createStagehandInstance());\n\n if (scope === 'thread') {\n // For 'browser' isolation, don't launch a shared browser here.\n // Each thread will get its own Stagehand instance via getStagehandForThread().\n // We still need a placeholder so the base class knows we're \"launched\".\n\n return;\n }\n\n // For 'none' isolation, launch a shared Stagehand instance\n this.stagehand = await this.createStagehandInstance();\n\n // Register the Stagehand instance with the thread manager\n this.threadManager.setStagehand(this.stagehand as any);\n\n // Listen for browser/context close events to detect external closure\n this.setupCloseListener(this.stagehand);\n }\n\n /**\n * Set up close event listener for a Stagehand instance.\n * Listens to both context and page close events for robust detection.\n */\n private setupCloseListener(stagehand: Stagehand): void {\n let disconnectHandled = false;\n const handleDisconnect = () => {\n if (disconnectHandled) return;\n disconnectHandled = true;\n this.handleBrowserDisconnected();\n };\n\n try {\n const context = stagehand.context;\n if (!context) return;\n\n // Listen for context close (fires when browser window is closed)\n const contextWithEvents = context as unknown as { on?: (event: string, cb: () => void) => void };\n if (contextWithEvents?.on) {\n contextWithEvents.on('close', handleDisconnect);\n }\n\n // Listen for last page closing (primary detection method)\n const pages = context.pages?.() ?? [];\n for (const page of pages) {\n const pageWithEvents = page as unknown as { on?: (event: string, cb: () => void) => void };\n if (pageWithEvents?.on) {\n pageWithEvents.on('close', () => {\n const remainingPages = context.pages?.() ?? [];\n if (remainingPages.length === 0) {\n handleDisconnect();\n }\n });\n }\n }\n } catch {\n // Ignore errors setting up close listener\n }\n }\n\n /**\n * Set up close event listener for a thread's Stagehand instance.\n * Uses CDP Target.targetDestroyed events to detect when all pages are gone.\n */\n private setupCloseListenerForThread(stagehand: Stagehand, threadId: string): void {\n let disconnectHandled = false;\n const handleDisconnect = () => {\n if (disconnectHandled) return;\n disconnectHandled = true;\n this.handleThreadBrowserDisconnected(threadId);\n };\n\n try {\n const stagehandAny = stagehand as any;\n const conn = stagehandAny.ctx?.conn;\n\n if (!conn?.on) {\n return;\n }\n\n // Track page targets - when all are destroyed, browser is closed\n const pageTargets = new Set<string>();\n\n // Initialize with current pages\n const context = stagehand.context;\n if (context) {\n const pages = context.pages?.() ?? [];\n for (const page of pages) {\n const pageAny = page as any;\n const targetId = pageAny._targetId ?? pageAny.targetId;\n if (targetId) {\n pageTargets.add(targetId);\n }\n }\n }\n\n // Listen for new page targets\n conn.on('Target.targetCreated', (params: { targetInfo: { targetId: string; type: string } }) => {\n if (params.targetInfo.type === 'page') {\n pageTargets.add(params.targetInfo.targetId);\n }\n });\n\n // Listen for destroyed targets - when all pages gone, browser closed\n conn.on('Target.targetDestroyed', (params: { targetId: string }) => {\n if (pageTargets.has(params.targetId)) {\n pageTargets.delete(params.targetId);\n if (pageTargets.size === 0) {\n handleDisconnect();\n }\n }\n });\n } catch {\n // Ignore errors setting up close listener\n }\n }\n\n /**\n * Handle browser disconnection for a specific thread.\n * Called when a thread's browser is closed externally.\n */\n private handleThreadBrowserDisconnected(threadId: string): void {\n this.threadManager.clearSession(threadId);\n this.logger.debug?.(`Cleared Stagehand session for thread: ${threadId}`);\n // Notify only the callbacks registered for this specific thread\n this.notifyBrowserClosed(threadId);\n }\n\n protected override async doClose(): Promise<void> {\n // Clean up all thread Stagehand instances first\n await this.threadManager.destroyAll();\n\n // Close the shared Stagehand instance if it exists\n if (this.stagehand) {\n await this.stagehand.close();\n this.stagehand = null;\n }\n\n // Reset thread state\n this.setCurrentThread(undefined);\n }\n\n /**\n * Check if the browser is still alive by verifying the context and pages exist.\n * Called by base class ensureReady() to detect externally closed browsers.\n */\n protected async checkBrowserAlive(): Promise<boolean> {\n const scope = this.getScope();\n\n if (scope === 'thread') {\n // For 'browser' isolation, check if any thread browsers are running\n return this.threadManager.hasActiveThreadStagehands();\n }\n\n // For 'none' isolation, check the shared Stagehand instance\n if (!this.stagehand) {\n return false;\n }\n try {\n const context = this.stagehand.context;\n if (!context) {\n return false;\n }\n const pages = context.pages();\n if (!pages || pages.length === 0) {\n return false;\n }\n // Will throw if browser is disconnected\n const url = pages[0]?.url();\n // Save browser state for potential restore on relaunch\n if (url && url !== 'about:blank') {\n const state = this.getBrowserStateFromStagehand(this.stagehand);\n if (state) {\n this.lastBrowserState = state;\n }\n }\n return true;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (this.isDisconnectionError(msg)) {\n this.logger.debug?.('Browser was externally closed');\n }\n return false;\n }\n }\n\n /**\n * Handle browser disconnection by clearing internal state.\n * For 'thread' scope, only notifies the specific thread's callbacks.\n * For 'shared' scope, notifies all callbacks.\n */\n override handleBrowserDisconnected(): void {\n const scope = this.threadManager.getScope();\n const threadId = this.getCurrentThread();\n\n if (scope === 'thread' && threadId !== DEFAULT_THREAD_ID) {\n // Only clear the specific thread's session - other threads have independent browsers\n this.threadManager.clearSession(threadId);\n this.logger.debug?.(`Cleared Stagehand session for thread: ${threadId}`);\n // Notify only this thread's callbacks - do NOT set global status to 'closed'\n // since other threads may still have active browsers\n this.notifyBrowserClosed(threadId);\n } else {\n // For 'shared' scope or default thread, the shared stagehand is gone\n this.stagehand = null;\n this.threadManager.clearStagehand();\n // Call base class which notifies all callbacks\n super.handleBrowserDisconnected();\n }\n }\n\n /**\n * Create an error response from an exception.\n * Extends base class to add Stagehand-specific error handling.\n */\n protected override createErrorFromException(error: unknown, context: string): BrowserToolError {\n const msg = error instanceof Error ? error.message : String(error);\n\n // Check for Stagehand-specific \"no actions found\" errors\n if (msg.includes('No actions found') || msg.includes('Could not find')) {\n return this.createError(\n 'element_not_found',\n `${context}: Could not find matching element or action.`,\n 'Try rephrasing the instruction or use observe() to see available actions.',\n );\n }\n\n // Delegate to base class for common errors\n return super.createErrorFromException(error, context);\n }\n\n // ---------------------------------------------------------------------------\n // Internal Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Get the Stagehand instance for a thread, creating it if needed.\n * For 'browser' isolation, this creates a dedicated Stagehand instance.\n * For 'none' isolation, returns the shared instance.\n */\n private async getStagehandForThread(threadId: string | undefined): Promise<Stagehand | null> {\n const scope = this.getScope();\n\n if (scope === 'shared') {\n return this.stagehand;\n }\n\n if (!threadId || threadId === DEFAULT_THREAD_ID) {\n return this.stagehand;\n }\n\n // For 'browser' isolation, get or create the thread's Stagehand instance\n let stagehand = this.threadManager.getStagehandForThread(threadId);\n if (!stagehand) {\n // Create session which creates the Stagehand instance\n // The onBrowserCreated callback will set up the close listener\n await this.threadManager.getManagerForThread(threadId);\n stagehand = this.threadManager.getStagehandForThread(threadId);\n }\n\n return stagehand ?? null;\n }\n\n /**\n * Require a Stagehand instance for the given or current thread.\n * Throws if no instance is available.\n * @param explicitThreadId - Optional thread ID to use instead of getCurrentThread()\n * Use this to avoid race conditions in concurrent tool calls.\n */\n private requireStagehand(explicitThreadId?: string): Stagehand {\n const threadId = explicitThreadId ?? this.getCurrentThread();\n const stagehand = this.threadManager.getStagehandForThread(threadId ?? '') ?? this.stagehand;\n\n if (!stagehand) {\n throw new Error('Browser not launched');\n }\n return stagehand;\n }\n\n /**\n * Get the current page from Stagehand v3, respecting thread isolation.\n * @param explicitThreadId - Optional thread ID to use instead of getCurrentThread()\n * Use this to avoid race conditions in concurrent tool calls.\n */\n private getPage(explicitThreadId?: string): V3Page | null {\n const scope = this.getScope();\n const threadId = explicitThreadId ?? this.getCurrentThread();\n\n // For 'browser' isolation, get the thread's Stagehand's active page\n if (scope === 'thread' && threadId && threadId !== DEFAULT_THREAD_ID) {\n const stagehand = this.threadManager.getStagehandForThread(threadId);\n if (stagehand?.context) {\n return stagehand.context.activePage() as V3Page | null;\n }\n return null;\n }\n\n // For 'none' isolation, use the shared Stagehand instance\n if (!this.stagehand) return null;\n\n try {\n const context = this.stagehand.context;\n if (context) {\n const activePage = context.activePage();\n if (activePage) {\n return activePage as V3Page;\n }\n // Fall back to first page if no active page\n const pages = context.pages();\n if (pages && pages.length > 0) {\n return pages[0] as V3Page;\n }\n }\n } catch {\n // Ignore errors - page may not be available\n }\n\n return null;\n }\n\n /**\n * Get the page for a specific thread, creating session if needed.\n */\n async getPageForThread(threadId: string): Promise<V3Page | null> {\n const scope = this.threadManager.getScope();\n\n if (scope === 'shared') {\n return this.getPage();\n }\n\n // For 'browser' isolation, get the thread's Stagehand instance\n const stagehand = await this.getStagehandForThread(threadId);\n if (stagehand?.context) {\n return stagehand.context.activePage() as V3Page | null;\n }\n\n return null;\n }\n\n /**\n * Get a CDP session for a specific page.\n */\n private getCdpSessionForPage(page: V3Page | null): any {\n if (!page) return null;\n\n try {\n // Stagehand v3 Page exposes getSessionForFrame(mainFrameId)\n const mainFrameId = page.mainFrameId?.();\n if (mainFrameId && page.getSessionForFrame) {\n return page.getSessionForFrame(mainFrameId);\n }\n } catch {\n // Ignore errors\n }\n\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Tools - Implements MastraBrowser.getTools()\n // ---------------------------------------------------------------------------\n\n override getTools(): Record<string, Tool<any, any>> {\n return createStagehandTools(this);\n }\n\n // ---------------------------------------------------------------------------\n // Core AI Methods\n // ---------------------------------------------------------------------------\n\n /**\n * Perform an action using natural language instruction\n * @param input - Action input\n * @param threadId - Optional thread ID for thread-safe operation\n */\n async act(\n input: ActInput,\n threadId?: string,\n ): Promise<{ success: true; message?: string; action?: string; url: string; hint: string } | BrowserToolError> {\n const stagehand = this.requireStagehand(threadId);\n const page = this.getPage(threadId);\n const url = page?.url() ?? '';\n\n try {\n // v3 API: stagehand.act(instruction, options?)\n // Pass page for thread isolation support\n const result = await stagehand.act(input.instruction, {\n variables: input.variables,\n timeout: input.timeout,\n page: page ?? undefined,\n });\n\n return {\n success: result.success as true,\n message: result.message,\n action: result.actionDescription,\n url: page?.url() ?? url,\n hint: 'Use observe() to discover available actions or extract() to get page data.',\n };\n } catch (error) {\n return this.createErrorFromException(error, 'Act');\n }\n }\n\n /**\n * Extract structured data from a page using natural language\n * @param input - Extract input\n * @param threadId - Optional thread ID for thread-safe operation\n */\n async extract(\n input: ExtractInput,\n threadId?: string,\n ): Promise<{ success: true; data: unknown; url: string; hint: string } | BrowserToolError> {\n const stagehand = this.requireStagehand(threadId);\n const page = this.getPage(threadId);\n const url = page?.url() ?? '';\n\n try {\n // v3 API: stagehand.extract(instruction, schema?, options?)\n // Pass page for thread isolation support\n const options: any = { page: page ?? undefined };\n const result = input.schema\n ? await stagehand.extract(input.instruction, input.schema as any, options)\n : await stagehand.extract(input.instruction, options);\n\n return {\n success: true,\n data: result,\n url: page?.url() ?? url,\n hint: 'Data extracted successfully. Use act() to perform actions based on this data.',\n };\n } catch (error) {\n return this.createErrorFromException(error, 'Extract');\n }\n }\n\n /**\n * Discover actionable elements on a page\n * @param input - Observe input\n * @param threadId - Optional thread ID for thread-safe operation\n */\n async observe(\n input: ObserveInput,\n threadId?: string,\n ): Promise<{ success: true; actions: StagehandAction[]; url: string; hint: string } | BrowserToolError> {\n const stagehand = this.requireStagehand(threadId);\n const page = this.getPage(threadId);\n const url = page?.url() ?? '';\n\n try {\n // v3 API: stagehand.observe() or stagehand.observe(instruction, options?)\n // Pass page for thread isolation support\n const options: any = { page: page ?? undefined };\n const actions = input.instruction\n ? await stagehand.observe(input.instruction, options)\n : await stagehand.observe(options);\n\n return {\n success: true,\n actions: actions.map((a: any) => ({\n selector: a.selector,\n description: a.description,\n method: a.method,\n arguments: a.arguments,\n })) as StagehandAction[],\n url: page?.url() ?? url,\n hint:\n actions.length > 0\n ? `Found ${actions.length} actions. Use act() with a specific instruction to execute one.`\n : 'No actions found. Try a different instruction or navigate to a different page.',\n };\n } catch (error) {\n return this.createErrorFromException(error, 'Observe');\n }\n }\n\n // ---------------------------------------------------------------------------\n // Navigation & State Methods\n // ---------------------------------------------------------------------------\n\n /**\n * Navigate to a URL\n * @param input - Navigate input\n * @param threadId - Optional thread ID for thread-safe operation\n */\n async navigate(\n input: NavigateInput,\n threadId?: string,\n ): Promise<{ success: true; url: string; title: string; hint: string } | BrowserToolError> {\n const page = this.getPage(threadId);\n\n if (!page) {\n return this.createError('browser_error', 'Browser page not available.', 'Ensure the browser is launched.');\n }\n\n try {\n await page.goto(input.url, {\n waitUntil: input.waitUntil ?? 'domcontentloaded',\n });\n\n const url = page.url();\n const title = await page.title();\n\n return {\n success: true,\n url,\n title,\n hint: 'Page loaded. Use observe() to discover actions or extract() to get data.',\n };\n } catch (error) {\n return this.createErrorFromException(error, 'Navigate');\n }\n }\n\n // ---------------------------------------------------------------------------\n // Tab Management\n // ---------------------------------------------------------------------------\n\n /**\n * Manage browser tabs - list, create, switch, close\n * @param input - Tabs input\n * @param threadId - Optional thread ID for thread-safe operation\n */\n async tabs(\n input: TabsInput,\n threadId?: string,\n ): Promise<\n | { success: true; tabs?: Array<{ index: number; url: string; title: string; active: boolean }>; hint: string }\n | { success: true; index?: number; url?: string; title?: string; remaining?: number; hint: string }\n | BrowserToolError\n > {\n const effectiveThreadId = threadId ?? this.getCurrentThread();\n const stagehand = this.requireStagehand(effectiveThreadId);\n const context = stagehand.context;\n\n if (!context) {\n return this.createError('browser_error', 'Browser context not available.', 'Ensure the browser is launched.');\n }\n\n try {\n switch (input.action) {\n case 'list': {\n const pages = context.pages();\n const activePage = context.activePage();\n const tabs = await Promise.all(\n pages.map(async (page, index) => ({\n index,\n url: page.url(),\n title: await page.title(),\n active: page === activePage,\n })),\n );\n return {\n success: true,\n tabs,\n hint: 'Use stagehand_tabs with action:\"switch\" and index to change tabs.',\n };\n }\n\n case 'new': {\n const newPage = await context.newPage(input.url);\n // newPage automatically becomes active in Stagehand\n await this.reconnectScreencastForThread(effectiveThreadId, 'new tab via tool');\n // Save state after new tab\n this.updateSessionBrowserState(effectiveThreadId);\n return {\n success: true,\n index: context.pages().length - 1,\n url: newPage.url(),\n title: await newPage.title(),\n hint: 'New tab opened. Use stagehand_observe to discover actions.',\n };\n }\n\n case 'switch': {\n if (input.index === undefined) {\n return this.createError(\n 'browser_error',\n 'Tab index required for switch action.',\n 'Provide index parameter.',\n );\n }\n const pages = context.pages();\n if (input.index < 0 || input.index >= pages.length) {\n return this.createError(\n 'browser_error',\n `Invalid tab index: ${input.index}. Valid range: 0-${pages.length - 1}`,\n 'Use stagehand_tabs with action:\"list\" to see available tabs.',\n );\n }\n const targetPage = pages[input.index]!;\n const targetUrl = targetPage.url();\n context.setActivePage(targetPage);\n await this.reconnectScreencastForThread(effectiveThreadId, 'tab switch via tool');\n // Emit URL directly since we have the target page\n const streamKey = this.getStreamKey(effectiveThreadId);\n const stream = this.activeScreencastStreams.get(streamKey);\n if (targetUrl && stream?.isActive()) {\n stream.emitUrl(targetUrl);\n }\n // Save state after switch (captures activeIndex change)\n this.updateSessionBrowserState(effectiveThreadId);\n return {\n success: true,\n index: input.index,\n url: targetUrl,\n title: await targetPage.title(),\n hint: 'Tab switched. Use stagehand_observe to discover actions.',\n };\n }\n\n case 'close': {\n const pages = context.pages();\n const indexToClose = input.index ?? pages.findIndex(p => p === context.activePage());\n if (indexToClose < 0 || indexToClose >= pages.length) {\n return this.createError(\n 'browser_error',\n `Invalid tab index: ${indexToClose}`,\n 'Use stagehand_tabs with action:\"list\" to see available tabs.',\n );\n }\n const pageToClose = pages[indexToClose]!;\n await pageToClose.close();\n await this.reconnectScreencastForThread(effectiveThreadId, 'tab close via tool');\n // Save state AFTER close (remaining tabs)\n this.updateSessionBrowserState(effectiveThreadId);\n const remainingPages = context.pages();\n return {\n success: true,\n remaining: remainingPages.length,\n hint:\n remainingPages.length > 0 ? 'Tab closed. Use stagehand_observe to see current tab.' : 'All tabs closed.',\n };\n }\n\n default:\n return this.createError(\n 'browser_error',\n `Unknown tabs action: ${(input as any).action}`,\n 'Use \"list\", \"new\", \"switch\", or \"close\".',\n );\n }\n } catch (error) {\n return this.createErrorFromException(error, 'Tabs');\n }\n }\n\n // ---------------------------------------------------------------------------\n // URL Tracking (for Studio browser view)\n // ---------------------------------------------------------------------------\n\n override async getCurrentUrl(threadId?: string): Promise<string | null> {\n // Don't try to get URL if browser isn't running - this can be called\n // before launch (e.g., by BrowserContextProcessor)\n if (!this.isBrowserRunning()) {\n return null;\n }\n\n // Use the thread-specific page if provided\n const effectiveThreadId = threadId ?? this.getCurrentThread();\n\n // For 'browser' isolation, check if we have an existing session first\n // Don't create a new session just to get the URL\n const scope = this.threadManager.getScope();\n if (scope === 'thread' && effectiveThreadId) {\n const stagehand = this.threadManager.getStagehandForThread(effectiveThreadId);\n if (!stagehand?.context) {\n return null; // No session yet, don't create one\n }\n const page = stagehand.context.activePage() as V3Page | null;\n const url = page?.url() ?? null;\n // Save browser state for potential restore on relaunch (before external close)\n if (url && url !== 'about:blank') {\n const state = this.getBrowserStateFromStagehand(stagehand);\n if (state) {\n this.threadManager.updateBrowserState(effectiveThreadId, state);\n }\n }\n return url;\n }\n\n // For 'none' isolation, use the shared page\n const page = this.getPage();\n if (!page) return null;\n\n try {\n const url = page.url();\n // Save browser state for potential restore on relaunch (before external close)\n if (url && url !== 'about:blank') {\n const state = this.getBrowserStateFromStagehand(this.stagehand);\n if (state) {\n this.lastBrowserState = state;\n }\n }\n return url;\n } catch {\n return null;\n }\n }\n\n /**\n * Navigate to a URL (simple version). Used internally for restoring state on relaunch.\n */\n override async navigateTo(url: string): Promise<void> {\n const page = this.getPage();\n if (!page) return;\n\n try {\n await page.goto(url, {\n timeoutMs: this.config.timeout ?? 30000,\n waitUntil: 'domcontentloaded',\n });\n } catch {\n // Silently ignore navigation errors during restore\n }\n }\n\n /**\n * Get the current browser state (all tabs and active tab index).\n */\n override async getBrowserState(threadId?: string): Promise<BrowserState | null> {\n if (!this.isBrowserRunning()) {\n return null;\n }\n try {\n const scope = this.threadManager.getScope();\n const effectiveThreadId = threadId ?? this.getCurrentThread();\n\n if (scope === 'thread' && effectiveThreadId) {\n const stagehand = this.threadManager.getStagehandForThread(effectiveThreadId);\n if (!stagehand) return null;\n return this.getBrowserStateFromStagehand(stagehand);\n }\n\n return this.getBrowserStateFromStagehand(this.stagehand);\n } catch {\n return null;\n }\n }\n\n /**\n * Get browser state from a specific Stagehand instance.\n */\n private getBrowserStateFromStagehand(stagehand: Stagehand | null): BrowserState | null {\n if (!stagehand?.context) return null;\n\n try {\n const pages = stagehand.context.pages();\n const activePage = stagehand.context.activePage();\n let activeIndex = 0;\n\n const tabs: BrowserTabState[] = pages.map((page, index) => {\n if (page === activePage) {\n activeIndex = index;\n }\n return { url: page.url() };\n });\n\n return {\n tabs,\n activeTabIndex: activeIndex,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Get all open tabs with their URLs and titles.\n */\n override async getTabState(threadId?: string): Promise<BrowserTabState[]> {\n const state = await this.getBrowserState(threadId);\n return state?.tabs ?? [];\n }\n\n /**\n * Get the active tab index.\n */\n override async getActiveTabIndex(threadId?: string): Promise<number> {\n const state = await this.getBrowserState(threadId);\n return state?.activeTabIndex ?? 0;\n }\n\n /**\n * Update the browser state in the thread session.\n * Called on navigation, tab open/close to keep state fresh.\n */\n private updateSessionBrowserState(threadId?: string): void {\n try {\n const effectiveThreadId = threadId ?? this.getCurrentThread() ?? DEFAULT_THREAD_ID;\n const scope = this.threadManager.getScope();\n\n let stagehand: Stagehand | null | undefined = null;\n if (scope === 'thread') {\n stagehand = this.threadManager.getStagehandForThread(effectiveThreadId);\n } else {\n stagehand = this.stagehand;\n }\n\n if (stagehand) {\n const state = this.getBrowserStateFromStagehand(stagehand);\n if (state) {\n this.threadManager.updateBrowserState(effectiveThreadId, state);\n }\n }\n } catch {\n // Silently ignore errors during state update\n }\n }\n\n // ---------------------------------------------------------------------------\n // Screencast (for Studio live view)\n // Uses Stagehand v3's native CDP access\n // ---------------------------------------------------------------------------\n\n /**\n * Get the stream key for a thread (or shared key for shared scope).\n */\n private getStreamKey(threadId?: string): string {\n return threadId || StagehandBrowser.SHARED_STREAM_KEY;\n }\n\n override async startScreencast(options?: ScreencastOptions): Promise<ScreencastStream> {\n const threadId = options?.threadId;\n\n // Create a CDP session provider that gets a fresh session for the current page\n // On reconnect, this will get a fresh CDP session for whatever page is currently active\n const provider = {\n getCdpSession: async () => {\n const page = await this.getPageForThread(threadId ?? '');\n if (!page) {\n throw new Error('No page available for screencast');\n }\n\n const session = this.getCdpSessionForPage(page);\n if (!session) {\n throw new Error('No CDP session available for page');\n }\n\n return session;\n },\n isBrowserRunning: () => this.isBrowserRunning(),\n };\n\n const stream = new ScreencastStreamImpl(provider, options);\n\n // Store the stream for potential future reconnection - keyed by thread\n const streamKey = this.getStreamKey(threadId);\n this.activeScreencastStreams.set(streamKey, stream);\n\n await stream.start();\n\n // Set up tab change detection\n await this.setupTabChangeDetection(threadId, stream);\n\n // Clean up when screencast stops\n stream.once('stop', () => {\n // Remove from streams map using captured key\n if (this.activeScreencastStreams.get(streamKey) === stream) {\n this.activeScreencastStreams.delete(streamKey);\n }\n // Clear debounce timer for this thread\n const timer = this.tabChangeDebounceTimers.get(streamKey);\n if (timer) {\n clearTimeout(timer);\n this.tabChangeDebounceTimers.delete(streamKey);\n }\n });\n\n return stream as unknown as ScreencastStream;\n }\n\n /**\n * Set up listeners to detect tab changes and reconnect the screencast.\n * Uses CDP Target events since Stagehand doesn't expose page lifecycle events.\n */\n private async setupTabChangeDetection(threadId: string | undefined, stream: ScreencastStreamImpl): Promise<void> {\n const stagehand = await this.getStagehandForThread(threadId);\n if (!stagehand?.context) return;\n\n // Use Stagehand's public CDP connection API\n const connection = stagehand.context.conn;\n\n if (!connection) {\n this.logger.debug?.('No CDP connection available for tab change detection');\n return;\n }\n\n // Track targetId -> sessionId for manual tab registration\n const targetSessions = new Map<string, string>();\n\n // Debounce timer for target info changes (separate from tab change timer)\n let targetInfoDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Helper to check if Stagehand is tracking a target\n const isTrackedByStagehand = (targetId: string): boolean => {\n const pages = stagehand.context?.pages() || [];\n return pages.some(p => p.targetId() === targetId);\n };\n\n // Get the stream key for this thread's debounce timer\n const streamKey = this.getStreamKey(threadId);\n\n // Listen for new tab creation\n const onTargetCreated = (params: { targetInfo: { type: string; targetId: string; url: string } }) => {\n if (params.targetInfo.type !== 'page') return;\n\n // Debounce to avoid rapid reconnects (per-thread timer)\n const existingTimer = this.tabChangeDebounceTimers.get(streamKey);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n this.tabChangeDebounceTimers.set(\n streamKey,\n setTimeout(() => {\n this.tabChangeDebounceTimers.delete(streamKey);\n void this.reconnectScreencastForThread(threadId, 'new tab');\n // Re-setup navigation listener for the new active page\n void setupPageNavigationListener();\n // Note: State is saved via tool handlers (new/switch/close), not CDP events\n }, 300),\n );\n };\n\n // Listen for target attached (to capture sessionId for later registration)\n const onTargetAttached = (params: {\n sessionId: string;\n targetInfo: { type: string; targetId: string; url: string };\n waitingForDebugger?: boolean;\n }) => {\n if (params.targetInfo.type !== 'page') return;\n // Always store the sessionId - we may need it for manual registration\n targetSessions.set(params.targetInfo.targetId, params.sessionId);\n };\n\n // Listen for target info changes (URL updates after navigation)\n // Store latest params for debounced handler\n let pendingTargetInfo: { targetInfo: { type: string; targetId: string; url: string } } | null = null;\n\n const onTargetInfoChanged = (params: { targetInfo: { type: string; targetId: string; url: string } }) => {\n if (params.targetInfo.type !== 'page') return;\n\n // Skip if Stagehand already tracks this target\n if (isTrackedByStagehand(params.targetInfo.targetId)) return;\n\n const sessionId = targetSessions.get(params.targetInfo.targetId);\n if (!sessionId) return;\n\n // Debounce to handle rapid URL changes\n pendingTargetInfo = params;\n if (targetInfoDebounceTimer) {\n clearTimeout(targetInfoDebounceTimer);\n }\n targetInfoDebounceTimer = setTimeout(async () => {\n targetInfoDebounceTimer = null;\n if (!pendingTargetInfo) return;\n\n const info = pendingTargetInfo.targetInfo;\n const sid = targetSessions.get(info.targetId);\n pendingTargetInfo = null;\n\n // Re-check if already tracked after debounce\n if (isTrackedByStagehand(info.targetId) || !sid) return;\n\n // Try to register with Stagehand\n const contextAny = stagehand.context as unknown as {\n onAttachedToTarget?: (\n info: { type: string; targetId: string; url: string },\n sessionId: string,\n ) => Promise<void>;\n };\n\n if (contextAny?.onAttachedToTarget) {\n try {\n await contextAny.onAttachedToTarget(info, sid);\n\n // Check if Stagehand actually registered it\n await new Promise(resolve => setTimeout(resolve, 100));\n\n if (isTrackedByStagehand(info.targetId)) {\n this.logger.debug?.('Page registered successfully, setting as active');\n const pages = stagehand.context?.pages() || [];\n const newPage = pages.find(p => p.targetId() === info.targetId);\n if (newPage && stagehand.context) {\n stagehand.context.setActivePage(newPage);\n }\n void this.reconnectScreencast('manual tab tracked');\n void setupPageNavigationListener();\n } else {\n this.logger.debug?.('Stagehand did not register the page (non-injectable URL)');\n }\n } catch (e) {\n this.logger.debug?.('Failed to register page with Stagehand', e);\n }\n }\n }, 300);\n };\n\n // Listen for tab destruction\n const onTargetDestroyed = (params: { targetId: string }) => {\n this.logger.debug?.('Page target destroyed');\n\n // Clean up session tracking\n targetSessions.delete(params.targetId);\n\n // Debounce to avoid rapid reconnects (per-thread timer)\n const existingTimer = this.tabChangeDebounceTimers.get(streamKey);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n this.tabChangeDebounceTimers.set(\n streamKey,\n setTimeout(() => {\n this.tabChangeDebounceTimers.delete(streamKey);\n void this.reconnectScreencastForThread(threadId, 'tab closed');\n // Re-setup navigation listener for the new active page\n void setupPageNavigationListener();\n // Note: Don't save state here - races with browser shutdown.\n // State is saved via tool handlers instead.\n }, 300),\n );\n };\n\n // Listen for navigation events (URL changes) on the PAGE-specific CDP session\n const onFrameNavigated = (params: { frame: { url: string; parentId?: string } }) => {\n // Only emit URL for main frame navigations (no parentId)\n if (!params.frame.parentId && params.frame.url) {\n stream.emitUrl(params.frame.url);\n // Update session state on navigation\n this.updateSessionBrowserState(threadId);\n }\n };\n\n // Track the page session for cleanup\n let pageSession: {\n on?: (event: string, handler: (...args: unknown[]) => void) => void;\n off?: (event: string, handler: (...args: unknown[]) => void) => void;\n } | null = null;\n\n // Set up page-level navigation listener\n const setupPageNavigationListener = async () => {\n try {\n // Clean up previous page session listener if any\n if (pageSession?.off) {\n pageSession.off('Page.frameNavigated', onFrameNavigated as (...args: unknown[]) => void);\n }\n\n const page = stagehand.context?.activePage();\n if (!page) return;\n\n // Get PAGE-specific CDP session (not browser-level connection)\n const session = page.getSessionForFrame(page.mainFrameId());\n if (!session) return;\n\n pageSession = session as typeof pageSession;\n await session.send('Page.enable');\n session.on('Page.frameNavigated', onFrameNavigated as (...args: unknown[]) => void);\n\n // Emit the current URL immediately (since framenavigated won't fire for already-loaded pages)\n const currentUrl = page.url();\n if (currentUrl && currentUrl !== 'about:blank') {\n stream.emitUrl(currentUrl);\n }\n } catch (error) {\n this.logger.debug?.('Failed to set up page navigation listener', error);\n }\n };\n\n // Register cleanup handler first to ensure we can clean up even if setup fails partway\n const cleanup = () => {\n // Clear per-thread debounce timer\n const timer = this.tabChangeDebounceTimers.get(streamKey);\n if (timer) {\n clearTimeout(timer);\n this.tabChangeDebounceTimers.delete(streamKey);\n }\n if (targetInfoDebounceTimer) {\n clearTimeout(targetInfoDebounceTimer);\n targetInfoDebounceTimer = null;\n }\n connection.off?.('Target.targetCreated', onTargetCreated);\n connection.off?.('Target.targetDestroyed', onTargetDestroyed);\n connection.off?.('Target.attachedToTarget', onTargetAttached);\n connection.off?.('Target.targetInfoChanged', onTargetInfoChanged);\n // Clean up page session listener\n if (pageSession?.off) {\n pageSession.off('Page.frameNavigated', onFrameNavigated as (...args: unknown[]) => void);\n }\n };\n\n // Register cleanup before adding listeners to prevent leaks on partial setup failure\n stream.once('stop', cleanup);\n\n try {\n connection.on?.('Target.targetCreated', onTargetCreated);\n connection.on?.('Target.targetDestroyed', onTargetDestroyed);\n connection.on?.('Target.attachedToTarget', onTargetAttached);\n connection.on?.('Target.targetInfoChanged', onTargetInfoChanged);\n\n // Set up navigation listener on the current page\n await setupPageNavigationListener();\n } catch (error) {\n this.logger.debug?.('Failed to set up tab change detection', error);\n // Cleanup is already registered on stream stop, no need to call here\n }\n }\n\n /**\n * Reconnect the active screencast for a specific thread.\n */\n private async reconnectScreencastForThread(threadId: string | undefined, reason: string): Promise<void> {\n const streamKey = this.getStreamKey(threadId);\n const stream = this.activeScreencastStreams.get(streamKey);\n if (!stream || !stream.isActive()) {\n return;\n }\n\n // Check if browser is still running before attempting reconnect\n if (!this.isBrowserRunning()) {\n this.logger.debug?.('Skipping screencast reconnect - browser not running');\n return;\n }\n\n // For thread scope, also check if this specific thread still has a session\n const scope = this.getScope();\n if (scope === 'thread' && threadId && !this.threadManager.getStagehandForThread(threadId)) {\n this.logger.debug?.(`Skipping screencast reconnect - no session for thread ${threadId}`);\n return;\n }\n\n this.logger.debug?.(`Reconnecting screencast: ${reason}`);\n\n try {\n // Small delay to let tab state settle\n await new Promise(resolve => setTimeout(resolve, 150));\n await stream.reconnect();\n\n // Emit the URL of the new active page after reconnecting\n const stagehand = await this.getStagehandForThread(threadId);\n const activePage = stagehand?.context?.activePage();\n if (activePage) {\n const url = activePage.url();\n if (url) {\n stream.emitUrl(url);\n }\n }\n } catch (error) {\n this.logger.debug?.('Screencast reconnect failed', error);\n }\n }\n\n /**\n * Reconnect the active screencast for the current thread.\n * Wrapper for reconnectScreencastForThread using getCurrentThread().\n */\n private async reconnectScreencast(reason: string): Promise<void> {\n const threadId = this.getCurrentThread();\n await this.reconnectScreencastForThread(threadId, reason);\n }\n\n // NOTE: Manual tab switching in browser UI is not fully supported.\n // Stagehand v3 does not track pages opened via browser UI (only pages created through its API).\n // We've requested this feature from Browserbase - see Notion doc for details.\n\n // ---------------------------------------------------------------------------\n // Event Injection (for Studio live view interactivity)\n // ---------------------------------------------------------------------------\n\n override async injectMouseEvent(event: MouseEventParams, threadId?: string): Promise<void> {\n // Use the provided threadId, or fall back to the current thread\n const effectiveThreadId = threadId ?? this.getCurrentThread();\n const page = await this.getPageForThread(effectiveThreadId ?? '');\n const cdpSession = this.getCdpSessionForPage(page);\n\n if (!cdpSession) {\n throw new Error('No CDP session available');\n }\n\n // CDP buttons bitmask: left=1, right=2, middle=4\n const buttonMap: Record<string, number> = {\n none: 0,\n left: 1,\n middle: 4,\n right: 2,\n };\n\n // clickCount should only default to 1 for press/release events; move and wheel use 0\n const defaultClickCount = event.type === 'mousePressed' || event.type === 'mouseReleased' ? 1 : 0;\n\n await cdpSession.send('Input.dispatchMouseEvent', {\n type: event.type,\n x: event.x,\n y: event.y,\n button: event.button ?? 'none',\n buttons: buttonMap[event.button ?? 'none'] ?? 0,\n clickCount: event.clickCount ?? defaultClickCount,\n deltaX: event.deltaX ?? 0,\n deltaY: event.deltaY ?? 0,\n modifiers: event.modifiers ?? 0,\n });\n }\n\n override async injectKeyboardEvent(event: KeyboardEventParams, threadId?: string): Promise<void> {\n // Use the provided threadId, or fall back to the current thread\n const effectiveThreadId = threadId ?? this.getCurrentThread();\n const page = await this.getPageForThread(effectiveThreadId ?? '');\n const cdpSession = this.getCdpSessionForPage(page);\n\n if (!cdpSession) {\n throw new Error('No CDP session available');\n }\n\n await cdpSession.send('Input.dispatchKeyEvent', {\n type: event.type,\n key: event.key,\n code: event.code,\n text: event.text,\n modifiers: event.modifiers ?? 0,\n windowsVirtualKeyCode: event.windowsVirtualKeyCode,\n });\n }\n}\n"]}
|