The model to use for tool execution (observe/act calls within agent tools). If not specified, inherits from the main model configuration.Format:"provider/model" (e.g., "openai/gpt-4o-mini", "google/gemini-2.0-flash-exp")
Enable streaming mode for the agent. When true, execute() returns AgentStreamResult with textStream for incremental output. When false (default), execute() returns AgentResult after completion.Default:false
Non-CUA agents only. Requires experimental: true. Not available when mode: "cua".
Tool mode for the agent. Determines which set of tools are available to the agent.Modes:
"dom" (default): Uses DOM-based tools (act, fillForm) for structured page interactions. Works with any model.
"hybrid": Uses both DOM-based and coordinate-based tools (act, click, type, dragAndDrop, clickAndHold, fillForm) for visual/screenshot-based interactions. Requires models with reliable coordinate-based action capabilities.
"cua": Uses Computer Use Agent (CUA) providers like Anthropic Claude, Google Gemini, or OpenAI for screenshot-based automation. This is the preferred way to enable CUA mode (replaces the deprecated cua: true option).
Default:"dom"
Hybrid Mode Model Requirements: Only use hybrid mode with models that can reliably perform coordinate-based actions:
Tools to exclude from this execution. Pass an array of tool names to prevent the agent from using those tools.Available tools by mode:DOM mode (default):act, fillForm, ariaTree, extract, goto, scroll, keys, navback, screenshot, think, wait, searchHybrid mode:click, type, dragAndDrop, clickAndHold, fillFormVision, act, ariaTree, extract, goto, scroll, keys, navback, screenshot, think, wait, search
Non-CUA agents only. Requires experimental: true. Not available when cua: true.
A Zod schema defining structured output data to return when the task completes. The agent will populate this data based on the information it gathered during execution. The result will be available in AgentResult.output.
Non-CUA agents only. Requires experimental: true. Not available when mode: "cua".
Copy
Ask AI
import { z } from "zod/v3";const result = await agent.execute({ instruction: "Find the cheapest flight from NYC to LA", output: z.object({ price: z.string().describe("The price of the flight"), airline: z.string().describe("The airline name"), departureTime: z.string().describe("Departure time"), }),});console.log(result.output); // { price: "$199", airline: "Delta", departureTime: "8:00 AM" }
interface AgentStreamResult { // Async iterable of text chunks for incremental output textStream: AsyncIterable<string>; // Async iterable of all stream events (tool calls, messages, etc.) fullStream: AsyncIterable<StreamPart>; // Promise that resolves to the final AgentResult when streaming completes result: Promise<AgentResult>; // Additional properties from StreamTextResult<ToolSet, never> // See Vercel AI SDK documentation for full details}
import { Stagehand } from "@browserbasehq/stagehand";// Initialize with Browserbase (API key and project ID from environment variables)// Set BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID in your environmentconst stagehand = new Stagehand({ env: "BROWSERBASE", model: "anthropic/claude-sonnet-4-20250514"});await stagehand.init();const page = stagehand.context.pages()[0];// Create agent with default configurationconst agent = stagehand.agent();// Navigate to a pageawait page.goto("https://www.google.com");// Execute a taskconst result = await agent.execute("Search for 'Stagehand automation' and click the first result");console.log(result.message);console.log(`Completed: ${result.completed}`);console.log(`Actions taken: ${result.actions.length}`);
Copy
Ask AI
// Create agent with custom model and system promptconst agent = stagehand.agent({ model: "openai/computer-use-preview", systemPrompt: "You are a helpful assistant that can navigate websites efficiently. Always verify actions before proceeding.", executionModel: "openai/gpt-4o-mini" // Use faster model for tool execution});const page = stagehand.context.pages()[0];await page.goto("https://example.com");const result = await agent.execute({ instruction: "Fill out the contact form with test data", maxSteps: 10, highlightCursor: true});
Copy
Ask AI
// Using AgentModelConfig for advanced configurationconst agent = stagehand.agent({ model: { modelName: "anthropic/claude-sonnet-4-20250514", apiKey: process.env.ANTHROPIC_API_KEY, baseURL: "https://custom-proxy.com/v1" }});const result = await agent.execute("Complete the checkout process");
Copy
Ask AI
const page1 = stagehand.context.pages()[0];const page2 = await stagehand.context.newPage();const agent = stagehand.agent();// Execute on specific pageawait page2.goto("https://example.com/dashboard");const result = await agent.execute({ instruction: "Export the data table", page: page2});
Copy
Ask AI
const stagehand = new Stagehand({ env: "LOCAL", experimental: true, // Required for streaming});await stagehand.init();const page = stagehand.context.pages()[0];await page.goto("https://amazon.com");// Create a streaming agentconst agent = stagehand.agent({ model: "anthropic/claude-sonnet-4-5-20250929", stream: true,});const streamResult = await agent.execute({ instruction: "Search for headphones and find the best deal", maxSteps: 20,});// Stream text output incrementallyfor await (const delta of streamResult.textStream) { process.stdout.write(delta);}// Get the final resultconst finalResult = await streamResult.result;console.log("Completed:", finalResult.completed);
Copy
Ask AI
const stagehand = new Stagehand({ env: "LOCAL", experimental: true,});await stagehand.init();const agent = stagehand.agent({ model: "anthropic/claude-sonnet-4-5-20250929",});const page = stagehand.context.pages()[0];await page.goto("https://example.com");const result = await agent.execute({ instruction: "Fill out the contact form", maxSteps: 10, callbacks: { prepareStep: async (stepContext) => { console.log(`Starting step ${stepContext.stepNumber}`); return stepContext; }, onStepFinish: async (event) => { console.log(`Step finished: ${event.finishReason}`); if (event.toolCalls) { for (const tc of event.toolCalls) { console.log(`Tool: ${tc.toolName}`, tc.input); } } }, },});
Copy
Ask AI
const stagehand = new Stagehand({ env: "LOCAL", experimental: true,});await stagehand.init();const agent = stagehand.agent({ model: "anthropic/claude-sonnet-4-5-20250929",});const page = stagehand.context.pages()[0];await page.goto("https://example.com");const controller = new AbortController();// Abort after 30 secondssetTimeout(() => controller.abort("Timeout exceeded"), 30000);try { const result = await agent.execute({ instruction: "Complete a complex multi-step workflow", maxSteps: 50, signal: controller.signal, });} catch (error) { if (error.name === "AgentAbortError") { console.log("Task cancelled:", error.message); }}
Copy
Ask AI
const stagehand = new Stagehand({ env: "LOCAL", experimental: true,});await stagehand.init();const agent = stagehand.agent({ model: "anthropic/claude-sonnet-4-5-20250929",});const page = stagehand.context.pages()[0];await page.goto("https://example.com/shop");// First executionconst firstResult = await agent.execute({ instruction: "Search for laptops and list the top 3 options", maxSteps: 10,});// Continue conversation with context from first runconst secondResult = await agent.execute({ instruction: "Filter those results by price under $1000", maxSteps: 10, messages: firstResult.messages, // Pass previous messages});// Chain further with accumulated contextconst thirdResult = await agent.execute({ instruction: "Add the best-rated one to cart", maxSteps: 10, messages: secondResult.messages,});console.log("Final:", thirdResult.message);
Copy
Ask AI
import { Client } from "@modelcontextprotocol/sdk/client/index.js";// Create agent with MCP integrationsconst agent = stagehand.agent({ model: "anthropic/claude-sonnet-4-20250514", integrations: [ "https://mcp-server.example.com", // MCP server URL mcpClientInstance // Or pre-connected Client object ]});const result = await agent.execute("Use the external tool to process this data");
Copy
Ask AI
const stagehand = new Stagehand({ env: "LOCAL", experimental: true, // Required for excludeTools});await stagehand.init();const agent = stagehand.agent({ model: "anthropic/claude-sonnet-4-5-20250929",});const page = stagehand.context.pages()[0];await page.goto("https://example.com");// Exclude specific tools from this executionconst result = await agent.execute({ instruction: "Navigate the page and click buttons", maxSteps: 15, excludeTools: ["screenshot", "extract", "search"],});console.log("Completed:", result.completed);
Copy
Ask AI
const stagehand = new Stagehand({ env: "LOCAL", experimental: true, // Required for hybrid mode});await stagehand.init();// Create agent with hybrid mode for coordinate-based interactionsconst agent = stagehand.agent({ mode: "hybrid", model: "google/gemini-3-flash-preview", // Use a model that supports coordinate-based actions});const page = stagehand.context.pages()[0];await page.goto("https://example.com/form");const result = await agent.execute({ instruction: "Fill out the registration form with test data", maxSteps: 15, highlightCursor: true, // Enabled by default in hybrid mode});console.log("Completed:", result.completed);
Copy
Ask AI
import { z } from "zod/v3";const stagehand = new Stagehand({ env: "LOCAL", experimental: true, // Required for structured output});await stagehand.init();const agent = stagehand.agent({ model: "anthropic/claude-sonnet-4-5-20250929",});const page = stagehand.context.pages()[0];await page.goto("https://www.google.com/flights");// Define output schema to receive structured dataconst result = await agent.execute({ instruction: "Find the cheapest flight from NYC to LA for next week", maxSteps: 20, output: z.object({ price: z.string().describe("The price of the flight"), airline: z.string().describe("The airline name"), departureTime: z.string().describe("Departure time"), arrivalTime: z.string().describe("Arrival time"), flightNumber: z.string().optional().describe("Flight number if available"), }),});// Access the structured outputconsole.log("Flight found:");console.log(` Price: ${result.output?.price}`);console.log(` Airline: ${result.output?.airline}`);console.log(` Departure: ${result.output?.departureTime}`);console.log(` Arrival: ${result.output?.arrivalTime}`);
Copy
Ask AI
import { tool } from "ai";import { z } from "zod/v3";// Define custom tools using AI SDK formatconst customTools = { calculateTotal: tool({ description: "Calculate the total of items in cart", parameters: z.object({ items: z.array(z.object({ price: z.number(), quantity: z.number() })) }), execute: async ({ items }) => { const total = items.reduce((sum, item) => sum + (item.price * item.quantity), 0); return { total }; } })};const agent = stagehand.agent({ model: "openai/computer-use-preview", tools: customTools});const result = await agent.execute("Calculate the total cost of items in the shopping cart");
The following errors may be thrown by the agent() method:
StagehandError - Base class for all Stagehand-specific errors
StagehandInitError - Agent was not properly initialized
MissingLLMConfigurationError - No LLM API key or client configured
UnsupportedModelError - The specified model is not supported for agent functionality
UnsupportedModelProviderError - The specified model provider is not supported
InvalidAISDKModelFormatError - Model string does not follow the required provider/model format
MCPConnectionError - Failed to connect to MCP server
StagehandDefaultError - General execution error with detailed message
AgentAbortError - Thrown when agent execution is cancelled via an AbortSignal
StreamingCallbacksInNonStreamingModeError - Thrown when streaming-only callbacks (onChunk, onFinish, onError, onAbort) are used without stream: true
ExperimentalNotConfiguredError - Thrown when experimental features (callbacks, signal, messages, streaming) are used without experimental: true in Stagehand constructor