@meetopenbot/stagehand 1.0.1 → 1.0.3
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/dist/index.d.ts +4 -0
- package/dist/index.js +75 -121
- package/package.json +16 -10
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
|
@@ -1,134 +1,88 @@
|
|
|
1
|
-
// index.ts
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { defineAgentPlugin } from "@meetopenbot/plugin-sdk";
|
|
3
|
+
|
|
4
|
+
// src/agent.ts
|
|
2
5
|
import { Stagehand } from "@browserbasehq/stagehand";
|
|
6
|
+
|
|
7
|
+
// src/config.ts
|
|
3
8
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
uiWidget
|
|
9
|
+
lookupSecret,
|
|
10
|
+
readConfigModel,
|
|
11
|
+
trimmedString
|
|
8
12
|
} from "@meetopenbot/plugin-sdk";
|
|
9
|
-
var
|
|
10
|
-
openai: { label: "OpenAI", envVar: "OPENAI_API_KEY", defaultModel: "openai/gpt-4o-mini" },
|
|
11
|
-
anthropic: { label: "Anthropic", envVar: "ANTHROPIC_API_KEY", defaultModel: "anthropic/claude-sonnet-4-5-20250929" },
|
|
12
|
-
google: { label: "Google Generative AI", envVar: "GOOGLE_GENERATIVE_AI_API_KEY", defaultModel: "google/gemini-2.5-flash" }
|
|
13
|
-
};
|
|
14
|
-
var configSchema = {
|
|
13
|
+
var pluginConfigSchema = {
|
|
15
14
|
type: "object",
|
|
16
15
|
properties: {
|
|
17
|
-
|
|
18
|
-
provider: { type: "string", enum: ["openai", "anthropic", "google"] },
|
|
19
|
-
model: { type: "string" },
|
|
20
|
-
env: { type: "string", enum: ["LOCAL", "BROWSERBASE"] },
|
|
21
|
-
browserbaseApiKey: { type: "string", format: "password" },
|
|
22
|
-
browserbaseProjectId: { type: "string" },
|
|
23
|
-
headless: { type: "boolean", default: true },
|
|
24
|
-
maxSteps: { type: "integer", default: 25 },
|
|
25
|
-
mode: { type: "string", enum: ["dom", "hybrid", "cua"] }
|
|
16
|
+
env: { type: "string", enum: ["LOCAL", "BROWSERBASE"], description: "Browser environment." }
|
|
26
17
|
}
|
|
27
18
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
let stagehand = null;
|
|
65
|
-
try {
|
|
66
|
-
yield agentOutput({ agentId: context.agentId, threadId, content: `Starting Stagehand (${requestedEnv.toLowerCase()})...` });
|
|
67
|
-
stagehand = new Stagehand({
|
|
68
|
-
env: requestedEnv,
|
|
69
|
-
model: apiKey ? { modelName: model, apiKey } : model,
|
|
70
|
-
apiKey: config.browserbaseApiKey ?? env.BROWSERBASE_API_KEY,
|
|
71
|
-
projectId: config.browserbaseProjectId ?? env.BROWSERBASE_PROJECT_ID,
|
|
72
|
-
localBrowserLaunchOptions: { headless: config.headless ?? true },
|
|
73
|
-
experimental: true
|
|
74
|
-
});
|
|
75
|
-
await stagehand.init();
|
|
76
|
-
const agent = stagehand.agent({
|
|
77
|
-
systemPrompt: context.agentDetails?.instructions ?? void 0,
|
|
78
|
-
mode: config.mode,
|
|
79
|
-
stream: true
|
|
80
|
-
});
|
|
81
|
-
const streamResult = await agent.execute({
|
|
82
|
-
instruction: content,
|
|
83
|
-
maxSteps: config.maxSteps ?? 25
|
|
84
|
-
});
|
|
85
|
-
for await (const part of streamResult.fullStream) {
|
|
86
|
-
if (part.type === "tool-call") {
|
|
87
|
-
yield agentOutput({
|
|
88
|
-
agentId: context.agentId,
|
|
89
|
-
threadId,
|
|
90
|
-
content: `
|
|
91
|
-
> [Tool Call] ${part.toolName}: ${JSON.stringify(part.input, null, 2)}
|
|
92
|
-
`
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
if (part.type === "tool-result") {
|
|
96
|
-
yield agentOutput({
|
|
97
|
-
agentId: context.agentId,
|
|
98
|
-
threadId,
|
|
99
|
-
content: `
|
|
100
|
-
> [Tool Result] ${part.toolName}: ${JSON.stringify(part.output, null, 2).slice(0, 800)}
|
|
101
|
-
`
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
const result = await streamResult.result;
|
|
106
|
-
if (result.message) yield agentOutput({ agentId: context.agentId, threadId, content: result.message });
|
|
107
|
-
if (result.output && Object.keys(result.output).length > 0) {
|
|
108
|
-
yield agentOutput({ agentId: context.agentId, threadId, content: "```json\n" + JSON.stringify(result.output, null, 2) + "\n```" });
|
|
109
|
-
}
|
|
110
|
-
} catch (error) {
|
|
111
|
-
yield agentOutput({ agentId: context.agentId, threadId, content: `Error: ${error.message}` });
|
|
112
|
-
} finally {
|
|
113
|
-
if (stagehand) await stagehand.close().catch(() => {
|
|
114
|
-
});
|
|
115
|
-
}
|
|
19
|
+
function resolveStagehandConfig(config) {
|
|
20
|
+
const browserbaseApiKey = lookupSecret({ envKeys: ["BROWSERBASE_API_KEY"] });
|
|
21
|
+
const requestedEnv = trimmedString(config.env) || (browserbaseApiKey ? "BROWSERBASE" : "LOCAL");
|
|
22
|
+
return {
|
|
23
|
+
requestedEnv,
|
|
24
|
+
model: readConfigModel(config, "openai/gpt-4o-mini"),
|
|
25
|
+
apiKey: lookupSecret({ envKeys: ["OPENAI_API_KEY"] }),
|
|
26
|
+
browserbaseApiKey,
|
|
27
|
+
browserbaseProjectId: lookupSecret({ envKeys: ["BROWSERBASE_PROJECT_ID"] }),
|
|
28
|
+
headless: true,
|
|
29
|
+
maxSteps: 25
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/agent.ts
|
|
34
|
+
async function runStagehandTurn({ prompt, context }) {
|
|
35
|
+
const config = resolveStagehandConfig(context.config);
|
|
36
|
+
if (config.requestedEnv === "BROWSERBASE" && (!config.browserbaseApiKey || !config.browserbaseProjectId)) {
|
|
37
|
+
return "Stagehand Browserbase setup is incomplete. Set `BROWSERBASE_API_KEY` and `BROWSERBASE_PROJECT_ID` in workspace settings.";
|
|
38
|
+
}
|
|
39
|
+
if (config.requestedEnv === "LOCAL" && !config.apiKey) {
|
|
40
|
+
return "Stagehand local setup is incomplete. Set `OPENAI_API_KEY` in workspace settings.";
|
|
41
|
+
}
|
|
42
|
+
let stagehand = null;
|
|
43
|
+
try {
|
|
44
|
+
stagehand = new Stagehand({
|
|
45
|
+
env: config.requestedEnv,
|
|
46
|
+
model: config.apiKey ? { modelName: config.model, apiKey: config.apiKey } : config.model,
|
|
47
|
+
apiKey: config.browserbaseApiKey,
|
|
48
|
+
projectId: config.browserbaseProjectId,
|
|
49
|
+
localBrowserLaunchOptions: { headless: config.headless },
|
|
50
|
+
experimental: true
|
|
116
51
|
});
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
52
|
+
await stagehand.init();
|
|
53
|
+
const agent = stagehand.agent({
|
|
54
|
+
systemPrompt: context.agentDetails?.instructions ?? void 0,
|
|
55
|
+
stream: true
|
|
56
|
+
});
|
|
57
|
+
const streamResult = await agent.execute({
|
|
58
|
+
instruction: prompt,
|
|
59
|
+
maxSteps: config.maxSteps
|
|
60
|
+
});
|
|
61
|
+
for await (const _part of streamResult.fullStream) {
|
|
62
|
+
}
|
|
63
|
+
const result = await streamResult.result;
|
|
64
|
+
const parts = [];
|
|
65
|
+
if (result.message) parts.push(result.message);
|
|
66
|
+
if (result.output && Object.keys(result.output).length > 0) {
|
|
67
|
+
parts.push(JSON.stringify(result.output, null, 2));
|
|
68
|
+
}
|
|
69
|
+
return parts.join("\n\n");
|
|
70
|
+
} finally {
|
|
71
|
+
if (stagehand) await stagehand.close().catch(() => {
|
|
128
72
|
});
|
|
129
73
|
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/index.ts
|
|
77
|
+
var plugin = await defineAgentPlugin({
|
|
78
|
+
name: "Stagehand",
|
|
79
|
+
description: "Stagehand AI browser automation",
|
|
80
|
+
models: { providers: ["openai"], default: "openai/gpt-4o-mini" },
|
|
81
|
+
configSchema: pluginConfigSchema,
|
|
82
|
+
run: runStagehandTurn
|
|
130
83
|
});
|
|
131
|
-
var
|
|
84
|
+
var src_default = plugin;
|
|
132
85
|
export {
|
|
133
|
-
|
|
86
|
+
src_default as default,
|
|
87
|
+
plugin
|
|
134
88
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meetopenbot/stagehand",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Stagehand AI browser automation plugin for OpenBot",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -8,27 +8,33 @@
|
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
10
10
|
"exports": {
|
|
11
|
-
".":
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
12
16
|
},
|
|
13
17
|
"files": [
|
|
14
18
|
"dist"
|
|
15
19
|
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build": "esbuild index.ts --bundle --platform=node --target=node18 --format=esm --packages=external --outfile=dist/index.js",
|
|
18
|
-
"postinstall": "playwright install chromium --with-deps || playwright install chromium || true",
|
|
19
|
-
"prepublishOnly": "npm run build"
|
|
20
|
-
},
|
|
21
20
|
"engines": {
|
|
22
21
|
"node": ">=18"
|
|
23
22
|
},
|
|
24
23
|
"dependencies": {
|
|
25
24
|
"@browserbasehq/stagehand": "^3.3.0",
|
|
26
|
-
"@meetopenbot/plugin-sdk": "^0.1.2",
|
|
27
25
|
"playwright": "^1.52.0",
|
|
28
|
-
"zod": "^4.3.5"
|
|
26
|
+
"zod": "^4.3.5",
|
|
27
|
+
"@meetopenbot/plugin-sdk": "^0.3.0"
|
|
29
28
|
},
|
|
30
29
|
"devDependencies": {
|
|
31
30
|
"@types/node": "^20.10.1",
|
|
32
31
|
"esbuild": "^0.21.0"
|
|
32
|
+
},
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "esbuild src/index.ts --bundle --platform=node --target=node18 --format=esm --packages=external --outfile=dist/index.js && node ../../scripts/write-plugin-declaration.mjs",
|
|
36
|
+
"setup:browser": "playwright install chromium",
|
|
37
|
+
"dev": "esbuild src/index.ts --bundle --platform=node --target=node18 --format=esm --packages=external --outfile=dist/index.js --watch",
|
|
38
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
33
39
|
}
|
|
34
|
-
}
|
|
40
|
+
}
|