Documentation Index
Fetch the complete documentation index at: https://mintlify.com/browserbase/stagehand/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Stagehand agents support streaming execution, allowing you to receive real-time updates as the agent performs actions. This is particularly useful for:
- Providing live feedback to users
- Monitoring long-running automation tasks
- Debugging agent behavior
- Building interactive UIs
Basic Streaming Example
Here’s how to create a streaming agent and consume its output:
import { Stagehand } from "@stagehand/core";
import chalk from "chalk";
async function main() {
console.log(`\n${chalk.bold("Stagehand 🤘 Agent Streaming Example")}\n`);
// Initialize Stagehand
const stagehand = new Stagehand({
env: "LOCAL",
verbose: 0,
cacheDir: "stagehand-agent-cache",
logInferenceToFile: false,
experimental: true,
});
await stagehand.init();
try {
const page = stagehand.context.pages()[0];
await page.goto("https://amazon.com");
// Create a streaming agent with stream: true in the config
const agent = stagehand.agent({
model: "anthropic/claude-sonnet-4-5-20250929",
stream: true, // This makes execute() return AgentStreamResult
});
const agentRun = await agent.execute({
instruction: "go to amazon, and search for shampoo, stop after searching",
maxSteps: 20,
});
// Stream the text
for await (const delta of agentRun.textStream) {
process.stdout.write(delta);
}
const finalResult = await agentRun.result;
console.log("Final Result:", finalResult);
} catch (error) {
console.log(`${chalk.red("✗")} Error: ${error}`);
}
}
main();
Streaming Full Events
You can also stream complete events including tool calls and messages:
import { Stagehand } from "@stagehand/core";
async function streamFullEvents() {
const stagehand = new Stagehand({
env: "LOCAL",
verbose: 0,
experimental: true,
});
await stagehand.init();
const page = stagehand.context.pages()[0];
await page.goto("https://amazon.com");
const agent = stagehand.agent({
model: "anthropic/claude-sonnet-4-5-20250929",
stream: true,
});
const agentRun = await agent.execute({
instruction: "search for wireless headphones and show me the top result",
maxSteps: 20,
});
// Stream everything (tool calls, messages, etc.)
for await (const delta of agentRun.fullStream) {
console.log(delta);
}
const finalResult = await agentRun.result;
console.log("Final Result:", finalResult);
await stagehand.close();
}
streamFullEvents();
Stream Result Types
When stream: true is enabled, agent.execute() returns an AgentStreamResult object with:
textStream
Streams text deltas as they’re generated:
for await (const delta of agentRun.textStream) {
process.stdout.write(delta); // Print incrementally
}
fullStream
Streams complete events including:
- Tool calls
- Messages
- Intermediate results
- Status updates
for await (const event of agentRun.fullStream) {
console.log(event.type, event.data);
}
result
A promise that resolves to the final result:
const finalResult = await agentRun.result;
console.log("Complete:", finalResult);
Streaming with Custom Tools
You can combine streaming with custom tools:
import { z } from "zod";
import { tool } from "ai";
import { Stagehand } from "@stagehand/core";
const searchProducts = tool({
description: "Search for products in a database",
inputSchema: z.object({
query: z.string(),
}),
execute: async ({ query }) => {
// Your search logic
return { results: ["Product 1", "Product 2"] };
},
});
async function streamWithTools() {
const stagehand = new Stagehand({
env: "LOCAL",
experimental: true,
});
await stagehand.init();
const page = stagehand.context.pages()[0];
await page.goto("https://example-store.com");
const agent = stagehand.agent({
stream: true,
tools: {
searchProducts,
},
});
const agentRun = await agent.execute({
instruction: "Search for 'laptop' and show me the results",
maxSteps: 20,
});
for await (const delta of agentRun.textStream) {
process.stdout.write(delta);
}
const result = await agentRun.result;
console.log("\nFinal:", result);
await stagehand.close();
}
streamWithTools();
Streaming with CUA
Streaming works with Computer Use Agents:
import { Stagehand } from "@stagehand/core";
async function streamCUA() {
const stagehand = new Stagehand({
env: "LOCAL",
verbose: 0,
experimental: true,
});
await stagehand.init();
const page = stagehand.context.pages()[0];
const agent = stagehand.agent({
mode: "cua",
model: {
modelName: "anthropic/claude-sonnet-4-5-20250929",
apiKey: process.env.ANTHROPIC_API_KEY,
},
stream: true,
});
await page.goto("https://www.google.com");
const agentRun = await agent.execute({
instruction: "Search for 'Stagehand documentation' and click the first result",
maxSteps: 20,
});
for await (const delta of agentRun.textStream) {
process.stdout.write(delta);
}
const result = await agentRun.result;
console.log("\nComplete:", result);
await stagehand.close();
}
streamCUA();
Building a Progress UI
Here’s an example of using streaming to build a progress indicator:
import { Stagehand } from "@stagehand/core";
import chalk from "chalk";
async function withProgressUI() {
const stagehand = new Stagehand({
env: "LOCAL",
experimental: true,
});
await stagehand.init();
const page = stagehand.context.pages()[0];
await page.goto("https://amazon.com");
const agent = stagehand.agent({
model: "anthropic/claude-sonnet-4-5-20250929",
stream: true,
});
const agentRun = await agent.execute({
instruction: "Find and add wireless earbuds to cart",
maxSteps: 30,
});
let stepCount = 0;
console.log(chalk.blue("🤖 Agent working...\n"));
for await (const event of agentRun.fullStream) {
if (event.type === "tool-call") {
stepCount++;
console.log(chalk.yellow(`Step ${stepCount}: ${event.data.toolName}`));
} else if (event.type === "text-delta") {
process.stdout.write(chalk.gray(event.data));
}
}
const result = await agentRun.result;
console.log(chalk.green("\n\n✓ Task complete!"));
console.log("Result:", result);
await stagehand.close();
}
withProgressUI();
Error Handling with Streams
Handle errors when streaming:
import { Stagehand } from "@stagehand/core";
async function streamWithErrorHandling() {
const stagehand = new Stagehand({
env: "LOCAL",
experimental: true,
});
await stagehand.init();
try {
const page = stagehand.context.pages()[0];
await page.goto("https://example.com");
const agent = stagehand.agent({
stream: true,
});
const agentRun = await agent.execute({
instruction: "Complete a complex task",
maxSteps: 20,
});
try {
for await (const delta of agentRun.textStream) {
process.stdout.write(delta);
}
const result = await agentRun.result;
console.log("Success:", result);
} catch (streamError) {
console.error("Stream error:", streamError);
}
} catch (error) {
console.error("Agent error:", error);
} finally {
await stagehand.close();
}
}
streamWithErrorHandling();
Key Concepts
Enable Streaming
Set stream: true in the agent configuration:
const agent = stagehand.agent({
stream: true, // Enable streaming
});
Async Iterators
Both textStream and fullStream are async iterators:
for await (const item of stream) {
// Process each item as it arrives
}
Result Promise
The result property is a promise that resolves when execution completes:
const finalResult = await agentRun.result;
Best Practices
- Use textStream for simple output - Best for displaying progress to users
- Use fullStream for detailed monitoring - Access all events for debugging
- Handle errors in streams - Wrap streaming logic in try/catch
- Await the result - Always await
result to get the final output
- Close resources - Call
stagehand.close() when done
- Disable verbose logging - Set
verbose: 0 to avoid cluttering stream output
Configuration Options
const stagehand = new Stagehand({
env: "LOCAL",
verbose: 0, // Disable logs for cleaner streaming
cacheDir: "stagehand-agent-cache",
logInferenceToFile: false, // Disable file logging
experimental: true, // Required for streaming
});
Next Steps