Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(community): Stagehand tools integration #7177

Merged
merged 36 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
cd9ea38
add docs and package for stagehand;
filip-michalsky Nov 10, 2024
c048a2d
update doc
filip-michalsky Nov 10, 2024
9d2b5a8
work on integration with stagehand
filip-michalsky Nov 10, 2024
82c7b5d
work on toolkit
filip-michalsky Nov 10, 2024
6cb4ed2
clean up
filip-michalsky Nov 13, 2024
34f33a4
resolving dependency errors
filip-michalsky Nov 13, 2024
22a4837
revert .gitignore changes
filip-michalsky Nov 13, 2024
0f1424c
revert gitignore
filip-michalsky Nov 13, 2024
b904ce7
revert gitignore
filip-michalsky Nov 13, 2024
2d4e802
cherry pick
filip-michalsky Nov 13, 2024
704b51c
update community deps
filip-michalsky Nov 13, 2024
2cf563c
add web nav as a tool
filip-michalsky Nov 14, 2024
dbf66a7
move stagehand toolkit and tests to toolkits dir
filip-michalsky Nov 14, 2024
6f20937
pr ready for review
filip-michalsky Nov 14, 2024
b77a507
Merge branch 'main' into stagehand-tools
filip-michalsky Nov 14, 2024
f967e06
build
filip-michalsky Nov 14, 2024
123b5fa
improve type checking
filip-michalsky Nov 14, 2024
5e7f508
remove openai from dependencies
filip-michalsky Nov 20, 2024
f7554a5
update config
filip-michalsky Nov 20, 2024
af332bc
wip on addressing feedback
filip-michalsky Nov 20, 2024
a747a6d
update stagehand tool
filip-michalsky Nov 21, 2024
5049507
update the integration test
filip-michalsky Nov 21, 2024
d373f71
add langgraph
filip-michalsky Nov 21, 2024
1d39522
linting
filip-michalsky Nov 21, 2024
bd53a5b
fix linting
filip-michalsky Nov 21, 2024
5bc5404
fix linter
filip-michalsky Nov 21, 2024
3495a41
linting and formatting done
filip-michalsky Nov 21, 2024
4038207
Merge branch 'main' into stagehand-tools
filip-michalsky Nov 21, 2024
ea731f9
trigger docs build
filip-michalsky Nov 21, 2024
e990949
fix example package json
filip-michalsky Nov 21, 2024
a051f5c
bump stagehand version dep
filip-michalsky Nov 24, 2024
72793c1
Revert "bump stagehand version dep"
filip-michalsky Nov 24, 2024
9ae7525
need openai dep to run stagehand extract
filip-michalsky Nov 24, 2024
75c8fd0
Remove LangGraph dep
jacoblee93 Nov 25, 2024
838163a
Merge branch 'main' of github.com:langchain-ai/langchainjs into 7177
jacoblee93 Nov 25, 2024
409e419
Reset lockfile
jacoblee93 Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions docs/core_docs/docs/integrations/tools/stagehand.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
sidebar_label: Stagehand AI Web Automation Toolkit
hide_table_of_contents: true
---

import CodeBlock from "@theme/CodeBlock";
import Example from "@examples/agents/stagehand_ai_web_browser.ts";
import { StagehandToolkit } from "@langchain/community/agents/toolkits/stagehand";

# Stagehand Toolkit

The Stagehand Toolkit equips your AI agent with the following capabilities:

- **navigate()**: Navigate to a specific URL.
- **act()**: Perform browser automation actions like clicking, typing, and navigation.
- **extract()**: Extract structured data from web pages using Zod schemas.
- **observe()**: Get a list of possible actions and elements on the current page.

## Setup

1. Install the required packages:

```bash
npm install @langchain/langgraph @langchain/community @langchain/core
```

2. Create a Stagehand Instance
If you plan to run the browser locally, you'll also need to install Playwright's browser dependencies.

```bash
npx playwright install
```

3. Set up your model provider credentials:

For OpenAI:

```bash
export OPENAI_API_KEY="your-openai-api-key"
```

For Anthropic:

```bash
export ANTHROPIC_API_KEY="your-anthropic-api-key"
```

## Usage, Standalone, Local Browser

```typescript
import { StagehandToolkit } from "langchain/community/agents/toolkits/stagehand";
import { ChatOpenAI } from "@langchain/openai";
import { Stagehand } from "@browserbasehq/stagehand";

// Specify your Browserbase credentials.
process.env.BROWSERBASE_API_KEY = "";
process.env.BROWSERBASE_PROJECT_ID = "";

// Specify OpenAI API key.
process.env.OPENAI_API_KEY = "";

const stagehand = new Stagehand({
env: "LOCAL",
headless: false,
verbose: 2,
debugDom: true,
enableCaching: false,
});

// Create a Stagehand Toolkit with all the available actions from the Stagehand.
const stagehandToolkit = await StagehandToolkit.fromStagehand(stagehand);

const navigateTool = stagehandToolkit.tools.find(
(t) => t.name === "stagehand_navigate"
);
if (!navigateTool) {
throw new Error("Navigate tool not found");
}
await navigateTool.invoke("https://www.google.com");

const actionTool = stagehandToolkit.tools.find(
(t) => t.name === "stagehand_act"
);
if (!actionTool) {
throw new Error("Action tool not found");
}
await actionTool.invoke('Search for "OpenAI"');

const observeTool = stagehandToolkit.tools.find(
(t) => t.name === "stagehand_observe"
);
if (!observeTool) {
throw new Error("Observe tool not found");
}
const result = await observeTool.invoke(
"What actions can be performed on the current page?"
);
const observations = JSON.parse(result);

// Handle observations as needed
console.log(observations);

const currentUrl = stagehand.page.url();
expect(currentUrl).toContain("google.com/search?q=OpenAI");
```

## Usage with LangGraph Agents

<CodeBlock language="typescript">{Example}</CodeBlock>

## Usage on Browserbase - remote headless browser

If you want to run the browser remotely, you can use the Browserbase platform.

You need to set the `BROWSERBASE_API_KEY` environment variable to your Browserbase API key.

```bash
export BROWSERBASE_API_KEY="your-browserbase-api-key"
```

You also need to set `BROWSERBASE_PROJECT_ID` to your Browserbase project ID.

```bash
export BROWSERBASE_PROJECT_ID="your-browserbase-project-id"
```

Then initialize the Stagehand instance with the `BROWSERBASE` environment.

```typescript
const stagehand = new Stagehand({
env: "BROWSERBASE",
});
```

## Related

- Tool [conceptual guide](/docs/concepts/tools)
- Tool [how-to guides](/docs/how_to/#tools)
- [Stagehand Documentation](https://github.com/browserbase/stagehand#readme)
1 change: 1 addition & 0 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"license": "MIT",
"dependencies": {
"@azure/identity": "^4.2.1",
"@browserbasehq/stagehand": "^1.3.0",
"@clickhouse/client": "^0.2.5",
"@elastic/elasticsearch": "^8.4.0",
"@faker-js/faker": "^8.4.1",
Expand Down
87 changes: 87 additions & 0 deletions examples/src/agents/stagehand_ai_web_browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { Stagehand } from "@browserbasehq/stagehand";
import {
StagehandActTool,
StagehandNavigateTool,
} from "@langchain/community/agents/toolkits/stagehand";
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

async function main() {
// Initialize Stagehand once and pass it to the tools
const stagehand = new Stagehand({
env: "LOCAL",
enableCaching: true,
});

const actTool = new StagehandActTool(stagehand);
const navigateTool = new StagehandNavigateTool(stagehand);

// Initialize the model
const model = new ChatOpenAI({
modelName: "gpt-4",
temperature: 0,
});

// Create the agent using langgraph
const agent = createReactAgent({
llm: model,
tools: [actTool, navigateTool],
});

// Execute the agent using streams
const inputs1 = {
messages: [
{
role: "user",
content: "Navigate to https://www.google.com",
},
],
};

const stream1 = await agent.stream(inputs1, {
streamMode: "values",
});

for await (const { messages } of stream1) {
const msg =
messages && messages.length > 0
? messages[messages.length - 1]
: undefined;
if (msg?.content) {
console.log(msg.content);
} else if (msg?.tool_calls && msg.tool_calls.length > 0) {
console.log(msg.tool_calls);
} else {
console.log(msg);
}
}

const inputs2 = {
messages: [
{
role: "user",
content: "Search for 'OpenAI'",
},
],
};

const stream2 = await agent.stream(inputs2, {
streamMode: "values",
});

for await (const { messages } of stream2) {
const msg =
messages && messages.length > 0
? messages[messages.length - 1]
: undefined;
if (msg?.content) {
console.log(msg.content);
} else if (msg?.tool_calls && msg.tool_calls.length > 0) {
console.log(msg.tool_calls);
} else {
console.log(msg);
}
}
}

main();
2 changes: 2 additions & 0 deletions libs/langchain-community/langchain.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const config = {
"agents/toolkits/aws_sfn": "agents/toolkits/aws_sfn",
"agents/toolkits/base": "agents/toolkits/base",
"agents/toolkits/connery": "agents/toolkits/connery/index",
"agents/toolkits/stagehand": "agents/toolkits/stagehand",
// embeddings
"embeddings/alibaba_tongyi": "embeddings/alibaba_tongyi",
"embeddings/baidu_qianfan": "embeddings/baidu_qianfan",
Expand Down Expand Up @@ -336,6 +337,7 @@ export const config = {
"tools/gmail",
"tools/google_calendar",
"agents/toolkits/aws_sfn",
"agents/toolkits/stagehand",
"callbacks/handlers/llmonitor",
"callbacks/handlers/lunary",
"callbacks/handlers/upstash_ratelimit",
Expand Down
6 changes: 6 additions & 0 deletions libs/langchain-community/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"author": "LangChain",
"license": "MIT",
"dependencies": {
"@langchain/langgraph": "^0.2.22",
"@langchain/openai": ">=0.2.0 <0.4.0",
"binary-extensions": "^2.2.0",
"expr-eval": "^2.0.2",
Expand Down Expand Up @@ -62,6 +63,7 @@
"@azure/search-documents": "^12.0.0",
"@azure/storage-blob": "^12.15.0",
"@browserbasehq/sdk": "^1.1.5",
"@browserbasehq/stagehand": "^1.0.0",
"@clickhouse/client": "^0.2.5",
"@cloudflare/ai": "1.0.12",
"@cloudflare/workers-types": "^4.20230922.0",
Expand Down Expand Up @@ -92,6 +94,7 @@
"@notionhq/client": "^2.2.10",
"@opensearch-project/opensearch": "^2.2.0",
"@planetscale/database": "^1.8.0",
"@playwright/test": "^1.48.2",
"@premai/prem-sdk": "^0.3.25",
"@qdrant/js-client-rest": "^1.8.2",
"@raycast/api": "^1.83.1",
Expand Down Expand Up @@ -190,6 +193,7 @@
"node-llama-cpp": "3.1.1",
"notion-to-md": "^3.1.0",
"officeparser": "^4.0.4",
"openai": "^4.73.0",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need this for stagehand extract tool

"pdf-parse": "1.1.1",
"pg": "^8.11.0",
"pg-copy-streams": "^6.0.5",
Expand Down Expand Up @@ -231,6 +235,7 @@
"@azure/search-documents": "^12.0.0",
"@azure/storage-blob": "^12.15.0",
"@browserbasehq/sdk": "*",
"@browserbasehq/stagehand": "^1.0.0",
"@clickhouse/client": "^0.2.5",
"@cloudflare/ai": "*",
"@datastax/astra-db-ts": "^1.0.0",
Expand Down Expand Up @@ -319,6 +324,7 @@
"neo4j-driver": "*",
"notion-to-md": "^3.1.0",
"officeparser": "^4.0.4",
"openai": "*",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need this for stagehand extract tool

"pdf-parse": "1.1.1",
"pg": "^8.11.0",
"pg-copy-streams": "^6.0.5",
Expand Down
Loading
Loading