@poncho-ai/browser 0.6.3 → 0.6.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/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +26 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +67 -25
- package/package.json +2 -2
- package/src/session.ts +60 -3
- package/src/tools.ts +23 -24
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/browser@0.6.
|
|
2
|
+
> @poncho-ai/browser@0.6.5 build /home/runner/work/poncho-ai/poncho-ai/packages/browser
|
|
3
3
|
> tsup src/index.ts --format esm --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
[34mCLI[39m tsup v8.5.1
|
|
8
8
|
[34mCLI[39m Target: es2022
|
|
9
9
|
[34mESM[39m Build start
|
|
10
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
11
|
-
[32mESM[39m ⚡️ Build success in
|
|
10
|
+
[32mESM[39m [1mdist/index.js [22m[32m45.97 KB[39m
|
|
11
|
+
[32mESM[39m ⚡️ Build success in 73ms
|
|
12
12
|
[34mDTS[39m Build start
|
|
13
|
-
[32mDTS[39m ⚡️ Build success in
|
|
14
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m13.
|
|
13
|
+
[32mDTS[39m ⚡️ Build success in 4746ms
|
|
14
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m13.69 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @poncho-ai/browser
|
|
2
2
|
|
|
3
|
+
## 0.6.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#42](https://github.com/cesr/poncho-ai/pull/42) [`e58a984`](https://github.com/cesr/poncho-ai/commit/e58a984efaa673b649318102bbf735fb4c2f9172) Thanks [@cesr](https://github.com/cesr)! - Add continuation model and fire-and-forget subagents
|
|
8
|
+
|
|
9
|
+
**Continuation model**: Agents no longer send a synthetic `"Continue"` user message between steps. Instead, the harness injects a transient signal when needed, and the full internal message chain is preserved across continuations so the LLM never loses context. `RunInput` gains `disableSoftDeadline` and `RunResult` gains `continuationMessages`.
|
|
10
|
+
|
|
11
|
+
**Fire-and-forget subagents**: Subagents now run asynchronously in the background. `spawn_subagent` returns immediately with a subagent ID; results are delivered back to the parent conversation as a callback once the subagent completes. Subagents cannot spawn their own subagents. The web UI shows results in a collapsible disclosure and reconnects the live event stream automatically when the parent agent resumes.
|
|
12
|
+
|
|
13
|
+
**Bug fixes**:
|
|
14
|
+
- Fixed a race condition where concurrent runs on the same harness instance could assign a subagent or browser tab to the wrong parent conversation (shared `_currentRunConversationId` field replaced with per-run `ToolContext.conversationId`).
|
|
15
|
+
- Fixed Upstash KV store silently dropping large values by switching from URL-path encoding to request body format for `SET`/`SETEX` commands.
|
|
16
|
+
- Fixed empty assistant content blocks causing Anthropic `text content blocks must be non-empty` errors.
|
|
17
|
+
|
|
18
|
+
**Client**: Added `getConversationStatus()` and `waitForSubagents` option on `sendMessage()`.
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [[`e58a984`](https://github.com/cesr/poncho-ai/commit/e58a984efaa673b649318102bbf735fb4c2f9172)]:
|
|
21
|
+
- @poncho-ai/sdk@1.6.0
|
|
22
|
+
|
|
23
|
+
## 0.6.4
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- [`b5af10a`](https://github.com/cesr/poncho-ai/commit/b5af10a2f7b0023c683f14cd465105f8ddfff0ee) Thanks [@cesr](https://github.com/cesr)! - Fix browser cookie restore failing with "Invalid parameters" by sanitizing Playwright-format cookies to CDP-compatible format before calling Network.setCookies. Falls back to per-cookie restore when batch call fails.
|
|
28
|
+
|
|
3
29
|
## 0.6.3
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -166,7 +166,7 @@ declare class BrowserSession {
|
|
|
166
166
|
private emitStatus;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
declare function createBrowserTools(getSession: () => BrowserSession
|
|
169
|
+
declare function createBrowserTools(getSession: () => BrowserSession): ToolDefinition[];
|
|
170
170
|
|
|
171
171
|
/**
|
|
172
172
|
* Returns a realistic Chrome user-agent string for the host OS.
|
package/dist/index.js
CHANGED
|
@@ -186,6 +186,24 @@ async function getBrowserManagerCtor() {
|
|
|
186
186
|
return BrowserManagerCtor;
|
|
187
187
|
}
|
|
188
188
|
var MAX_TABS = 8;
|
|
189
|
+
var VALID_SAME_SITE = ["Strict", "Lax", "None"];
|
|
190
|
+
function sanitizeCookieForCDP(c) {
|
|
191
|
+
const name = typeof c.name === "string" ? c.name : "";
|
|
192
|
+
const value = typeof c.value === "string" ? c.value : "";
|
|
193
|
+
if (!name) return null;
|
|
194
|
+
const out = { name, value };
|
|
195
|
+
if (typeof c.domain === "string" && c.domain) out.domain = c.domain;
|
|
196
|
+
if (typeof c.path === "string") out.path = c.path;
|
|
197
|
+
if (typeof c.secure === "boolean") out.secure = c.secure;
|
|
198
|
+
if (typeof c.httpOnly === "boolean") out.httpOnly = c.httpOnly;
|
|
199
|
+
if (typeof c.expires === "number" && c.expires > 0) {
|
|
200
|
+
out.expires = c.expires;
|
|
201
|
+
}
|
|
202
|
+
if (typeof c.sameSite === "string" && VALID_SAME_SITE.includes(c.sameSite)) {
|
|
203
|
+
out.sameSite = c.sameSite;
|
|
204
|
+
}
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
189
207
|
var SAME_TAB_INIT_SCRIPT = `
|
|
190
208
|
(() => {
|
|
191
209
|
// Override window.open to navigate in-place
|
|
@@ -836,6 +854,10 @@ var BrowserSession = class {
|
|
|
836
854
|
tab.frameListeners.add(listener);
|
|
837
855
|
return () => {
|
|
838
856
|
tab.frameListeners.delete(listener);
|
|
857
|
+
if (tab.frameListeners.size === 0 && this._screencastConversation === conversationId) {
|
|
858
|
+
this.stopScreencast().catch(() => {
|
|
859
|
+
});
|
|
860
|
+
}
|
|
839
861
|
};
|
|
840
862
|
}
|
|
841
863
|
onStatus(conversationId, listener) {
|
|
@@ -941,8 +963,28 @@ var BrowserSession = class {
|
|
|
941
963
|
if (!json) return;
|
|
942
964
|
const state = JSON.parse(json);
|
|
943
965
|
if (state.cookies?.length) {
|
|
944
|
-
|
|
945
|
-
|
|
966
|
+
const sanitized = state.cookies.map(sanitizeCookieForCDP).filter((c) => c !== null);
|
|
967
|
+
if (sanitized.length) {
|
|
968
|
+
try {
|
|
969
|
+
await cdp.send("Network.setCookies", { cookies: sanitized });
|
|
970
|
+
} catch {
|
|
971
|
+
let restored = 0;
|
|
972
|
+
for (const cookie of sanitized) {
|
|
973
|
+
try {
|
|
974
|
+
await cdp.send("Network.setCookies", { cookies: [cookie] });
|
|
975
|
+
restored++;
|
|
976
|
+
} catch {
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
if (restored > 0) {
|
|
980
|
+
console.log(`[poncho][browser] Restored ${restored}/${sanitized.length} cookies (batch failed, fell back to individual)`);
|
|
981
|
+
} else {
|
|
982
|
+
console.warn("[poncho][browser] Could not restore any cookies");
|
|
983
|
+
}
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
console.log(`[poncho][browser] Restored ${sanitized.length} cookies`);
|
|
987
|
+
}
|
|
946
988
|
}
|
|
947
989
|
if (state.origins?.length) {
|
|
948
990
|
const entries = {};
|
|
@@ -1033,7 +1075,7 @@ var BrowserSession = class {
|
|
|
1033
1075
|
};
|
|
1034
1076
|
|
|
1035
1077
|
// src/tools.ts
|
|
1036
|
-
function createBrowserTools(getSession
|
|
1078
|
+
function createBrowserTools(getSession) {
|
|
1037
1079
|
return [
|
|
1038
1080
|
{
|
|
1039
1081
|
name: "browser_open",
|
|
@@ -1048,9 +1090,9 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1048
1090
|
},
|
|
1049
1091
|
required: ["url"]
|
|
1050
1092
|
},
|
|
1051
|
-
handler: async (input) => {
|
|
1093
|
+
handler: async (input, context) => {
|
|
1052
1094
|
const session = getSession();
|
|
1053
|
-
const cid =
|
|
1095
|
+
const cid = context.conversationId ?? "__default__";
|
|
1054
1096
|
const url = String(input.url ?? "");
|
|
1055
1097
|
if (!url) throw new Error("url is required");
|
|
1056
1098
|
const result = await session.open(cid, url);
|
|
@@ -1067,9 +1109,9 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1067
1109
|
type: "object",
|
|
1068
1110
|
properties: {}
|
|
1069
1111
|
},
|
|
1070
|
-
handler: async () => {
|
|
1112
|
+
handler: async (_input, context) => {
|
|
1071
1113
|
const session = getSession();
|
|
1072
|
-
const snapshot = await session.snapshot(
|
|
1114
|
+
const snapshot = await session.snapshot(context.conversationId ?? "__default__");
|
|
1073
1115
|
return { snapshot };
|
|
1074
1116
|
}
|
|
1075
1117
|
},
|
|
@@ -1086,11 +1128,11 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1086
1128
|
},
|
|
1087
1129
|
required: ["ref"]
|
|
1088
1130
|
},
|
|
1089
|
-
handler: async (input) => {
|
|
1131
|
+
handler: async (input, context) => {
|
|
1090
1132
|
const session = getSession();
|
|
1091
1133
|
const ref = String(input.ref ?? "");
|
|
1092
1134
|
if (!ref) throw new Error("ref is required");
|
|
1093
|
-
await session.click(
|
|
1135
|
+
await session.click(context.conversationId ?? "__default__", ref);
|
|
1094
1136
|
return { clicked: ref };
|
|
1095
1137
|
}
|
|
1096
1138
|
},
|
|
@@ -1111,12 +1153,12 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1111
1153
|
},
|
|
1112
1154
|
required: ["text"]
|
|
1113
1155
|
},
|
|
1114
|
-
handler: async (input) => {
|
|
1156
|
+
handler: async (input, context) => {
|
|
1115
1157
|
const session = getSession();
|
|
1116
1158
|
const text = String(input.text ?? "");
|
|
1117
1159
|
if (!text) throw new Error("text is required");
|
|
1118
1160
|
const exact = input.exact === true;
|
|
1119
|
-
await session.clickText(
|
|
1161
|
+
await session.clickText(context.conversationId ?? "__default__", text, exact);
|
|
1120
1162
|
return { clicked: text, exact };
|
|
1121
1163
|
}
|
|
1122
1164
|
},
|
|
@@ -1133,11 +1175,11 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1133
1175
|
},
|
|
1134
1176
|
required: ["script"]
|
|
1135
1177
|
},
|
|
1136
|
-
handler: async (input) => {
|
|
1178
|
+
handler: async (input, context) => {
|
|
1137
1179
|
const session = getSession();
|
|
1138
1180
|
const script = String(input.script ?? "");
|
|
1139
1181
|
if (!script) throw new Error("script is required");
|
|
1140
|
-
const result = await session.executeJs(
|
|
1182
|
+
const result = await session.executeJs(context.conversationId ?? "__default__", script);
|
|
1141
1183
|
return { result: result ?? null };
|
|
1142
1184
|
}
|
|
1143
1185
|
},
|
|
@@ -1158,12 +1200,12 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1158
1200
|
},
|
|
1159
1201
|
required: ["ref", "text"]
|
|
1160
1202
|
},
|
|
1161
|
-
handler: async (input) => {
|
|
1203
|
+
handler: async (input, context) => {
|
|
1162
1204
|
const session = getSession();
|
|
1163
1205
|
const ref = String(input.ref ?? "");
|
|
1164
1206
|
const text = String(input.text ?? "");
|
|
1165
1207
|
if (!ref) throw new Error("ref is required");
|
|
1166
|
-
await session.type(
|
|
1208
|
+
await session.type(context.conversationId ?? "__default__", ref, text);
|
|
1167
1209
|
return { typed: text, into: ref };
|
|
1168
1210
|
}
|
|
1169
1211
|
},
|
|
@@ -1174,9 +1216,9 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1174
1216
|
type: "object",
|
|
1175
1217
|
properties: {}
|
|
1176
1218
|
},
|
|
1177
|
-
handler: async () => {
|
|
1219
|
+
handler: async (_input, context) => {
|
|
1178
1220
|
const session = getSession();
|
|
1179
|
-
const result = await session.content(
|
|
1221
|
+
const result = await session.content(context.conversationId ?? "__default__");
|
|
1180
1222
|
return { url: result.url, title: result.title, text: result.text };
|
|
1181
1223
|
}
|
|
1182
1224
|
},
|
|
@@ -1187,9 +1229,9 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1187
1229
|
type: "object",
|
|
1188
1230
|
properties: {}
|
|
1189
1231
|
},
|
|
1190
|
-
handler: async () => {
|
|
1232
|
+
handler: async (_input, context) => {
|
|
1191
1233
|
const session = getSession();
|
|
1192
|
-
const base64 = await session.screenshot(
|
|
1234
|
+
const base64 = await session.screenshot(context.conversationId ?? "__default__");
|
|
1193
1235
|
const filePart = {
|
|
1194
1236
|
type: "file",
|
|
1195
1237
|
data: base64,
|
|
@@ -1217,11 +1259,11 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1217
1259
|
},
|
|
1218
1260
|
required: ["direction"]
|
|
1219
1261
|
},
|
|
1220
|
-
handler: async (input) => {
|
|
1262
|
+
handler: async (input, context) => {
|
|
1221
1263
|
const session = getSession();
|
|
1222
1264
|
const direction = String(input.direction ?? "down");
|
|
1223
1265
|
const amount = typeof input.amount === "number" ? input.amount : void 0;
|
|
1224
|
-
await session.scroll(
|
|
1266
|
+
await session.scroll(context.conversationId ?? "__default__", direction, amount);
|
|
1225
1267
|
return { scrolled: direction, amount: amount ?? "viewport" };
|
|
1226
1268
|
}
|
|
1227
1269
|
},
|
|
@@ -1237,10 +1279,10 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1237
1279
|
}
|
|
1238
1280
|
}
|
|
1239
1281
|
},
|
|
1240
|
-
handler: async (input) => {
|
|
1282
|
+
handler: async (input, context) => {
|
|
1241
1283
|
const session = getSession();
|
|
1242
1284
|
const url = input.url ? String(input.url) : void 0;
|
|
1243
|
-
const { cleared } = await session.clearCookies(
|
|
1285
|
+
const { cleared } = await session.clearCookies(context.conversationId ?? "__default__", url);
|
|
1244
1286
|
return { cleared, scope: url ?? "all" };
|
|
1245
1287
|
}
|
|
1246
1288
|
},
|
|
@@ -1251,9 +1293,9 @@ function createBrowserTools(getSession, getConversationId) {
|
|
|
1251
1293
|
type: "object",
|
|
1252
1294
|
properties: {}
|
|
1253
1295
|
},
|
|
1254
|
-
handler: async () => {
|
|
1296
|
+
handler: async (_input, context) => {
|
|
1255
1297
|
const session = getSession();
|
|
1256
|
-
await session.closeTab(
|
|
1298
|
+
await session.closeTab(context.conversationId ?? "__default__");
|
|
1257
1299
|
return { closed: true };
|
|
1258
1300
|
}
|
|
1259
1301
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poncho-ai/browser",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "Browser automation for Poncho agents, powered by agent-browser",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"agent-browser": "^0.15.1",
|
|
24
|
-
"@poncho-ai/sdk": "1.
|
|
24
|
+
"@poncho-ai/sdk": "1.6.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tsup": "^8.0.0",
|
package/src/session.ts
CHANGED
|
@@ -62,6 +62,37 @@ async function getBrowserManagerCtor(): Promise<new () => BrowserManagerInstance
|
|
|
62
62
|
|
|
63
63
|
const MAX_TABS = 8;
|
|
64
64
|
|
|
65
|
+
const VALID_SAME_SITE = ["Strict", "Lax", "None"];
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Map a Playwright-format cookie to a CDP-compatible CookieParam, stripping
|
|
69
|
+
* unknown fields and fixing values that newer Chrome versions reject.
|
|
70
|
+
*/
|
|
71
|
+
function sanitizeCookieForCDP(c: Record<string, unknown>): Record<string, unknown> | null {
|
|
72
|
+
const name = typeof c.name === "string" ? c.name : "";
|
|
73
|
+
const value = typeof c.value === "string" ? c.value : "";
|
|
74
|
+
if (!name) return null;
|
|
75
|
+
|
|
76
|
+
const out: Record<string, unknown> = { name, value };
|
|
77
|
+
|
|
78
|
+
if (typeof c.domain === "string" && c.domain) out.domain = c.domain;
|
|
79
|
+
if (typeof c.path === "string") out.path = c.path;
|
|
80
|
+
if (typeof c.secure === "boolean") out.secure = c.secure;
|
|
81
|
+
if (typeof c.httpOnly === "boolean") out.httpOnly = c.httpOnly;
|
|
82
|
+
|
|
83
|
+
// Playwright uses -1 for session cookies; CDP expects the field to be
|
|
84
|
+
// absent for session cookies.
|
|
85
|
+
if (typeof c.expires === "number" && c.expires > 0) {
|
|
86
|
+
out.expires = c.expires;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (typeof c.sameSite === "string" && VALID_SAME_SITE.includes(c.sameSite)) {
|
|
90
|
+
out.sameSite = c.sameSite;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
|
|
65
96
|
/**
|
|
66
97
|
* Init script that forces new-tab navigations (window.open, target="_blank")
|
|
67
98
|
* to open in the current tab. Runs before page scripts on every navigation.
|
|
@@ -779,7 +810,12 @@ export class BrowserSession {
|
|
|
779
810
|
this.tabs.set(conversationId, tab);
|
|
780
811
|
}
|
|
781
812
|
tab.frameListeners.add(listener);
|
|
782
|
-
return () => {
|
|
813
|
+
return () => {
|
|
814
|
+
tab!.frameListeners.delete(listener);
|
|
815
|
+
if (tab!.frameListeners.size === 0 && this._screencastConversation === conversationId) {
|
|
816
|
+
this.stopScreencast().catch(() => {});
|
|
817
|
+
}
|
|
818
|
+
};
|
|
783
819
|
}
|
|
784
820
|
|
|
785
821
|
onStatus(conversationId: string, listener: StatusListener): () => void {
|
|
@@ -896,8 +932,29 @@ export class BrowserSession {
|
|
|
896
932
|
origins?: Array<{ origin: string; localStorage: Array<{ name: string; value: string }> }>;
|
|
897
933
|
};
|
|
898
934
|
if (state.cookies?.length) {
|
|
899
|
-
|
|
900
|
-
|
|
935
|
+
const sanitized = state.cookies
|
|
936
|
+
.map(sanitizeCookieForCDP)
|
|
937
|
+
.filter((c): c is Record<string, unknown> => c !== null);
|
|
938
|
+
if (sanitized.length) {
|
|
939
|
+
try {
|
|
940
|
+
await cdp.send("Network.setCookies", { cookies: sanitized });
|
|
941
|
+
} catch {
|
|
942
|
+
let restored = 0;
|
|
943
|
+
for (const cookie of sanitized) {
|
|
944
|
+
try {
|
|
945
|
+
await cdp.send("Network.setCookies", { cookies: [cookie] });
|
|
946
|
+
restored++;
|
|
947
|
+
} catch { /* skip this cookie */ }
|
|
948
|
+
}
|
|
949
|
+
if (restored > 0) {
|
|
950
|
+
console.log(`[poncho][browser] Restored ${restored}/${sanitized.length} cookies (batch failed, fell back to individual)`);
|
|
951
|
+
} else {
|
|
952
|
+
console.warn("[poncho][browser] Could not restore any cookies");
|
|
953
|
+
}
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
console.log(`[poncho][browser] Restored ${sanitized.length} cookies`);
|
|
957
|
+
}
|
|
901
958
|
}
|
|
902
959
|
if (state.origins?.length) {
|
|
903
960
|
const entries: Record<string, Array<{ name: string; value: string }>> = {};
|
package/src/tools.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type { ToolDefinition, FileContentPart } from "@poncho-ai/sdk";
|
|
1
|
+
import type { ToolContext, ToolDefinition, FileContentPart } from "@poncho-ai/sdk";
|
|
2
2
|
import type { BrowserSession } from "./session.js";
|
|
3
3
|
|
|
4
4
|
type BrowserToolInput = Record<string, unknown>;
|
|
5
5
|
|
|
6
6
|
export function createBrowserTools(
|
|
7
7
|
getSession: () => BrowserSession,
|
|
8
|
-
getConversationId: () => string,
|
|
9
8
|
): ToolDefinition[] {
|
|
10
9
|
return [
|
|
11
10
|
{
|
|
@@ -22,9 +21,9 @@ export function createBrowserTools(
|
|
|
22
21
|
},
|
|
23
22
|
required: ["url"],
|
|
24
23
|
},
|
|
25
|
-
handler: async (input: BrowserToolInput) => {
|
|
24
|
+
handler: async (input: BrowserToolInput, context: ToolContext) => {
|
|
26
25
|
const session = getSession();
|
|
27
|
-
const cid =
|
|
26
|
+
const cid = context.conversationId ?? "__default__";
|
|
28
27
|
const url = String(input.url ?? "");
|
|
29
28
|
if (!url) throw new Error("url is required");
|
|
30
29
|
const result = await session.open(cid, url);
|
|
@@ -44,9 +43,9 @@ export function createBrowserTools(
|
|
|
44
43
|
type: "object",
|
|
45
44
|
properties: {},
|
|
46
45
|
},
|
|
47
|
-
handler: async () => {
|
|
46
|
+
handler: async (_input: BrowserToolInput, context: ToolContext) => {
|
|
48
47
|
const session = getSession();
|
|
49
|
-
const snapshot = await session.snapshot(
|
|
48
|
+
const snapshot = await session.snapshot(context.conversationId ?? "__default__");
|
|
50
49
|
return { snapshot };
|
|
51
50
|
},
|
|
52
51
|
},
|
|
@@ -65,11 +64,11 @@ export function createBrowserTools(
|
|
|
65
64
|
},
|
|
66
65
|
required: ["ref"],
|
|
67
66
|
},
|
|
68
|
-
handler: async (input: BrowserToolInput) => {
|
|
67
|
+
handler: async (input: BrowserToolInput, context: ToolContext) => {
|
|
69
68
|
const session = getSession();
|
|
70
69
|
const ref = String(input.ref ?? "");
|
|
71
70
|
if (!ref) throw new Error("ref is required");
|
|
72
|
-
await session.click(
|
|
71
|
+
await session.click(context.conversationId ?? "__default__", ref);
|
|
73
72
|
return { clicked: ref };
|
|
74
73
|
},
|
|
75
74
|
},
|
|
@@ -94,12 +93,12 @@ export function createBrowserTools(
|
|
|
94
93
|
},
|
|
95
94
|
required: ["text"],
|
|
96
95
|
},
|
|
97
|
-
handler: async (input: BrowserToolInput) => {
|
|
96
|
+
handler: async (input: BrowserToolInput, context: ToolContext) => {
|
|
98
97
|
const session = getSession();
|
|
99
98
|
const text = String(input.text ?? "");
|
|
100
99
|
if (!text) throw new Error("text is required");
|
|
101
100
|
const exact = input.exact === true;
|
|
102
|
-
await session.clickText(
|
|
101
|
+
await session.clickText(context.conversationId ?? "__default__", text, exact);
|
|
103
102
|
return { clicked: text, exact };
|
|
104
103
|
},
|
|
105
104
|
},
|
|
@@ -121,11 +120,11 @@ export function createBrowserTools(
|
|
|
121
120
|
},
|
|
122
121
|
required: ["script"],
|
|
123
122
|
},
|
|
124
|
-
handler: async (input: BrowserToolInput) => {
|
|
123
|
+
handler: async (input: BrowserToolInput, context: ToolContext) => {
|
|
125
124
|
const session = getSession();
|
|
126
125
|
const script = String(input.script ?? "");
|
|
127
126
|
if (!script) throw new Error("script is required");
|
|
128
|
-
const result = await session.executeJs(
|
|
127
|
+
const result = await session.executeJs(context.conversationId ?? "__default__", script);
|
|
129
128
|
return { result: result ?? null };
|
|
130
129
|
},
|
|
131
130
|
},
|
|
@@ -148,12 +147,12 @@ export function createBrowserTools(
|
|
|
148
147
|
},
|
|
149
148
|
required: ["ref", "text"],
|
|
150
149
|
},
|
|
151
|
-
handler: async (input: BrowserToolInput) => {
|
|
150
|
+
handler: async (input: BrowserToolInput, context: ToolContext) => {
|
|
152
151
|
const session = getSession();
|
|
153
152
|
const ref = String(input.ref ?? "");
|
|
154
153
|
const text = String(input.text ?? "");
|
|
155
154
|
if (!ref) throw new Error("ref is required");
|
|
156
|
-
await session.type(
|
|
155
|
+
await session.type(context.conversationId ?? "__default__", ref, text);
|
|
157
156
|
return { typed: text, into: ref };
|
|
158
157
|
},
|
|
159
158
|
},
|
|
@@ -167,9 +166,9 @@ export function createBrowserTools(
|
|
|
167
166
|
type: "object",
|
|
168
167
|
properties: {},
|
|
169
168
|
},
|
|
170
|
-
handler: async () => {
|
|
169
|
+
handler: async (_input: BrowserToolInput, context: ToolContext) => {
|
|
171
170
|
const session = getSession();
|
|
172
|
-
const result = await session.content(
|
|
171
|
+
const result = await session.content(context.conversationId ?? "__default__");
|
|
173
172
|
return { url: result.url, title: result.title, text: result.text };
|
|
174
173
|
},
|
|
175
174
|
},
|
|
@@ -182,9 +181,9 @@ export function createBrowserTools(
|
|
|
182
181
|
type: "object",
|
|
183
182
|
properties: {},
|
|
184
183
|
},
|
|
185
|
-
handler: async () => {
|
|
184
|
+
handler: async (_input: BrowserToolInput, context: ToolContext) => {
|
|
186
185
|
const session = getSession();
|
|
187
|
-
const base64 = await session.screenshot(
|
|
186
|
+
const base64 = await session.screenshot(context.conversationId ?? "__default__");
|
|
188
187
|
const filePart: FileContentPart = {
|
|
189
188
|
type: "file",
|
|
190
189
|
data: base64,
|
|
@@ -213,11 +212,11 @@ export function createBrowserTools(
|
|
|
213
212
|
},
|
|
214
213
|
required: ["direction"],
|
|
215
214
|
},
|
|
216
|
-
handler: async (input: BrowserToolInput) => {
|
|
215
|
+
handler: async (input: BrowserToolInput, context: ToolContext) => {
|
|
217
216
|
const session = getSession();
|
|
218
217
|
const direction = String(input.direction ?? "down") as "up" | "down";
|
|
219
218
|
const amount = typeof input.amount === "number" ? input.amount : undefined;
|
|
220
|
-
await session.scroll(
|
|
219
|
+
await session.scroll(context.conversationId ?? "__default__", direction, amount);
|
|
221
220
|
return { scrolled: direction, amount: amount ?? "viewport" };
|
|
222
221
|
},
|
|
223
222
|
},
|
|
@@ -238,10 +237,10 @@ export function createBrowserTools(
|
|
|
238
237
|
},
|
|
239
238
|
},
|
|
240
239
|
},
|
|
241
|
-
handler: async (input: BrowserToolInput) => {
|
|
240
|
+
handler: async (input: BrowserToolInput, context: ToolContext) => {
|
|
242
241
|
const session = getSession();
|
|
243
242
|
const url = input.url ? String(input.url) : undefined;
|
|
244
|
-
const { cleared } = await session.clearCookies(
|
|
243
|
+
const { cleared } = await session.clearCookies(context.conversationId ?? "__default__", url);
|
|
245
244
|
return { cleared, scope: url ?? "all" };
|
|
246
245
|
},
|
|
247
246
|
},
|
|
@@ -253,9 +252,9 @@ export function createBrowserTools(
|
|
|
253
252
|
type: "object",
|
|
254
253
|
properties: {},
|
|
255
254
|
},
|
|
256
|
-
handler: async () => {
|
|
255
|
+
handler: async (_input: BrowserToolInput, context: ToolContext) => {
|
|
257
256
|
const session = getSession();
|
|
258
|
-
await session.closeTab(
|
|
257
|
+
await session.closeTab(context.conversationId ?? "__default__");
|
|
259
258
|
return { closed: true };
|
|
260
259
|
},
|
|
261
260
|
},
|