@eko-ai/eko 3.1.0 → 3.1.2
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 +42 -16
- package/dist/agent/browser/browser_labels.d.ts +16 -1
- package/dist/agent/browser/browser_labels.d.ts.map +1 -1
- package/dist/agent/browser/build_dom_tree.d.ts.map +1 -1
- package/dist/agent/browser/utils.d.ts +21 -0
- package/dist/agent/browser/utils.d.ts.map +1 -1
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/index.cjs.js +281 -57
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +281 -57
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const config$1 = {
|
|
2
2
|
name: "Eko",
|
|
3
|
+
mode: "normal",
|
|
3
4
|
platform: "mac",
|
|
4
5
|
maxReactNum: 500,
|
|
5
6
|
maxTokens: 16000,
|
|
@@ -12,6 +13,7 @@ const config$1 = {
|
|
|
12
13
|
maxDialogueImgFileNum: 1,
|
|
13
14
|
toolResultMultimodal: true,
|
|
14
15
|
parallelToolCalls: true,
|
|
16
|
+
markImageMode: "dom",
|
|
15
17
|
expertMode: false,
|
|
16
18
|
expertModeTodoLoopNum: 10,
|
|
17
19
|
};
|
|
@@ -31937,7 +31939,7 @@ class Eko {
|
|
|
31937
31939
|
results.push(agent_results.join("\n\n"));
|
|
31938
31940
|
}
|
|
31939
31941
|
context.conversation.splice(0, context.conversation.length);
|
|
31940
|
-
if (config$1.expertMode &&
|
|
31942
|
+
if ((config$1.mode == "expert" || config$1.expertMode) &&
|
|
31941
31943
|
!workflow.modified &&
|
|
31942
31944
|
agentTree.nextAgent &&
|
|
31943
31945
|
lastAgent?.AgentContext &&
|
|
@@ -34184,12 +34186,12 @@ class Agent {
|
|
|
34184
34186
|
const finalResult = await this.handleCallResult(agentContext, messages, agentTools, results);
|
|
34185
34187
|
loopNum++;
|
|
34186
34188
|
if (!finalResult) {
|
|
34187
|
-
if (config$1.expertMode && loopNum % config$1.expertModeTodoLoopNum == 0) {
|
|
34189
|
+
if ((config$1.mode == "expert" || config$1.expertMode) && loopNum % config$1.expertModeTodoLoopNum == 0) {
|
|
34188
34190
|
await doTodoListManager(agentContext, rlm, messages, llm_tools);
|
|
34189
34191
|
}
|
|
34190
34192
|
continue;
|
|
34191
34193
|
}
|
|
34192
|
-
if (config$1.expertMode && checkNum == 0) {
|
|
34194
|
+
if ((config$1.mode == "expert" || config$1.expertMode) && checkNum == 0) {
|
|
34193
34195
|
checkNum++;
|
|
34194
34196
|
const { completionStatus } = await doTaskResultCheck(agentContext, rlm, messages, llm_tools);
|
|
34195
34197
|
if (completionStatus == "incomplete") {
|
|
@@ -35081,10 +35083,145 @@ function extract_page_content(max_url_length = 200, max_content_length = 50000)
|
|
|
35081
35083
|
result = result.replace(/\s*\n/g, "\n").replace(/\n+/g, "\n").trim();
|
|
35082
35084
|
if (result.length > max_content_length) {
|
|
35083
35085
|
// result = result.slice(0, max_content_length) + "...";
|
|
35084
|
-
result = Array.from(result).slice(0, max_content_length).join(
|
|
35086
|
+
result = Array.from(result).slice(0, max_content_length).join("") + "...";
|
|
35085
35087
|
}
|
|
35086
35088
|
return result;
|
|
35087
35089
|
}
|
|
35090
|
+
function mark_screenshot_highlight_elements(screenshot, area_map, client_rect) {
|
|
35091
|
+
return new Promise(async (resolve, reject) => {
|
|
35092
|
+
try {
|
|
35093
|
+
// Convert base64 to Blob
|
|
35094
|
+
const base64Data = screenshot.imageBase64;
|
|
35095
|
+
const binaryString = atob(base64Data);
|
|
35096
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
35097
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
35098
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
35099
|
+
}
|
|
35100
|
+
const blob = new Blob([bytes], { type: screenshot.imageType });
|
|
35101
|
+
const imageBitmap = await createImageBitmap(blob, {
|
|
35102
|
+
resizeQuality: "high",
|
|
35103
|
+
resizeWidth: client_rect.width,
|
|
35104
|
+
resizeHeight: client_rect.height,
|
|
35105
|
+
});
|
|
35106
|
+
const canvas = new OffscreenCanvas(imageBitmap.width, imageBitmap.height);
|
|
35107
|
+
const ctx = canvas.getContext("2d");
|
|
35108
|
+
if (!ctx) {
|
|
35109
|
+
reject(new Error("Failed to get canvas context"));
|
|
35110
|
+
return;
|
|
35111
|
+
}
|
|
35112
|
+
ctx.imageSmoothingEnabled = true;
|
|
35113
|
+
ctx.imageSmoothingQuality = "high";
|
|
35114
|
+
ctx.drawImage(imageBitmap, 0, 0);
|
|
35115
|
+
const sortedEntries = Object.entries(area_map)
|
|
35116
|
+
.filter(([id, area]) => area.width > 0 && area.height > 0)
|
|
35117
|
+
.sort((a, b) => {
|
|
35118
|
+
const areaA = a[1].width * a[1].height;
|
|
35119
|
+
const areaB = b[1].width * b[1].height;
|
|
35120
|
+
return areaA - areaB;
|
|
35121
|
+
});
|
|
35122
|
+
const colors = [
|
|
35123
|
+
"#FF0000",
|
|
35124
|
+
"#00FF00",
|
|
35125
|
+
"#0000FF",
|
|
35126
|
+
"#FFA500",
|
|
35127
|
+
"#800080",
|
|
35128
|
+
"#008080",
|
|
35129
|
+
"#FF69B4",
|
|
35130
|
+
"#4B0082",
|
|
35131
|
+
"#FF4500",
|
|
35132
|
+
"#2E8B57",
|
|
35133
|
+
"#DC143C",
|
|
35134
|
+
"#4682B4",
|
|
35135
|
+
];
|
|
35136
|
+
sortedEntries.forEach(([id, area], index) => {
|
|
35137
|
+
const color = colors[index % colors.length];
|
|
35138
|
+
// Draw a border
|
|
35139
|
+
ctx.strokeStyle = color;
|
|
35140
|
+
ctx.lineWidth = 2;
|
|
35141
|
+
ctx.strokeRect(area.x, area.y, area.width, area.height);
|
|
35142
|
+
// Draw ID tag background
|
|
35143
|
+
const fontSize = Math.min(12, Math.max(8, area.height / 2));
|
|
35144
|
+
ctx.font = `${fontSize}px sans-serif`;
|
|
35145
|
+
const textMetrics = ctx.measureText(id);
|
|
35146
|
+
const padding = 4;
|
|
35147
|
+
const labelWidth = textMetrics.width + padding * 2;
|
|
35148
|
+
const labelHeight = fontSize + padding * 2;
|
|
35149
|
+
// The tag position is in the upper right corner.
|
|
35150
|
+
const labelX = area.x + area.width - labelWidth;
|
|
35151
|
+
let labelY = area.y;
|
|
35152
|
+
// Adjust if box is too small
|
|
35153
|
+
if (area.width < labelWidth + 4 || area.height < labelHeight + 4) {
|
|
35154
|
+
// Position outside the box if it's too small
|
|
35155
|
+
labelY = area.y - labelHeight;
|
|
35156
|
+
}
|
|
35157
|
+
// Draw label background
|
|
35158
|
+
ctx.fillStyle = color;
|
|
35159
|
+
ctx.fillRect(labelX, labelY, labelWidth, labelHeight);
|
|
35160
|
+
// Draw ID text
|
|
35161
|
+
ctx.fillStyle = "#FFFFFF";
|
|
35162
|
+
ctx.textBaseline = "top";
|
|
35163
|
+
ctx.fillText(id, labelX + padding, labelY + padding);
|
|
35164
|
+
});
|
|
35165
|
+
// Convert OffscreenCanvas to Blob, then to base64
|
|
35166
|
+
const resultBlob = await canvas.convertToBlob({
|
|
35167
|
+
type: screenshot.imageType,
|
|
35168
|
+
});
|
|
35169
|
+
const reader = new FileReader();
|
|
35170
|
+
reader.onloadend = () => {
|
|
35171
|
+
const resultBase64 = reader.result;
|
|
35172
|
+
resolve(resultBase64);
|
|
35173
|
+
};
|
|
35174
|
+
reader.onerror = () => {
|
|
35175
|
+
reject(new Error("Failed to convert blob to base64"));
|
|
35176
|
+
};
|
|
35177
|
+
reader.readAsDataURL(resultBlob);
|
|
35178
|
+
}
|
|
35179
|
+
catch (error) {
|
|
35180
|
+
reject(error);
|
|
35181
|
+
}
|
|
35182
|
+
});
|
|
35183
|
+
}
|
|
35184
|
+
async function compress_image(imageBase64, imageType, compress, quality = 1) {
|
|
35185
|
+
const base64Data = imageBase64;
|
|
35186
|
+
const binaryString = atob(base64Data);
|
|
35187
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
35188
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
35189
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
35190
|
+
}
|
|
35191
|
+
const blob = new Blob([bytes], { type: imageType });
|
|
35192
|
+
const bitmap = await createImageBitmap(blob);
|
|
35193
|
+
const width = compress.scale
|
|
35194
|
+
? bitmap.width * compress.scale
|
|
35195
|
+
: compress.resizeWidth;
|
|
35196
|
+
const height = compress.scale
|
|
35197
|
+
? bitmap.height * compress.scale
|
|
35198
|
+
: compress.resizeHeight;
|
|
35199
|
+
if (bitmap.width == width && bitmap.height == height && quality == 1) {
|
|
35200
|
+
return {
|
|
35201
|
+
imageBase64: imageBase64,
|
|
35202
|
+
imageType: imageType,
|
|
35203
|
+
};
|
|
35204
|
+
}
|
|
35205
|
+
const canvas = new OffscreenCanvas(width, height);
|
|
35206
|
+
const ctx = canvas.getContext("2d");
|
|
35207
|
+
ctx.drawImage(bitmap, 0, 0, width, height);
|
|
35208
|
+
const resultBlob = await canvas.convertToBlob({
|
|
35209
|
+
type: "image/jpeg",
|
|
35210
|
+
quality: quality,
|
|
35211
|
+
});
|
|
35212
|
+
return new Promise((resolve) => {
|
|
35213
|
+
const reader = new FileReader();
|
|
35214
|
+
reader.onloadend = () => {
|
|
35215
|
+
let imageDataUrl = reader.result;
|
|
35216
|
+
let imageBase64 = imageDataUrl.substring(imageDataUrl.indexOf("base64,") + 7);
|
|
35217
|
+
resolve({
|
|
35218
|
+
imageBase64: imageBase64,
|
|
35219
|
+
imageType: "image/jpeg",
|
|
35220
|
+
});
|
|
35221
|
+
};
|
|
35222
|
+
reader.readAsDataURL(resultBlob);
|
|
35223
|
+
});
|
|
35224
|
+
}
|
|
35088
35225
|
|
|
35089
35226
|
const AGENT_NAME = "Browser";
|
|
35090
35227
|
class BaseBrowserAgent extends Agent {
|
|
@@ -35266,19 +35403,30 @@ function run_build_dom_tree() {
|
|
|
35266
35403
|
/**
|
|
35267
35404
|
* Get clickable elements on the page
|
|
35268
35405
|
*
|
|
35269
|
-
* @param {*}
|
|
35406
|
+
* @param {*} markHighlightElements Is mark highlighted
|
|
35270
35407
|
* @param {*} includeAttributes [attr_names...]
|
|
35271
|
-
* @returns { element_str, selector_map }
|
|
35408
|
+
* @returns { element_str, client_rect, selector_map, area_map }
|
|
35272
35409
|
*/
|
|
35273
|
-
function get_clickable_elements(
|
|
35410
|
+
function get_clickable_elements(markHighlightElements = true, includeAttributes) {
|
|
35274
35411
|
window.clickable_elements = {};
|
|
35275
35412
|
computedStyleCache = new WeakMap();
|
|
35276
35413
|
document.querySelectorAll("[eko-user-highlight-id]").forEach(ele => ele.removeAttribute("eko-user-highlight-id"));
|
|
35277
|
-
let page_tree = build_dom_tree(
|
|
35414
|
+
let page_tree = build_dom_tree(markHighlightElements);
|
|
35278
35415
|
let element_tree = parse_node(page_tree);
|
|
35279
|
-
let selector_map = create_selector_map(element_tree);
|
|
35280
35416
|
let element_str = clickable_elements_to_string(element_tree, includeAttributes);
|
|
35281
|
-
|
|
35417
|
+
let client_rect = {
|
|
35418
|
+
width: window.innerWidth || document.documentElement.clientWidth,
|
|
35419
|
+
height: window.innerHeight || document.documentElement.clientHeight,
|
|
35420
|
+
};
|
|
35421
|
+
if (markHighlightElements) {
|
|
35422
|
+
let selector_map = {};
|
|
35423
|
+
// selector_map = create_selector_map(element_tree);
|
|
35424
|
+
return { element_str, client_rect, selector_map };
|
|
35425
|
+
}
|
|
35426
|
+
else {
|
|
35427
|
+
let area_map = create_area_map(element_tree);
|
|
35428
|
+
return { element_str, client_rect, area_map };
|
|
35429
|
+
}
|
|
35282
35430
|
}
|
|
35283
35431
|
function get_highlight_element(highlightIndex) {
|
|
35284
35432
|
let element = document.querySelector(`[eko-user-highlight-id="eko-highlight-${highlightIndex}"]`);
|
|
@@ -35377,12 +35525,13 @@ function run_build_dom_tree() {
|
|
|
35377
35525
|
process_node(element_tree);
|
|
35378
35526
|
return formatted_text.join('\n');
|
|
35379
35527
|
}
|
|
35380
|
-
function
|
|
35381
|
-
let
|
|
35528
|
+
function create_area_map(element_tree) {
|
|
35529
|
+
let area_map = {};
|
|
35382
35530
|
function process_node(node) {
|
|
35383
35531
|
if (node.tagName) {
|
|
35384
35532
|
if (node.highlightIndex != null) {
|
|
35385
|
-
|
|
35533
|
+
const element = window.clickable_elements[node.highlightIndex];
|
|
35534
|
+
area_map[node.highlightIndex] = get_element_real_bounding_rect(element);
|
|
35386
35535
|
}
|
|
35387
35536
|
for (let i = 0; i < node.children.length; i++) {
|
|
35388
35537
|
process_node(node.children[i]);
|
|
@@ -35390,7 +35539,38 @@ function run_build_dom_tree() {
|
|
|
35390
35539
|
}
|
|
35391
35540
|
}
|
|
35392
35541
|
process_node(element_tree);
|
|
35393
|
-
return
|
|
35542
|
+
return area_map;
|
|
35543
|
+
}
|
|
35544
|
+
function get_element_real_bounding_rect(element) {
|
|
35545
|
+
if (!element || !(element instanceof Element)) {
|
|
35546
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
35547
|
+
}
|
|
35548
|
+
let rect = element.getBoundingClientRect();
|
|
35549
|
+
let x = rect.left;
|
|
35550
|
+
let y = rect.top;
|
|
35551
|
+
let width = rect.width;
|
|
35552
|
+
let height = rect.height;
|
|
35553
|
+
let win = element.ownerDocument.defaultView;
|
|
35554
|
+
let maxDepth = 10;
|
|
35555
|
+
let depth = 0;
|
|
35556
|
+
while (win && win !== win.parent && depth < maxDepth) {
|
|
35557
|
+
depth++;
|
|
35558
|
+
const frameElement = win.frameElement;
|
|
35559
|
+
if (!frameElement) {
|
|
35560
|
+
break;
|
|
35561
|
+
}
|
|
35562
|
+
const frameRect = frameElement.getBoundingClientRect();
|
|
35563
|
+
x += frameRect.left;
|
|
35564
|
+
y += frameRect.top;
|
|
35565
|
+
// Consider the border and padding of the iframe.
|
|
35566
|
+
const frameStyle = getCachedComputedStyle(frameElement);
|
|
35567
|
+
x += parseFloat(frameStyle.borderLeftWidth) || 0;
|
|
35568
|
+
y += parseFloat(frameStyle.borderTopWidth) || 0;
|
|
35569
|
+
x += parseFloat(frameStyle.paddingLeft) || 0;
|
|
35570
|
+
y += parseFloat(frameStyle.paddingTop) || 0;
|
|
35571
|
+
win = win.parent;
|
|
35572
|
+
}
|
|
35573
|
+
return { x, y, width, height };
|
|
35394
35574
|
}
|
|
35395
35575
|
function parse_node(node_data, parent) {
|
|
35396
35576
|
if (!node_data) {
|
|
@@ -35430,7 +35610,7 @@ function run_build_dom_tree() {
|
|
|
35430
35610
|
}
|
|
35431
35611
|
return element_node;
|
|
35432
35612
|
}
|
|
35433
|
-
function build_dom_tree(
|
|
35613
|
+
function build_dom_tree(markHighlightElements) {
|
|
35434
35614
|
let highlightIndex = 0; // Reset highlight index
|
|
35435
35615
|
function highlightElement(element, index, parentIframe = null) {
|
|
35436
35616
|
// Create or get highlight container
|
|
@@ -35630,13 +35810,10 @@ function run_build_dom_tree() {
|
|
|
35630
35810
|
interactiveRoles.has(ariaRole) ||
|
|
35631
35811
|
(tabIndex !== null && tabIndex !== '-1') ||
|
|
35632
35812
|
element.getAttribute('data-action') === 'a-dropdown-select' ||
|
|
35633
|
-
element.getAttribute('data-action') === 'a-dropdown-button'
|
|
35813
|
+
element.getAttribute('data-action') === 'a-dropdown-button' ||
|
|
35814
|
+
element.getAttribute('contenteditable') === 'true';
|
|
35634
35815
|
if (hasInteractiveRole)
|
|
35635
35816
|
return true;
|
|
35636
|
-
// Get computed style
|
|
35637
|
-
const style = getCachedComputedStyle(element);
|
|
35638
|
-
// Check if element has click-like styling
|
|
35639
|
-
const hasClickStyling = style.cursor === 'pointer' || element.style.cursor === 'pointer';
|
|
35640
35817
|
// Check for event listeners
|
|
35641
35818
|
const hasClickHandler = element.onclick !== null ||
|
|
35642
35819
|
element.getAttribute('onclick') !== null ||
|
|
@@ -35644,10 +35821,13 @@ function run_build_dom_tree() {
|
|
|
35644
35821
|
element.hasAttribute('@click') ||
|
|
35645
35822
|
element.hasAttribute('v-on:click');
|
|
35646
35823
|
// Helper function to safely get event listeners
|
|
35647
|
-
function
|
|
35648
|
-
|
|
35649
|
-
|
|
35650
|
-
|
|
35824
|
+
function getElementEventListeners(el) {
|
|
35825
|
+
if (window.getEventListeners) {
|
|
35826
|
+
const listeners = window.getEventListeners?.(el);
|
|
35827
|
+
if (listeners) {
|
|
35828
|
+
return listeners;
|
|
35829
|
+
}
|
|
35830
|
+
}
|
|
35651
35831
|
// List of common event types to check
|
|
35652
35832
|
const listeners = {};
|
|
35653
35833
|
const eventTypes = [
|
|
@@ -35675,7 +35855,7 @@ function run_build_dom_tree() {
|
|
|
35675
35855
|
return listeners;
|
|
35676
35856
|
}
|
|
35677
35857
|
// Check for click-related events on the element itself
|
|
35678
|
-
const listeners =
|
|
35858
|
+
const listeners = getElementEventListeners(element);
|
|
35679
35859
|
const hasClickListeners = listeners &&
|
|
35680
35860
|
(listeners.click?.length > 0 ||
|
|
35681
35861
|
listeners.mousedown?.length > 0 ||
|
|
@@ -35687,18 +35867,27 @@ function run_build_dom_tree() {
|
|
|
35687
35867
|
element.hasAttribute('aria-pressed') ||
|
|
35688
35868
|
element.hasAttribute('aria-selected') ||
|
|
35689
35869
|
element.hasAttribute('aria-checked');
|
|
35690
|
-
// Check for form-related functionality
|
|
35691
|
-
element.form !== undefined ||
|
|
35692
|
-
element.hasAttribute('contenteditable') ||
|
|
35693
|
-
(style && style.userSelect !== 'none');
|
|
35694
35870
|
// Check if element is draggable
|
|
35695
35871
|
const isDraggable = element.draggable || element.getAttribute('draggable') === 'true';
|
|
35696
|
-
|
|
35697
|
-
|
|
35698
|
-
|
|
35699
|
-
|
|
35700
|
-
|
|
35701
|
-
|
|
35872
|
+
if (hasAriaProps || hasClickHandler || hasClickListeners || isDraggable) {
|
|
35873
|
+
return true;
|
|
35874
|
+
}
|
|
35875
|
+
// Check if element has click-like styling
|
|
35876
|
+
let hasClickStyling = element.style.cursor === 'pointer' || getCachedComputedStyle(element).cursor === 'pointer';
|
|
35877
|
+
if (hasClickStyling) {
|
|
35878
|
+
let count = 0;
|
|
35879
|
+
let current = element.parentElement;
|
|
35880
|
+
while (current && current !== document.documentElement) {
|
|
35881
|
+
hasClickStyling = current.style.cursor === 'pointer' || getCachedComputedStyle(current).cursor === 'pointer';
|
|
35882
|
+
if (hasClickStyling)
|
|
35883
|
+
return false;
|
|
35884
|
+
current = current.parentElement;
|
|
35885
|
+
if (++count > 10)
|
|
35886
|
+
break;
|
|
35887
|
+
}
|
|
35888
|
+
return true;
|
|
35889
|
+
}
|
|
35890
|
+
return false;
|
|
35702
35891
|
}
|
|
35703
35892
|
// Helper function to check if element is visible
|
|
35704
35893
|
function isElementVisible(element) {
|
|
@@ -35728,11 +35917,14 @@ function run_build_dom_tree() {
|
|
|
35728
35917
|
if (!topEl)
|
|
35729
35918
|
return false;
|
|
35730
35919
|
// Check if the element or any of its parents match our target element
|
|
35920
|
+
let count = 0;
|
|
35731
35921
|
let current = topEl;
|
|
35732
35922
|
while (current && current !== shadowRoot) {
|
|
35733
35923
|
if (current === element)
|
|
35734
35924
|
return true;
|
|
35735
35925
|
current = current.parentElement;
|
|
35926
|
+
if (++count > 15)
|
|
35927
|
+
break;
|
|
35736
35928
|
}
|
|
35737
35929
|
return false;
|
|
35738
35930
|
}
|
|
@@ -35747,11 +35939,14 @@ function run_build_dom_tree() {
|
|
|
35747
35939
|
const topEl = document.elementFromPoint(point.x, point.y);
|
|
35748
35940
|
if (!topEl)
|
|
35749
35941
|
return false;
|
|
35942
|
+
let count = 0;
|
|
35750
35943
|
let current = topEl;
|
|
35751
35944
|
while (current && current !== document.documentElement) {
|
|
35752
35945
|
if (current === element)
|
|
35753
35946
|
return true;
|
|
35754
35947
|
current = current.parentElement;
|
|
35948
|
+
if (++count > 15)
|
|
35949
|
+
break;
|
|
35755
35950
|
}
|
|
35756
35951
|
return false;
|
|
35757
35952
|
}
|
|
@@ -35821,7 +36016,7 @@ function run_build_dom_tree() {
|
|
|
35821
36016
|
if (shouldHighlight) {
|
|
35822
36017
|
nodeData.highlightIndex = highlightIndex++;
|
|
35823
36018
|
window.clickable_elements[nodeData.highlightIndex] = node;
|
|
35824
|
-
if (
|
|
36019
|
+
if (markHighlightElements) {
|
|
35825
36020
|
highlightElement(node, nodeData.highlightIndex, parentIframe);
|
|
35826
36021
|
}
|
|
35827
36022
|
}
|
|
@@ -35982,26 +36177,37 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
|
|
|
35982
36177
|
}
|
|
35983
36178
|
async screenshot_and_html(agentContext) {
|
|
35984
36179
|
try {
|
|
35985
|
-
let element_result
|
|
36180
|
+
let element_result;
|
|
36181
|
+
let double_screenshots;
|
|
35986
36182
|
for (let i = 0; i < 5; i++) {
|
|
35987
36183
|
await sleep(200);
|
|
35988
36184
|
await this.execute_script(agentContext, run_build_dom_tree, []);
|
|
35989
36185
|
await sleep(50);
|
|
35990
|
-
element_result = (await this.execute_script(agentContext, () => {
|
|
35991
|
-
return window.get_clickable_elements(
|
|
35992
|
-
}, []));
|
|
36186
|
+
element_result = (await this.execute_script(agentContext, (markHighlightElements) => {
|
|
36187
|
+
return window.get_clickable_elements(markHighlightElements);
|
|
36188
|
+
}, [config$1.mode != "fast" && config$1.markImageMode == "dom"]));
|
|
35993
36189
|
if (element_result) {
|
|
35994
36190
|
break;
|
|
35995
36191
|
}
|
|
35996
36192
|
}
|
|
35997
36193
|
await sleep(100);
|
|
35998
|
-
|
|
35999
|
-
|
|
36000
|
-
|
|
36194
|
+
const screenshot = config$1.mode == "fast"
|
|
36195
|
+
? undefined
|
|
36196
|
+
: await this.screenshot_and_compress(agentContext, element_result.client_rect);
|
|
36197
|
+
if (config$1.markImageMode == "draw" &&
|
|
36198
|
+
screenshot?.imageBase64 &&
|
|
36199
|
+
element_result.area_map) {
|
|
36200
|
+
double_screenshots = { ...screenshot };
|
|
36201
|
+
const markImageBase64 = await mark_screenshot_highlight_elements(screenshot, element_result.area_map, element_result.client_rect);
|
|
36202
|
+
screenshot.imageBase64 = markImageBase64;
|
|
36203
|
+
}
|
|
36204
|
+
const pseudoHtml = element_result.element_str || "";
|
|
36001
36205
|
return {
|
|
36002
|
-
|
|
36003
|
-
|
|
36206
|
+
double_screenshots: double_screenshots,
|
|
36207
|
+
imageBase64: screenshot?.imageBase64,
|
|
36208
|
+
imageType: screenshot?.imageType,
|
|
36004
36209
|
pseudoHtml: pseudoHtml,
|
|
36210
|
+
client_rect: element_result.client_rect,
|
|
36005
36211
|
};
|
|
36006
36212
|
}
|
|
36007
36213
|
finally {
|
|
@@ -36013,6 +36219,20 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
|
|
|
36013
36219
|
catch (e) { }
|
|
36014
36220
|
}
|
|
36015
36221
|
}
|
|
36222
|
+
async screenshot_and_compress(agentContext, client_rect) {
|
|
36223
|
+
const screenshot = await this.screenshot(agentContext);
|
|
36224
|
+
if (!client_rect || !screenshot) {
|
|
36225
|
+
return screenshot;
|
|
36226
|
+
}
|
|
36227
|
+
const compressedImage = await compress_image(screenshot.imageBase64, screenshot.imageType, {
|
|
36228
|
+
resizeWidth: client_rect.width,
|
|
36229
|
+
resizeHeight: client_rect.height,
|
|
36230
|
+
});
|
|
36231
|
+
return {
|
|
36232
|
+
imageBase64: compressedImage.imageBase64,
|
|
36233
|
+
imageType: compressedImage.imageType,
|
|
36234
|
+
};
|
|
36235
|
+
}
|
|
36016
36236
|
get_element_script(index) {
|
|
36017
36237
|
return `window.get_highlight_element(${index});`;
|
|
36018
36238
|
}
|
|
@@ -36272,7 +36492,7 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
|
|
|
36272
36492
|
];
|
|
36273
36493
|
}
|
|
36274
36494
|
async double_screenshots(agentContext, messages, tools) {
|
|
36275
|
-
return
|
|
36495
|
+
return config$1.mode != "fast";
|
|
36276
36496
|
}
|
|
36277
36497
|
async handleMessages(agentContext, messages, tools) {
|
|
36278
36498
|
const pseudoHtmlDescription = "This is the environmental information after the operation, including the latest browser screenshot and page elements. Please perform the next operation based on the environmental information. Do not output the following elements and index information in your response.\n\nIndex and elements:\n";
|
|
@@ -36282,23 +36502,27 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
|
|
|
36282
36502
|
lastTool.toolName !== "get_all_tabs" &&
|
|
36283
36503
|
lastTool.toolName !== "variable_storage") {
|
|
36284
36504
|
await sleep(300);
|
|
36285
|
-
|
|
36505
|
+
const image_contents = [];
|
|
36506
|
+
const result = await this.screenshot_and_html(agentContext);
|
|
36286
36507
|
if (await this.double_screenshots(agentContext, messages, tools)) {
|
|
36287
|
-
|
|
36288
|
-
|
|
36508
|
+
const imageResult = result.double_screenshots
|
|
36509
|
+
? result.double_screenshots
|
|
36510
|
+
: await this.screenshot_and_compress(agentContext, result.client_rect);
|
|
36511
|
+
const image = toImage(imageResult.imageBase64);
|
|
36289
36512
|
image_contents.push({
|
|
36290
36513
|
type: "file",
|
|
36291
36514
|
data: image,
|
|
36292
36515
|
mediaType: imageResult.imageType,
|
|
36293
36516
|
});
|
|
36294
36517
|
}
|
|
36295
|
-
|
|
36296
|
-
|
|
36297
|
-
|
|
36298
|
-
|
|
36299
|
-
|
|
36300
|
-
|
|
36301
|
-
|
|
36518
|
+
if (result.imageBase64) {
|
|
36519
|
+
const image = toImage(result.imageBase64);
|
|
36520
|
+
image_contents.push({
|
|
36521
|
+
type: "file",
|
|
36522
|
+
data: image,
|
|
36523
|
+
mediaType: result.imageType || "image/png",
|
|
36524
|
+
});
|
|
36525
|
+
}
|
|
36302
36526
|
messages.push({
|
|
36303
36527
|
role: "user",
|
|
36304
36528
|
content: [
|
|
@@ -36447,7 +36671,7 @@ function do_click(params) {
|
|
|
36447
36671
|
cancelable: true,
|
|
36448
36672
|
button, // 0 left; 1 middle; 2 right
|
|
36449
36673
|
});
|
|
36450
|
-
if (eventType ===
|
|
36674
|
+
if (eventType === "click" && element.click) {
|
|
36451
36675
|
// support shadow dom element
|
|
36452
36676
|
element.click();
|
|
36453
36677
|
}
|