act(), extract(), observe(), and agent().
Access
Available on all sessions except Selenium:Copy
import { playwright } from '@bctrl/sdk';
const session = await playwright.connect({ apiKey: '...' });
// Use Stagehand methods
await session.stagehand.act('...');
await session.stagehand.extract('...', schema);
await session.stagehand.observe();
const agent = session.stagehand.agent();
act()
Execute a single action using natural language.Copy
await session.stagehand.act('Click the login button');
Examples
Copy
// Clicks
await session.stagehand.act('Click the Sign In button');
await session.stagehand.act('Click the first search result');
// Typing
await session.stagehand.act('Type "hello world" in the search box');
await session.stagehand.act('Fill the email field with [email protected]');
// Selection
await session.stagehand.act('Select "California" from the state dropdown');
await session.stagehand.act('Check the "Remember me" checkbox');
// Navigation
await session.stagehand.act('Scroll down to the pricing section');
await session.stagehand.act('Click the Next Page button');
// Complex
await session.stagehand.act('Close the cookie consent banner');
await session.stagehand.act('Expand the "Advanced Options" section');
Options
Copy
const result = await session.stagehand.act('Click submit', {
modelName: 'gpt-4o', // LLM to use
timeout: 30000, // Timeout in ms
});
Return Value
Copy
interface ActResult {
success: boolean;
action: {
type: 'click' | 'type' | 'scroll' | 'wait' | 'goto';
description: string;
selector?: string;
value?: string;
};
}
extract()
Extract structured data from the page.Copy
import { z } from 'zod';
const data = await session.stagehand.extract(
'Get the product details',
z.object({
name: z.string(),
price: z.number()
})
);
Schema Types
Copy
// String
const title = await session.stagehand.extract(
'Get the page title',
z.string()
);
// Number
const price = await session.stagehand.extract(
'Get the product price',
z.number()
);
// Boolean
const inStock = await session.stagehand.extract(
'Is the product in stock?',
z.boolean()
);
// Object
const product = await session.stagehand.extract(
'Get product details',
z.object({
name: z.string(),
price: z.number(),
description: z.string(),
rating: z.number().optional()
})
);
// Array
const items = await session.stagehand.extract(
'Get all menu items with prices',
z.array(z.object({
name: z.string(),
price: z.number()
}))
);
// Enum
const status = await session.stagehand.extract(
'What is the order status?',
z.enum(['pending', 'processing', 'shipped', 'delivered'])
);
Tips for Better Extraction
Be specific in your instruction
Be specific in your instruction
Copy
// Bad - vague
await session.stagehand.extract('Get the data', schema);
// Good - specific
await session.stagehand.extract(
'Get all product names and prices from the search results table',
schema
);
Use appropriate schema types
Use appropriate schema types
Copy
// Bad - string for numbers
z.object({ price: z.string() })
// Good - proper types
z.object({ price: z.number() })
Mark optional fields
Mark optional fields
Copy
z.object({
name: z.string(),
rating: z.number().optional(), // May not exist
reviews: z.array(z.string()).default([])
})
observe()
Identify available actions on the current page.Copy
const actions = await session.stagehand.observe();
Examples
Copy
// Get all available actions
const actions = await session.stagehand.observe();
// Returns: StagehandAction[]
// With specific instruction
const buttons = await session.stagehand.observe('Find all clickable buttons');
const forms = await session.stagehand.observe('Find all form inputs');
Use Cases
Copy
// Discover page structure
const actions = await session.stagehand.observe();
console.log('Available actions:', actions);
// Then act on what you found
if (actions.some(a => a.description.includes('login'))) {
await session.stagehand.act('Click the login button');
}
agent()
Create an autonomous agent for multi-step tasks.Copy
const agent = session.stagehand.agent({
maxSteps: 10
});
const result = await agent.execute('Book a flight from NYC to LA');
Configuration
Copy
const agent = session.stagehand.agent({
modelName: 'gpt-4o', // LLM to use
maxSteps: 10, // Maximum actions
maxRetries: 3, // Retries per step
temperature: 0.1 // LLM temperature
});
Execution
Copy
const result = await agent.execute(
'Search for laptops under $500 and add the best-rated one to cart'
);
console.log(result.success); // boolean
console.log(result.message); // Summary
console.log(result.actions); // All actions taken
Example
Copy
import { playwright } from '@bctrl/sdk';
const session = await playwright.connect({ apiKey: '...' });
await session.page.goto('https://amazon.com');
const agent = session.stagehand.agent({
modelName: 'gpt-4o',
maxSteps: 15
});
const result = await agent.execute(`
1. Search for "wireless headphones"
2. Filter by 4+ star rating
3. Sort by price low to high
4. Click on the first result
5. Add it to cart
`);
if (result.success) {
console.log('Added to cart!');
console.log('Actions taken:', result.actions.length);
}
await session.close();
Metrics & History
Track AI usage:Copy
// Get usage metrics
const metrics = await session.stagehand.getMetrics();
console.log('Total tokens:', metrics.totalInputTokens + metrics.totalOutputTokens);
console.log('Total actions:', metrics.totalActions);
// Get operation history
const history = await session.stagehand.getHistory();
for (const entry of history) {
console.log(entry.action, entry.success);
}
Full Example
Copy
import { playwright } from '@bctrl/sdk';
import { z } from 'zod';
async function scrapeAndAnalyze() {
const session = await playwright.connect({
apiKey: process.env.BCTRL_API_KEY
});
const page = session.page;
await page.goto('https://news.ycombinator.com');
// Extract top stories
const stories = await session.stagehand.extract(
'Get the top 10 stories with title, URL, points, and comment count',
z.array(z.object({
title: z.string(),
url: z.string(),
points: z.number(),
comments: z.number()
}))
);
console.log('Top stories:', stories);
// Navigate and extract more
await session.stagehand.act('Click on the top story');
// Let agent summarize
const agent = session.stagehand.agent({ maxSteps: 5 });
const summary = await agent.execute(
'Read the article and provide a 2-sentence summary'
);
console.log('Summary:', summary.message);
// Check metrics
const metrics = await session.stagehand.getMetrics();
console.log('Tokens used:', metrics.totalInputTokens + metrics.totalOutputTokens);
await session.close();
}
scrapeAndAnalyze();

