@meetopenbot/stagehand 1.0.3 → 1.0.5
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.js +70 -9
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { defineAgentPlugin } from "@meetopenbot/plugin-sdk";
|
|
|
3
3
|
|
|
4
4
|
// src/agent.ts
|
|
5
5
|
import { Stagehand } from "@browserbasehq/stagehand";
|
|
6
|
+
import { textReply as textReply2 } from "@meetopenbot/plugin-sdk";
|
|
6
7
|
|
|
7
8
|
// src/config.ts
|
|
8
9
|
import {
|
|
@@ -30,14 +31,70 @@ function resolveStagehandConfig(config) {
|
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
// src/stream.ts
|
|
35
|
+
import {
|
|
36
|
+
createTextReplyBuffer,
|
|
37
|
+
textReply
|
|
38
|
+
} from "@meetopenbot/plugin-sdk";
|
|
39
|
+
var classifyStagehandPart = (part) => {
|
|
40
|
+
if (part.type === "text-delta") {
|
|
41
|
+
const text = part.text ?? part.delta ?? "";
|
|
42
|
+
return text ? { type: "delta", text } : { type: "skip" };
|
|
43
|
+
}
|
|
44
|
+
if (part.type === "tool-call" && part.toolCallId) {
|
|
45
|
+
return {
|
|
46
|
+
type: "tool_call",
|
|
47
|
+
id: part.toolCallId,
|
|
48
|
+
name: part.toolName ?? "tool",
|
|
49
|
+
input: part.input
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if ((part.type === "tool-result" || part.type === "tool-error") && part.toolCallId) {
|
|
53
|
+
return {
|
|
54
|
+
type: "tool_result",
|
|
55
|
+
id: part.toolCallId,
|
|
56
|
+
name: part.toolName,
|
|
57
|
+
input: part.input,
|
|
58
|
+
output: part.type === "tool-error" ? part.error : part.output,
|
|
59
|
+
error: part.type === "tool-error"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (part.type === "step-finish" || part.type === "finish") {
|
|
63
|
+
return { type: "flush" };
|
|
64
|
+
}
|
|
65
|
+
return { type: "skip" };
|
|
66
|
+
};
|
|
67
|
+
async function* runStagehandStream(fullStream) {
|
|
68
|
+
const replies = createTextReplyBuffer({ groupId: "stagehand:tools" });
|
|
69
|
+
for await (const part of fullStream) {
|
|
70
|
+
yield* replies.apply(classifyStagehandPart(part));
|
|
71
|
+
}
|
|
72
|
+
yield* replies.end();
|
|
73
|
+
}
|
|
74
|
+
function finalStagehandReply(args) {
|
|
75
|
+
const items = [];
|
|
76
|
+
if (!args.yielded && args.message?.trim()) items.push(textReply(args.message.trim()));
|
|
77
|
+
if (args.output && typeof args.output === "object" && Object.keys(args.output).length > 0) {
|
|
78
|
+
items.push(textReply(JSON.stringify(args.output, null, 2)));
|
|
79
|
+
}
|
|
80
|
+
return items;
|
|
81
|
+
}
|
|
82
|
+
|
|
33
83
|
// src/agent.ts
|
|
34
|
-
async function runStagehandTurn({
|
|
84
|
+
async function* runStagehandTurn({
|
|
85
|
+
prompt,
|
|
86
|
+
context
|
|
87
|
+
}) {
|
|
35
88
|
const config = resolveStagehandConfig(context.config);
|
|
36
89
|
if (config.requestedEnv === "BROWSERBASE" && (!config.browserbaseApiKey || !config.browserbaseProjectId)) {
|
|
37
|
-
|
|
90
|
+
yield textReply2(
|
|
91
|
+
"Stagehand Browserbase setup is incomplete. Set `BROWSERBASE_API_KEY` and `BROWSERBASE_PROJECT_ID` in workspace settings."
|
|
92
|
+
);
|
|
93
|
+
return;
|
|
38
94
|
}
|
|
39
95
|
if (config.requestedEnv === "LOCAL" && !config.apiKey) {
|
|
40
|
-
|
|
96
|
+
yield textReply2("Stagehand local setup is incomplete. Set `OPENAI_API_KEY` in workspace settings.");
|
|
97
|
+
return;
|
|
41
98
|
}
|
|
42
99
|
let stagehand = null;
|
|
43
100
|
try {
|
|
@@ -58,15 +115,19 @@ async function runStagehandTurn({ prompt, context }) {
|
|
|
58
115
|
instruction: prompt,
|
|
59
116
|
maxSteps: config.maxSteps
|
|
60
117
|
});
|
|
61
|
-
|
|
118
|
+
let yielded = false;
|
|
119
|
+
for await (const item of runStagehandStream(streamResult.fullStream)) {
|
|
120
|
+
yielded = true;
|
|
121
|
+
yield item;
|
|
62
122
|
}
|
|
63
123
|
const result = await streamResult.result;
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
124
|
+
for (const item of finalStagehandReply({
|
|
125
|
+
yielded,
|
|
126
|
+
message: result.message,
|
|
127
|
+
output: result.output
|
|
128
|
+
})) {
|
|
129
|
+
yield item;
|
|
68
130
|
}
|
|
69
|
-
return parts.join("\n\n");
|
|
70
131
|
} finally {
|
|
71
132
|
if (stagehand) await stagehand.close().catch(() => {
|
|
72
133
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meetopenbot/stagehand",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Stagehand AI browser automation plugin for OpenBot",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@browserbasehq/stagehand": "^3.3.0",
|
|
25
25
|
"playwright": "^1.52.0",
|
|
26
26
|
"zod": "^4.3.5",
|
|
27
|
-
"@meetopenbot/plugin-sdk": "^0.
|
|
27
|
+
"@meetopenbot/plugin-sdk": "^0.5.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node": "^20.10.1",
|