Skip to content

Commit a4fac1b

Browse files
authored
feat(mcp-browser): readme and add userDataDir, wsEndpoint, userAgent (#610)
1 parent 4d8aae2 commit a4fac1b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1341
-266
lines changed

.changeset/angry-crews-agree.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.changeset/breezy-laws-cover.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/bright-bananas-float.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/dirty-students-behave.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/eighty-rules-shout.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/fuzzy-walls-report.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/lovely-readers-complain.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/ninety-ravens-bow.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.changeset/pre.json

Lines changed: 0 additions & 52 deletions
This file was deleted.

.changeset/rich-nails-hug.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/shaggy-grapes-poke.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/shy-pets-cover.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/silver-seals-grab.md

Lines changed: 0 additions & 9 deletions
This file was deleted.

.changeset/spotty-fireants-travel.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/tame-foxes-protect.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/tricky-apples-walk.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/agent-infra/browser-use/CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# @agent-infra/browser-use
22

3+
## 0.1.0
4+
5+
### Minor Changes
6+
7+
- feat(agent-tars): provider mcp servers
8+
9+
### Patch Changes
10+
11+
- 9089c63: feat: launchOptions add args
12+
- Updated dependencies [9089c63]
13+
- Updated dependencies
14+
- @agent-infra/browser@0.1.0
15+
- @agent-infra/shared@0.0.1
16+
317
## 0.0.2-beta.0
418

519
### Patch Changes

packages/agent-infra/browser-use/assets/buildDomTree.js

Lines changed: 94 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,56 @@ window.buildDomTree = (
2121
const { doHighlightElements, focusHighlightIndex, viewportExpansion } = args;
2222
let highlightIndex = 0; // Reset highlight index
2323

24-
// Quick check to confirm the script receives focusHighlightIndex
25-
console.log('focusHighlightIndex:', focusHighlightIndex);
24+
const DOM_CACHE = {
25+
boundingRects: new WeakMap(),
26+
clientRects: new WeakMap(),
27+
computedStyles: new WeakMap(),
28+
clearCache: () => {
29+
DOM_CACHE.boundingRects = new WeakMap();
30+
DOM_CACHE.clientRects = new WeakMap();
31+
DOM_CACHE.computedStyles = new WeakMap();
32+
},
33+
};
34+
35+
function getCachedBoundingRect(element) {
36+
if (!element) return null;
37+
if (DOM_CACHE.boundingRects.has(element)) {
38+
return DOM_CACHE.boundingRects.get(element);
39+
}
40+
const rect = element.getBoundingClientRect();
41+
if (rect) {
42+
DOM_CACHE.boundingRects.set(element, rect);
43+
}
44+
return rect;
45+
}
46+
47+
// Add a new function to get cached client rects
48+
function getCachedClientRects(element) {
49+
if (!element) return null;
50+
51+
if (DOM_CACHE.clientRects.has(element)) {
52+
return DOM_CACHE.clientRects.get(element);
53+
}
54+
55+
const rects = element.getClientRects();
56+
57+
if (rects) {
58+
DOM_CACHE.clientRects.set(element, rects);
59+
}
60+
return rects;
61+
}
62+
63+
function getCachedComputedStyle(element) {
64+
if (!element) return null;
65+
if (DOM_CACHE.computedStyles.has(element)) {
66+
return DOM_CACHE.computedStyles.get(element);
67+
}
68+
const style = getComputedStyle(element);
69+
if (style) {
70+
DOM_CACHE.computedStyles.set(element, style);
71+
}
72+
return style;
73+
}
2674

2775
function highlightElement(element, index, parentIframe = null) {
2876
// Create or get highlight container
@@ -69,13 +117,13 @@ window.buildDomTree = (
69117
overlay.style.boxSizing = 'border-box';
70118

71119
// Position overlay based on element, including scroll position
72-
const rect = element.getBoundingClientRect();
120+
const rect = getCachedBoundingRect(element);
73121
let top = rect.top + window.scrollY;
74122
let left = rect.left + window.scrollX;
75123

76124
// Adjust position if element is inside an iframe
77125
if (parentIframe) {
78-
const iframeRect = parentIframe.getBoundingClientRect();
126+
const iframeRect = getCachedBoundingRect(parentIframe);
79127
top += iframeRect.top;
80128
left += iframeRect.left;
81129
}
@@ -327,7 +375,7 @@ window.buildDomTree = (
327375
if (hasInteractiveRole) return true;
328376

329377
// Get computed style
330-
const style = window.getComputedStyle(element);
378+
const style = getCachedComputedStyle(element);
331379

332380
// Check if element has click-like styling
333381
// const hasClickStyling = style.cursor === 'pointer' ||
@@ -429,7 +477,7 @@ window.buildDomTree = (
429477

430478
// Helper function to check if element is visible
431479
function isElementVisible(element) {
432-
const style = window.getComputedStyle(element);
480+
const style = getCachedComputedStyle(element);
433481
return (
434482
element.offsetWidth > 0 &&
435483
element.offsetHeight > 0 &&
@@ -440,6 +488,42 @@ window.buildDomTree = (
440488

441489
// Helper function to check if element is the top element at its position
442490
function isTopElement(element) {
491+
// Special case: when viewportExpansion is -1, consider all elements as "top" elements
492+
if (viewportExpansion === -1) {
493+
return true;
494+
}
495+
496+
const rects = getCachedClientRects(element); // Replace element.getClientRects()
497+
498+
if (!rects || rects.length === 0) {
499+
return false; // No geometry, cannot be top
500+
}
501+
502+
let isAnyRectInViewport = false;
503+
for (const rect of rects) {
504+
// Use the same logic as isInExpandedViewport check
505+
if (
506+
rect.width > 0 &&
507+
rect.height > 0 &&
508+
!(
509+
// Only check non-empty rects
510+
(
511+
rect.bottom < -viewportExpansion ||
512+
rect.top > window.innerHeight + viewportExpansion ||
513+
rect.right < -viewportExpansion ||
514+
rect.left > window.innerWidth + viewportExpansion
515+
)
516+
)
517+
) {
518+
isAnyRectInViewport = true;
519+
break;
520+
}
521+
}
522+
523+
if (!isAnyRectInViewport) {
524+
return false; // All rects are outside the viewport area
525+
}
526+
443527
// Find the correct document context and root element
444528
let doc = element.ownerDocument;
445529

@@ -451,7 +535,7 @@ window.buildDomTree = (
451535
// For shadow DOM, we need to check within its own root context
452536
const shadowRoot = element.getRootNode();
453537
if (shadowRoot instanceof ShadowRoot) {
454-
const rect = element.getBoundingClientRect();
538+
const rect = getCachedBoundingRect(element);
455539
const point = {
456540
x: rect.left + rect.width / 2,
457541
y: rect.top + rect.height / 2,
@@ -475,7 +559,7 @@ window.buildDomTree = (
475559
}
476560

477561
// Regular DOM elements
478-
const rect = element.getBoundingClientRect();
562+
const rect = getCachedBoundingRect(element);
479563

480564
// If viewportExpansion is -1, check if element is the top one at its position
481565
if (viewportExpansion === -1) {
@@ -561,6 +645,8 @@ window.buildDomTree = (
561645

562646
// Function to traverse the DOM and create nested JSON
563647
function buildDomTree(node, parentIframe = null) {
648+
DOM_CACHE.clearCache();
649+
564650
if (!node) return null;
565651

566652
// Special case for text nodes

packages/agent-infra/browser-use/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@agent-infra/browser-use",
3-
"version": "0.0.2-beta.0",
3+
"version": "0.1.0",
44
"main": "dist/index.js",
55
"module": "dist/index.mjs",
66
"types": "dist/index.d.ts",

packages/agent-infra/browser/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# @agent-infra/browser
22

3+
## 0.1.0
4+
5+
### Minor Changes
6+
7+
- feat(agent-tars): provider mcp servers
8+
9+
### Patch Changes
10+
11+
- 9089c63: feat: launchOptions add args
12+
- @agent-infra/shared@0.0.1
13+
314
## 0.0.3-beta.0
415

516
### Patch Changes

packages/agent-infra/browser/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@agent-infra/browser",
33
"description": "A tiny Browser Control library, built for Agent Tars.",
4-
"version": "0.0.3-beta.0",
4+
"version": "0.1.0",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",
77
"types": "dist/index.d.ts",

packages/agent-infra/browser/src/local-browser.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ export class LocalBrowser extends BaseBrowser {
4040
// This parameter combined with `captureBeyondViewport: false`, will resolve the screenshot blinking issue.
4141
deviceScaleFactor: 0,
4242
},
43+
...(options.userDataDir && {
44+
userDataDir: options.userDataDir,
45+
}),
4346
args: [
4447
'--no-sandbox',
4548
'--mute-audio',

packages/agent-infra/browser/src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ export interface LaunchOptions {
7272
* Used to bypass the proxy server for specific domains
7373
*/
7474
proxyBypassList?: string;
75+
76+
/**
77+
* Path to a user data directory.
78+
* {@link https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/user_data_dir.md | see the Chromium docs}
79+
* for more info.
80+
*/
81+
userDataDir?: string;
7582
}
7683

7784
/**

0 commit comments

Comments
 (0)