agentic-browser 2.0.1 → 2.2.0
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/README.md +7 -3
- package/dist/cli/index.mjs +16 -25
- package/dist/index.mjs +2 -3
- package/dist/mcp/index.mjs +56 -15
- package/dist/{runtime-DUSoQl5x.mjs → runtime-CRkUsvhV.mjs} +1190 -326
- package/dist/{setup-COK-KCfv.mjs → setup-BP0YyerC.mjs} +1 -3
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -113,7 +113,7 @@ agentic-browser agent start --user-agent "MyBot/1.0"
|
|
|
113
113
|
agentic-browser agent status
|
|
114
114
|
agentic-browser agent navigate https://example.com
|
|
115
115
|
agentic-browser agent click "#login"
|
|
116
|
-
agentic-browser agent content --mode
|
|
116
|
+
agentic-browser agent content --mode summary
|
|
117
117
|
agentic-browser agent content --mode html --selector main
|
|
118
118
|
agentic-browser agent elements
|
|
119
119
|
agentic-browser agent elements --roles button,link --limit 20
|
|
@@ -132,7 +132,7 @@ agentic-browser agent elements --roles button,link,input --visible-only --limit
|
|
|
132
132
|
agentic-browser agent elements --selector "#main-content"
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
Returns a JSON array of elements with
|
|
135
|
+
Returns a JSON array of elements with selectors and fallback selectors usable in the typed agent commands like `agent click`, `agent type`, and `agent select`:
|
|
136
136
|
|
|
137
137
|
```json
|
|
138
138
|
{
|
|
@@ -154,6 +154,10 @@ Returns a JSON array of elements with CSS selectors and fallback selectors usabl
|
|
|
154
154
|
|
|
155
155
|
MCP responses are compact — `visible`, `actions`, and `tagName` are omitted to reduce token usage, and `enabled` is omitted when it is `true`. Responses also include a `summary` block with `countsByRole` and `primaryActions` so an LLM can identify the main controls faster. The full element shape is available via the programmatic API.
|
|
156
156
|
|
|
157
|
+
When an element lives inside an open shadow root or a same-origin iframe, discovery returns a composed locator using `>>>` to cross boundaries, for example `iframe[name="checkout"] >>> button[aria-label="Pay"]`. The same locator string works with `agent click`, `agent type`, MCP `browser_interact`, and fallback selectors.
|
|
158
|
+
|
|
159
|
+
`agent content` and MCP `browser_get_content` now default to `summary`, which returns a low-token overview with `title`, `headings`, `landmarks`, `primaryActions`, `inputs`, `alerts`, and iframe metadata. Use `a11y` when you need the deeper accessibility structure, and `text` or `html` only when you need raw content.
|
|
160
|
+
|
|
157
161
|
````
|
|
158
162
|
|
|
159
163
|
## MCP Server
|
|
@@ -223,8 +227,8 @@ More `interact` actions:
|
|
|
223
227
|
### 4. Read Page Content
|
|
224
228
|
|
|
225
229
|
```bash
|
|
230
|
+
agentic-browser page:content <sessionId> --mode summary
|
|
226
231
|
agentic-browser page:content <sessionId> --mode title
|
|
227
|
-
agentic-browser page:content <sessionId> --mode text
|
|
228
232
|
agentic-browser page:content <sessionId> --mode html --selector main
|
|
229
233
|
```
|
|
230
234
|
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { r as createCliRuntime } from "../runtime-
|
|
2
|
+
import { r as createCliRuntime } from "../runtime-CRkUsvhV.mjs";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import crypto from "node:crypto";
|
|
6
6
|
import { Command } from "commander";
|
|
7
|
-
|
|
8
7
|
//#region src/cli/commands/agent.ts
|
|
9
8
|
const STATE_FILE_NAME = "agent-state.json";
|
|
10
9
|
function stateFilePath(runtime) {
|
|
@@ -152,7 +151,8 @@ async function agentContent(runtime, input) {
|
|
|
152
151
|
action: "content",
|
|
153
152
|
...await runtime.api.getContent(sessionId, {
|
|
154
153
|
mode: input.mode,
|
|
155
|
-
selector: input.selector
|
|
154
|
+
selector: input.selector,
|
|
155
|
+
maxChars: input.maxChars
|
|
156
156
|
})
|
|
157
157
|
};
|
|
158
158
|
}
|
|
@@ -184,7 +184,6 @@ async function agentCleanup(runtime, input) {
|
|
|
184
184
|
...runtime.api.cleanupSessions(input)
|
|
185
185
|
};
|
|
186
186
|
}
|
|
187
|
-
|
|
188
187
|
//#endregion
|
|
189
188
|
//#region src/cli/output/result-formatter.ts
|
|
190
189
|
function formatResult(resultStatus, message) {
|
|
@@ -193,7 +192,6 @@ function formatResult(resultStatus, message) {
|
|
|
193
192
|
message
|
|
194
193
|
};
|
|
195
194
|
}
|
|
196
|
-
|
|
197
195
|
//#endregion
|
|
198
196
|
//#region src/cli/commands/session-start.ts
|
|
199
197
|
async function runSessionStart(runtime, input) {
|
|
@@ -203,32 +201,27 @@ async function runSessionStart(runtime, input) {
|
|
|
203
201
|
sessionId: session.sessionId
|
|
204
202
|
};
|
|
205
203
|
}
|
|
206
|
-
|
|
207
204
|
//#endregion
|
|
208
205
|
//#region src/cli/commands/session-status.ts
|
|
209
206
|
async function runSessionStatus(runtime, input) {
|
|
210
207
|
return runtime.api.getSession(input.sessionId);
|
|
211
208
|
}
|
|
212
|
-
|
|
213
209
|
//#endregion
|
|
214
210
|
//#region src/cli/commands/session-stop.ts
|
|
215
211
|
async function runSessionStop(runtime, input) {
|
|
216
212
|
await runtime.api.terminateSession(input.sessionId);
|
|
217
213
|
return { terminated: true };
|
|
218
214
|
}
|
|
219
|
-
|
|
220
215
|
//#endregion
|
|
221
216
|
//#region src/cli/commands/session-cleanup.ts
|
|
222
217
|
async function runSessionCleanup(runtime, input) {
|
|
223
218
|
return runtime.api.cleanupSessions(input);
|
|
224
219
|
}
|
|
225
|
-
|
|
226
220
|
//#endregion
|
|
227
221
|
//#region src/cli/commands/session-restart.ts
|
|
228
222
|
async function runSessionRestart(runtime, input) {
|
|
229
223
|
return await runtime.api.restartSession(input.sessionId);
|
|
230
224
|
}
|
|
231
|
-
|
|
232
225
|
//#endregion
|
|
233
226
|
//#region src/cli/commands/session-auth.ts
|
|
234
227
|
async function runSessionAuth(runtime, input) {
|
|
@@ -238,7 +231,6 @@ async function runSessionAuth(runtime, input) {
|
|
|
238
231
|
valid: runtime.context.tokenService.validate(input.sessionId, token)
|
|
239
232
|
};
|
|
240
233
|
}
|
|
241
|
-
|
|
242
234
|
//#endregion
|
|
243
235
|
//#region src/cli/commands/command-run.ts
|
|
244
236
|
async function runCommand(runtime, input) {
|
|
@@ -253,43 +245,38 @@ async function runCommand(runtime, input) {
|
|
|
253
245
|
throw new Error(`Command rejected: ${error.message}`);
|
|
254
246
|
}
|
|
255
247
|
}
|
|
256
|
-
|
|
257
248
|
//#endregion
|
|
258
249
|
//#region src/cli/commands/page-content.ts
|
|
259
250
|
async function runPageContent(runtime, input) {
|
|
260
251
|
return await runtime.api.getContent(input.sessionId, {
|
|
261
252
|
mode: input.mode,
|
|
262
|
-
selector: input.selector
|
|
253
|
+
selector: input.selector,
|
|
254
|
+
maxChars: input.maxChars
|
|
263
255
|
});
|
|
264
256
|
}
|
|
265
|
-
|
|
266
257
|
//#endregion
|
|
267
258
|
//#region src/cli/commands/memory-search.ts
|
|
268
259
|
async function runMemorySearch(runtime, input) {
|
|
269
260
|
if (!input.taskIntent || !input.taskIntent.trim()) throw new Error("taskIntent is required");
|
|
270
261
|
return runtime.api.searchMemory(input);
|
|
271
262
|
}
|
|
272
|
-
|
|
273
263
|
//#endregion
|
|
274
264
|
//#region src/cli/commands/memory-inspect.ts
|
|
275
265
|
async function runMemoryInspect(runtime, input) {
|
|
276
266
|
if (!input.insightId || !input.insightId.trim()) throw new Error("insightId is required");
|
|
277
267
|
return runtime.api.inspectMemory(input.insightId);
|
|
278
268
|
}
|
|
279
|
-
|
|
280
269
|
//#endregion
|
|
281
270
|
//#region src/cli/commands/memory-verify.ts
|
|
282
271
|
async function runMemoryVerify(runtime, input) {
|
|
283
272
|
if (!input.insightId || !input.insightId.trim()) throw new Error("insightId is required");
|
|
284
273
|
return runtime.api.verifyMemory(input.insightId);
|
|
285
274
|
}
|
|
286
|
-
|
|
287
275
|
//#endregion
|
|
288
276
|
//#region src/cli/commands/memory-stats.ts
|
|
289
277
|
async function runMemoryStats(runtime) {
|
|
290
278
|
return runtime.api.memoryStats();
|
|
291
279
|
}
|
|
292
|
-
|
|
293
280
|
//#endregion
|
|
294
281
|
//#region src/cli/index.ts
|
|
295
282
|
async function main() {
|
|
@@ -337,11 +324,12 @@ async function main() {
|
|
|
337
324
|
});
|
|
338
325
|
console.log(JSON.stringify(result));
|
|
339
326
|
});
|
|
340
|
-
program.command("page:content").argument("<sessionId>").option("--mode <mode>", "title|text|html|a11y", "
|
|
327
|
+
program.command("page:content").argument("<sessionId>").option("--mode <mode>", "title|text|html|a11y|summary", "summary").option("--selector <selector>", "optional CSS selector").option("--max-chars <n>", "max characters for text/html/a11y modes").action(async (sessionId, options) => {
|
|
341
328
|
const result = await runPageContent(runtime, {
|
|
342
329
|
sessionId,
|
|
343
330
|
mode: options.mode,
|
|
344
|
-
selector: options.selector
|
|
331
|
+
selector: options.selector,
|
|
332
|
+
maxChars: options.maxChars ? Number.parseInt(options.maxChars, 10) : void 0
|
|
345
333
|
});
|
|
346
334
|
console.log(JSON.stringify(result));
|
|
347
335
|
});
|
|
@@ -485,8 +473,12 @@ async function main() {
|
|
|
485
473
|
const result = await agentTerminate(runtime);
|
|
486
474
|
console.log(JSON.stringify(result));
|
|
487
475
|
});
|
|
488
|
-
agent.command("content").option("--mode <mode>", "title|text|html|a11y", "
|
|
489
|
-
const result = await agentContent(runtime,
|
|
476
|
+
agent.command("content").option("--mode <mode>", "title|text|html|a11y|summary", "summary").option("--selector <selector>", "optional CSS selector").option("--max-chars <n>", "max characters for text/html/a11y modes").action(async (options) => {
|
|
477
|
+
const result = await agentContent(runtime, {
|
|
478
|
+
mode: options.mode,
|
|
479
|
+
selector: options.selector,
|
|
480
|
+
maxChars: options.maxChars ? Number.parseInt(options.maxChars, 10) : void 0
|
|
481
|
+
});
|
|
490
482
|
console.log(JSON.stringify(result));
|
|
491
483
|
});
|
|
492
484
|
agent.command("elements").description("List interactive elements on the current page").option("--roles <roles>", "comma-separated roles filter", (v) => v.split(",")).option("--visible-only", "only visible elements", true).option("--no-visible-only", "include hidden elements").option("--limit <n>", "max elements", "50").option("--selector <selector>", "scope to CSS selector subtree").action(async (options) => {
|
|
@@ -520,7 +512,7 @@ async function main() {
|
|
|
520
512
|
await startMcpServer();
|
|
521
513
|
});
|
|
522
514
|
program.command("setup").description("Configure agentic-browser as MCP server for your AI tool").action(async () => {
|
|
523
|
-
const { runSetup } = await import("../setup-
|
|
515
|
+
const { runSetup } = await import("../setup-BP0YyerC.mjs");
|
|
524
516
|
await runSetup();
|
|
525
517
|
});
|
|
526
518
|
await program.parseAsync(process.argv);
|
|
@@ -533,6 +525,5 @@ main().then((keepAlive) => {
|
|
|
533
525
|
console.error(JSON.stringify({ error: message }));
|
|
534
526
|
process.exit(1);
|
|
535
527
|
});
|
|
536
|
-
|
|
537
528
|
//#endregion
|
|
538
|
-
export {
|
|
529
|
+
export {};
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as createMockAgenticBrowserCore, n as createAgenticBrowserCore, t as AgenticBrowserCore } from "./runtime-
|
|
3
|
-
|
|
4
|
-
export { AgenticBrowserCore, createAgenticBrowserCore, createMockAgenticBrowserCore };
|
|
2
|
+
import { i as createMockAgenticBrowserCore, n as createAgenticBrowserCore, t as AgenticBrowserCore } from "./runtime-CRkUsvhV.mjs";
|
|
3
|
+
export { AgenticBrowserCore, createAgenticBrowserCore, createMockAgenticBrowserCore };
|
package/dist/mcp/index.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as createAgenticBrowserCore } from "../runtime-
|
|
2
|
+
import { n as createAgenticBrowserCore } from "../runtime-CRkUsvhV.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
-
|
|
7
6
|
//#region src/mcp/response-helpers.ts
|
|
8
7
|
function uniqueLines(content, maxLineLength = 160) {
|
|
9
8
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -23,10 +22,27 @@ function truncateContent(content, limit) {
|
|
|
23
22
|
};
|
|
24
23
|
const originalLength = content.length;
|
|
25
24
|
return {
|
|
26
|
-
content: content.slice(0, limit) + `\n\n[Truncated
|
|
25
|
+
content: content.slice(0, limit) + `\n\n[Truncated - showing first ${limit} of ${originalLength} characters. Use a CSS selector to scope the content, or use mode="summary" for a lower-token overview.]`,
|
|
27
26
|
truncated: true
|
|
28
27
|
};
|
|
29
28
|
}
|
|
29
|
+
function resolveCompactedContent(result, limit) {
|
|
30
|
+
if (result.truncated) return {
|
|
31
|
+
content: result.content,
|
|
32
|
+
truncated: true
|
|
33
|
+
};
|
|
34
|
+
return truncateContent(result.content, limit);
|
|
35
|
+
}
|
|
36
|
+
function parseStructuredSummary(result) {
|
|
37
|
+
if (result.structuredContent) return result.structuredContent;
|
|
38
|
+
if (!result.content) return;
|
|
39
|
+
try {
|
|
40
|
+
const parsed = JSON.parse(result.content);
|
|
41
|
+
return parsed && typeof parsed === "object" ? parsed : void 0;
|
|
42
|
+
} catch {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
30
46
|
function summarizeTextContent(content) {
|
|
31
47
|
const lines = uniqueLines(content);
|
|
32
48
|
return {
|
|
@@ -69,9 +85,23 @@ function compactPageContent(result, maxChars) {
|
|
|
69
85
|
text: 8e3,
|
|
70
86
|
a11y: 1e4,
|
|
71
87
|
html: 4e3,
|
|
72
|
-
title: void 0
|
|
88
|
+
title: void 0,
|
|
89
|
+
summary: void 0
|
|
73
90
|
}[result.mode];
|
|
74
|
-
|
|
91
|
+
if (result.mode === "summary") {
|
|
92
|
+
const structured = parseStructuredSummary(result);
|
|
93
|
+
if (structured) return {
|
|
94
|
+
mode: "summary",
|
|
95
|
+
...structured,
|
|
96
|
+
truncated: false
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
mode: "summary",
|
|
100
|
+
content: result.content,
|
|
101
|
+
truncated: false
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const truncated = resolveCompactedContent(result, limit);
|
|
75
105
|
if (result.mode === "title") return {
|
|
76
106
|
...result,
|
|
77
107
|
truncated: false
|
|
@@ -82,6 +112,7 @@ function compactPageContent(result, maxChars) {
|
|
|
82
112
|
mode: result.mode,
|
|
83
113
|
content: truncated.content,
|
|
84
114
|
truncated: truncated.truncated,
|
|
115
|
+
originalLength: result.originalLength,
|
|
85
116
|
summaryLines: summary.summaryLines,
|
|
86
117
|
previewLines: summary.previewLines
|
|
87
118
|
};
|
|
@@ -92,6 +123,7 @@ function compactPageContent(result, maxChars) {
|
|
|
92
123
|
mode: result.mode,
|
|
93
124
|
content: truncated.content,
|
|
94
125
|
truncated: truncated.truncated,
|
|
126
|
+
originalLength: result.originalLength,
|
|
95
127
|
headings: summary.headings,
|
|
96
128
|
landmarks: summary.landmarks,
|
|
97
129
|
actions: summary.actions,
|
|
@@ -102,7 +134,8 @@ function compactPageContent(result, maxChars) {
|
|
|
102
134
|
return {
|
|
103
135
|
mode: result.mode,
|
|
104
136
|
content: truncated.content,
|
|
105
|
-
truncated: truncated.truncated
|
|
137
|
+
truncated: truncated.truncated,
|
|
138
|
+
originalLength: result.originalLength
|
|
106
139
|
};
|
|
107
140
|
}
|
|
108
141
|
function summarizeElements(elements) {
|
|
@@ -156,11 +189,17 @@ function compactMemoryResults(results) {
|
|
|
156
189
|
return compact;
|
|
157
190
|
}) };
|
|
158
191
|
}
|
|
159
|
-
|
|
160
192
|
//#endregion
|
|
161
193
|
//#region src/mcp/index.ts
|
|
162
194
|
let core;
|
|
163
195
|
let activeSessionId;
|
|
196
|
+
const DEFAULT_MCP_MAX_CHARS = {
|
|
197
|
+
summary: void 0,
|
|
198
|
+
title: void 0,
|
|
199
|
+
text: 8e3,
|
|
200
|
+
a11y: 1e4,
|
|
201
|
+
html: 4e3
|
|
202
|
+
};
|
|
164
203
|
function getCore() {
|
|
165
204
|
if (!core) core = createAgenticBrowserCore();
|
|
166
205
|
return core;
|
|
@@ -267,26 +306,29 @@ server.tool("browser_interact", "Interact with a page element or perform browser
|
|
|
267
306
|
text: JSON.stringify(compact)
|
|
268
307
|
}] };
|
|
269
308
|
});
|
|
270
|
-
server.tool("browser_get_content", "Get the current page content. Modes: \"text\" (readable text), \"a11y\" (accessibility tree
|
|
309
|
+
server.tool("browser_get_content", "Get the current page content. Modes: \"summary\" (recommended low-token overview with headings, actions, inputs, alerts, and iframe awareness), \"text\" (readable text), \"a11y\" (accessibility tree for deeper structure), \"title\" (page title only), \"html\" (raw HTML). A session is auto-started if needed.", {
|
|
271
310
|
mode: z.enum([
|
|
272
311
|
"title",
|
|
273
312
|
"text",
|
|
274
313
|
"html",
|
|
275
|
-
"a11y"
|
|
276
|
-
|
|
314
|
+
"a11y",
|
|
315
|
+
"summary"
|
|
316
|
+
]).default("summary").describe("Content extraction mode"),
|
|
277
317
|
selector: z.string().optional().describe("CSS selector to scope content (e.g. \"main\", \"#content\")"),
|
|
278
|
-
maxChars: z.number().optional().describe("Maximum characters to return (default:
|
|
318
|
+
maxChars: z.number().optional().describe("Maximum characters to return (default: 8000 for text, 10000 for a11y, 4000 for html, ignored for summary/title). Use a CSS selector to scope content instead of raising this limit."),
|
|
279
319
|
sessionId: z.string().optional().describe("Session ID (auto-resolved if omitted)")
|
|
280
320
|
}, async ({ mode, selector, maxChars, sessionId }) => {
|
|
281
321
|
const sid = await resolveSession(sessionId);
|
|
322
|
+
const effectiveMaxChars = maxChars ?? DEFAULT_MCP_MAX_CHARS[mode];
|
|
282
323
|
const result = await getCore().getPageContent({
|
|
283
324
|
sessionId: sid,
|
|
284
325
|
mode,
|
|
285
|
-
selector
|
|
326
|
+
selector,
|
|
327
|
+
maxChars: effectiveMaxChars
|
|
286
328
|
});
|
|
287
329
|
return { content: [{
|
|
288
330
|
type: "text",
|
|
289
|
-
text: JSON.stringify(compactPageContent(result
|
|
331
|
+
text: JSON.stringify(compactPageContent(result))
|
|
290
332
|
}] };
|
|
291
333
|
});
|
|
292
334
|
server.tool("browser_get_elements", "Discover all interactive elements on the current page (buttons, links, inputs, etc.). Returns CSS selectors and fallbackSelectors you can use with browser_interact. Pass fallbackSelectors to browser_interact for automatic retry when the primary selector breaks. Actions are derived from role: link/button/custom→click, input/textarea/contenteditable→click+type+press, select→click+select, checkbox/radio→toggle. A session is auto-started if needed.", {
|
|
@@ -379,6 +421,5 @@ async function main() {
|
|
|
379
421
|
};
|
|
380
422
|
await server.connect(transport);
|
|
381
423
|
}
|
|
382
|
-
|
|
383
424
|
//#endregion
|
|
384
|
-
export { main };
|
|
425
|
+
export { main };
|