@eko-ai/eko 1.0.7 → 1.0.8
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 +66 -23
- package/dist/extension/content/index.d.ts +1 -0
- package/dist/extension/tools/browser.d.ts +2 -1
- package/dist/extension/tools/index.d.ts +2 -1
- package/dist/extension/tools/request_login.d.ts +10 -0
- package/dist/extension/utils.d.ts +1 -0
- package/dist/extension.cjs.js +137 -20
- package/dist/extension.esm.js +137 -20
- package/dist/extension_content_script.js +129 -2
- package/dist/index.cjs.js +85 -5
- package/dist/index.esm.js +85 -5
- package/dist/models/action.d.ts +1 -0
- package/dist/nodejs/script/build_dom_tree.d.ts +1 -0
- package/dist/nodejs/tools/browser_use.d.ts +28 -0
- package/dist/nodejs/tools/index.d.ts +1 -0
- package/dist/nodejs.cjs.js +71428 -11
- package/dist/nodejs.esm.js +71422 -5
- package/dist/web/tools/browser.d.ts +2 -1
- package/dist/web.cjs.js +29 -17
- package/dist/web.esm.js +29 -17
- package/package.json +5 -7
|
@@ -40,6 +40,11 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
|
|
40
40
|
sendResponse(result);
|
|
41
41
|
break;
|
|
42
42
|
}
|
|
43
|
+
case 'request_user_help': {
|
|
44
|
+
request_user_help(request.task_id, request.failure_type, request.failure_message);
|
|
45
|
+
sendResponse(true);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
43
48
|
case 'computer:type': {
|
|
44
49
|
sendResponse(type(request));
|
|
45
50
|
break;
|
|
@@ -204,7 +209,7 @@ function scroll_to(request) {
|
|
|
204
209
|
return false;
|
|
205
210
|
}
|
|
206
211
|
element.scrollIntoView({
|
|
207
|
-
behavior: 'smooth'
|
|
212
|
+
behavior: 'smooth',
|
|
208
213
|
});
|
|
209
214
|
}
|
|
210
215
|
else if (request.xpath) {
|
|
@@ -215,7 +220,7 @@ function scroll_to(request) {
|
|
|
215
220
|
return false;
|
|
216
221
|
}
|
|
217
222
|
element.scrollIntoView({
|
|
218
|
-
behavior: 'smooth'
|
|
223
|
+
behavior: 'smooth',
|
|
219
224
|
});
|
|
220
225
|
}
|
|
221
226
|
else {
|
|
@@ -277,3 +282,125 @@ function select_dropdown_option(request) {
|
|
|
277
282
|
selectedText: option.text.trim(),
|
|
278
283
|
};
|
|
279
284
|
}
|
|
285
|
+
function request_user_help(task_id, failure_type, failure_message) {
|
|
286
|
+
const domId = 'eko-request-user-help';
|
|
287
|
+
if (document.getElementById(domId)) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const failureTitleMap = {
|
|
291
|
+
login_required: 'Login Required',
|
|
292
|
+
captcha: 'Captcha Detected',
|
|
293
|
+
blocked: 'Blocked',
|
|
294
|
+
other: 'Error',
|
|
295
|
+
rate_limited: 'Rate Limited',
|
|
296
|
+
};
|
|
297
|
+
const notification = document.createElement('div');
|
|
298
|
+
notification.id = domId;
|
|
299
|
+
notification.style.cssText = `
|
|
300
|
+
position: fixed;
|
|
301
|
+
top: 5px;
|
|
302
|
+
left: 18px;
|
|
303
|
+
z-index: 9999;
|
|
304
|
+
background-color: #FEF0ED;
|
|
305
|
+
color: white;
|
|
306
|
+
padding: 16px;
|
|
307
|
+
border-radius: 12px;
|
|
308
|
+
border: 1px solid #FBB8A5;
|
|
309
|
+
font-family: Arial, sans-serif;
|
|
310
|
+
width: 350px;
|
|
311
|
+
display: flex;
|
|
312
|
+
flex-direction: row;
|
|
313
|
+
gap: 10px;
|
|
314
|
+
cursor: move;
|
|
315
|
+
user-select: none;
|
|
316
|
+
`;
|
|
317
|
+
let isDragging = false;
|
|
318
|
+
let xOffset = 0;
|
|
319
|
+
let yOffset = 0;
|
|
320
|
+
let initialX = 0;
|
|
321
|
+
let initialY = 0;
|
|
322
|
+
notification.addEventListener('mousedown', (e) => {
|
|
323
|
+
isDragging = true;
|
|
324
|
+
initialX = e.clientX - xOffset;
|
|
325
|
+
initialY = e.clientY - yOffset;
|
|
326
|
+
e.preventDefault();
|
|
327
|
+
});
|
|
328
|
+
document.addEventListener('mousemove', (e) => {
|
|
329
|
+
if (!isDragging)
|
|
330
|
+
return;
|
|
331
|
+
const currentX = e.clientX - initialX;
|
|
332
|
+
const currentY = e.clientY - initialY;
|
|
333
|
+
xOffset = currentX;
|
|
334
|
+
yOffset = currentY;
|
|
335
|
+
notification.style.transform = `translate(${xOffset}px, ${yOffset}px)`;
|
|
336
|
+
});
|
|
337
|
+
document.addEventListener('mouseup', () => {
|
|
338
|
+
isDragging = false;
|
|
339
|
+
});
|
|
340
|
+
const leftContainer = document.createElement('div');
|
|
341
|
+
leftContainer.style.cssText = `
|
|
342
|
+
width: 28px;
|
|
343
|
+
height: 28px;
|
|
344
|
+
display: flex;
|
|
345
|
+
flex-direction: column;
|
|
346
|
+
align-items: center;
|
|
347
|
+
border-radius: 99px;
|
|
348
|
+
background: #FDCCCC;
|
|
349
|
+
justify-content: center;
|
|
350
|
+
`;
|
|
351
|
+
leftContainer.innerHTML = ``;
|
|
352
|
+
const rightContainer = document.createElement('div');
|
|
353
|
+
rightContainer.style.cssText = `
|
|
354
|
+
flex: 1;
|
|
355
|
+
display: flex;
|
|
356
|
+
flex-direction: column;
|
|
357
|
+
`;
|
|
358
|
+
const title = document.createElement('div');
|
|
359
|
+
title.style.cssText = `
|
|
360
|
+
font-size: 16px;
|
|
361
|
+
font-weight: 700;
|
|
362
|
+
line-height: 22px;
|
|
363
|
+
color: #DD342D;
|
|
364
|
+
text-align: left;
|
|
365
|
+
`;
|
|
366
|
+
title.innerText = failureTitleMap[failure_type] || failure_type;
|
|
367
|
+
const message2 = document.createElement('div');
|
|
368
|
+
message2.style.cssText = `
|
|
369
|
+
font-size: 16px;
|
|
370
|
+
font-weight: 400;
|
|
371
|
+
line-height: 22px;
|
|
372
|
+
color: #DD342D;
|
|
373
|
+
text-align: left;
|
|
374
|
+
`;
|
|
375
|
+
message2.innerText = failure_message + '\nWhen you resolve the issue, click the button below.';
|
|
376
|
+
const buttonDiv = document.createElement('div');
|
|
377
|
+
buttonDiv.style.cssText = `
|
|
378
|
+
margin-top: 16px;
|
|
379
|
+
display: flex;
|
|
380
|
+
flex-direction: row-reverse;
|
|
381
|
+
justify-content: flex-start;
|
|
382
|
+
align-items: center;
|
|
383
|
+
`;
|
|
384
|
+
const resolvedBut = document.createElement('div');
|
|
385
|
+
resolvedBut.innerText = 'Resolved';
|
|
386
|
+
resolvedBut.style.cssText = `
|
|
387
|
+
border-radius: 8px;
|
|
388
|
+
background: #DD342D;
|
|
389
|
+
color: white;
|
|
390
|
+
padding: 10px;
|
|
391
|
+
border: none;
|
|
392
|
+
cursor: pointer;
|
|
393
|
+
`;
|
|
394
|
+
resolvedBut.onclick = () => {
|
|
395
|
+
chrome.runtime.sendMessage({ type: 'issue_resolved', task_id, failure_type }, () => {
|
|
396
|
+
notification.remove();
|
|
397
|
+
});
|
|
398
|
+
};
|
|
399
|
+
buttonDiv.appendChild(resolvedBut);
|
|
400
|
+
rightContainer.appendChild(title);
|
|
401
|
+
rightContainer.appendChild(message2);
|
|
402
|
+
rightContainer.appendChild(buttonDiv);
|
|
403
|
+
notification.appendChild(leftContainer);
|
|
404
|
+
notification.appendChild(rightContainer);
|
|
405
|
+
document.body.appendChild(notification);
|
|
406
|
+
}
|
package/dist/index.cjs.js
CHANGED
|
@@ -313,6 +313,7 @@ class ActionImpl {
|
|
|
313
313
|
console.error('Stream Error:', error);
|
|
314
314
|
},
|
|
315
315
|
};
|
|
316
|
+
this.handleHistoryImageMessages(messages);
|
|
316
317
|
// Wait for stream to complete
|
|
317
318
|
await this.llmProvider.generateStream(messages, params, handler);
|
|
318
319
|
// Wait for tool execution to complete if it was started
|
|
@@ -320,7 +321,7 @@ class ActionImpl {
|
|
|
320
321
|
await toolExecutionPromise;
|
|
321
322
|
}
|
|
322
323
|
if (context.__abort) {
|
|
323
|
-
throw new Error(
|
|
324
|
+
throw new Error('Abort');
|
|
324
325
|
}
|
|
325
326
|
// Add messages in the correct order after everything is complete
|
|
326
327
|
if (assistantTextMessage) {
|
|
@@ -334,6 +335,37 @@ class ActionImpl {
|
|
|
334
335
|
}
|
|
335
336
|
return { response, hasToolUse, roundMessages };
|
|
336
337
|
}
|
|
338
|
+
handleHistoryImageMessages(messages) {
|
|
339
|
+
// Remove all images of the historical tool call results, except for the last one.
|
|
340
|
+
let last_user = true;
|
|
341
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
342
|
+
const message = messages[i];
|
|
343
|
+
if (message.role === 'user') {
|
|
344
|
+
if (last_user) {
|
|
345
|
+
last_user = false;
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
if (message.content instanceof Array) {
|
|
349
|
+
let content = message.content;
|
|
350
|
+
for (let j = 0; j < content.length; j++) {
|
|
351
|
+
if (content[j].type === 'tool_result' && content[j].content instanceof Array) {
|
|
352
|
+
let tool_content = content[j].content;
|
|
353
|
+
if (tool_content.length > 0) {
|
|
354
|
+
for (let k = tool_content.length - 1; k >= 0; k--) {
|
|
355
|
+
if (tool_content[k].type === 'image') {
|
|
356
|
+
tool_content.splice(k, 1);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else if (tool_content[0].type === 'image') {
|
|
361
|
+
tool_content = [{ type: 'text', text: 'ok' }];
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
337
369
|
async execute(input, context, outputSchema) {
|
|
338
370
|
var _a;
|
|
339
371
|
// Create return tool with output schema
|
|
@@ -8876,13 +8908,61 @@ class OpenaiProvider {
|
|
|
8876
8908
|
content: content.text,
|
|
8877
8909
|
});
|
|
8878
8910
|
}
|
|
8879
|
-
else if (content.type == '
|
|
8911
|
+
else if (content.type == 'image') {
|
|
8880
8912
|
_messages.push({
|
|
8881
|
-
role: '
|
|
8882
|
-
content:
|
|
8883
|
-
|
|
8913
|
+
role: 'user',
|
|
8914
|
+
content: [
|
|
8915
|
+
{
|
|
8916
|
+
type: 'image_url',
|
|
8917
|
+
image_url: {
|
|
8918
|
+
url: `data:${content.source.media_type};base64,${content.source.data}`,
|
|
8919
|
+
},
|
|
8920
|
+
},
|
|
8921
|
+
],
|
|
8884
8922
|
});
|
|
8885
8923
|
}
|
|
8924
|
+
else if (content.type == 'tool_result') {
|
|
8925
|
+
let _content = [];
|
|
8926
|
+
if (content.content == 'string') {
|
|
8927
|
+
_content.push({ type: 'text', text: content.content });
|
|
8928
|
+
}
|
|
8929
|
+
else {
|
|
8930
|
+
for (let k = 0; k < content.content.length; k++) {
|
|
8931
|
+
let item = content.content[k];
|
|
8932
|
+
if (item.type == 'text') {
|
|
8933
|
+
_content.push({ ...item });
|
|
8934
|
+
}
|
|
8935
|
+
else if (item.type == 'image') {
|
|
8936
|
+
_content.push({
|
|
8937
|
+
type: 'image_url',
|
|
8938
|
+
image_url: {
|
|
8939
|
+
url: `data:${item.source.media_type};base64,${item.source.data}`,
|
|
8940
|
+
},
|
|
8941
|
+
});
|
|
8942
|
+
}
|
|
8943
|
+
}
|
|
8944
|
+
}
|
|
8945
|
+
let hasImage = _content.filter((s) => s.type == 'image_url').length > 0;
|
|
8946
|
+
if (hasImage) {
|
|
8947
|
+
// OpenAI does not support images returned by the tool.
|
|
8948
|
+
_messages.push({
|
|
8949
|
+
role: 'tool',
|
|
8950
|
+
content: 'ok',
|
|
8951
|
+
tool_call_id: content.tool_call_id || content.tool_use_id,
|
|
8952
|
+
});
|
|
8953
|
+
_messages.push({
|
|
8954
|
+
role: 'user',
|
|
8955
|
+
content: _content,
|
|
8956
|
+
});
|
|
8957
|
+
}
|
|
8958
|
+
else {
|
|
8959
|
+
_messages.push({
|
|
8960
|
+
role: 'tool',
|
|
8961
|
+
content: _content,
|
|
8962
|
+
tool_call_id: content.tool_call_id || content.tool_use_id,
|
|
8963
|
+
});
|
|
8964
|
+
}
|
|
8965
|
+
}
|
|
8886
8966
|
}
|
|
8887
8967
|
}
|
|
8888
8968
|
else {
|
package/dist/index.esm.js
CHANGED
|
@@ -309,6 +309,7 @@ class ActionImpl {
|
|
|
309
309
|
console.error('Stream Error:', error);
|
|
310
310
|
},
|
|
311
311
|
};
|
|
312
|
+
this.handleHistoryImageMessages(messages);
|
|
312
313
|
// Wait for stream to complete
|
|
313
314
|
await this.llmProvider.generateStream(messages, params, handler);
|
|
314
315
|
// Wait for tool execution to complete if it was started
|
|
@@ -316,7 +317,7 @@ class ActionImpl {
|
|
|
316
317
|
await toolExecutionPromise;
|
|
317
318
|
}
|
|
318
319
|
if (context.__abort) {
|
|
319
|
-
throw new Error(
|
|
320
|
+
throw new Error('Abort');
|
|
320
321
|
}
|
|
321
322
|
// Add messages in the correct order after everything is complete
|
|
322
323
|
if (assistantTextMessage) {
|
|
@@ -330,6 +331,37 @@ class ActionImpl {
|
|
|
330
331
|
}
|
|
331
332
|
return { response, hasToolUse, roundMessages };
|
|
332
333
|
}
|
|
334
|
+
handleHistoryImageMessages(messages) {
|
|
335
|
+
// Remove all images of the historical tool call results, except for the last one.
|
|
336
|
+
let last_user = true;
|
|
337
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
338
|
+
const message = messages[i];
|
|
339
|
+
if (message.role === 'user') {
|
|
340
|
+
if (last_user) {
|
|
341
|
+
last_user = false;
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (message.content instanceof Array) {
|
|
345
|
+
let content = message.content;
|
|
346
|
+
for (let j = 0; j < content.length; j++) {
|
|
347
|
+
if (content[j].type === 'tool_result' && content[j].content instanceof Array) {
|
|
348
|
+
let tool_content = content[j].content;
|
|
349
|
+
if (tool_content.length > 0) {
|
|
350
|
+
for (let k = tool_content.length - 1; k >= 0; k--) {
|
|
351
|
+
if (tool_content[k].type === 'image') {
|
|
352
|
+
tool_content.splice(k, 1);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else if (tool_content[0].type === 'image') {
|
|
357
|
+
tool_content = [{ type: 'text', text: 'ok' }];
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
333
365
|
async execute(input, context, outputSchema) {
|
|
334
366
|
var _a;
|
|
335
367
|
// Create return tool with output schema
|
|
@@ -8872,13 +8904,61 @@ class OpenaiProvider {
|
|
|
8872
8904
|
content: content.text,
|
|
8873
8905
|
});
|
|
8874
8906
|
}
|
|
8875
|
-
else if (content.type == '
|
|
8907
|
+
else if (content.type == 'image') {
|
|
8876
8908
|
_messages.push({
|
|
8877
|
-
role: '
|
|
8878
|
-
content:
|
|
8879
|
-
|
|
8909
|
+
role: 'user',
|
|
8910
|
+
content: [
|
|
8911
|
+
{
|
|
8912
|
+
type: 'image_url',
|
|
8913
|
+
image_url: {
|
|
8914
|
+
url: `data:${content.source.media_type};base64,${content.source.data}`,
|
|
8915
|
+
},
|
|
8916
|
+
},
|
|
8917
|
+
],
|
|
8880
8918
|
});
|
|
8881
8919
|
}
|
|
8920
|
+
else if (content.type == 'tool_result') {
|
|
8921
|
+
let _content = [];
|
|
8922
|
+
if (content.content == 'string') {
|
|
8923
|
+
_content.push({ type: 'text', text: content.content });
|
|
8924
|
+
}
|
|
8925
|
+
else {
|
|
8926
|
+
for (let k = 0; k < content.content.length; k++) {
|
|
8927
|
+
let item = content.content[k];
|
|
8928
|
+
if (item.type == 'text') {
|
|
8929
|
+
_content.push({ ...item });
|
|
8930
|
+
}
|
|
8931
|
+
else if (item.type == 'image') {
|
|
8932
|
+
_content.push({
|
|
8933
|
+
type: 'image_url',
|
|
8934
|
+
image_url: {
|
|
8935
|
+
url: `data:${item.source.media_type};base64,${item.source.data}`,
|
|
8936
|
+
},
|
|
8937
|
+
});
|
|
8938
|
+
}
|
|
8939
|
+
}
|
|
8940
|
+
}
|
|
8941
|
+
let hasImage = _content.filter((s) => s.type == 'image_url').length > 0;
|
|
8942
|
+
if (hasImage) {
|
|
8943
|
+
// OpenAI does not support images returned by the tool.
|
|
8944
|
+
_messages.push({
|
|
8945
|
+
role: 'tool',
|
|
8946
|
+
content: 'ok',
|
|
8947
|
+
tool_call_id: content.tool_call_id || content.tool_use_id,
|
|
8948
|
+
});
|
|
8949
|
+
_messages.push({
|
|
8950
|
+
role: 'user',
|
|
8951
|
+
content: _content,
|
|
8952
|
+
});
|
|
8953
|
+
}
|
|
8954
|
+
else {
|
|
8955
|
+
_messages.push({
|
|
8956
|
+
role: 'tool',
|
|
8957
|
+
content: _content,
|
|
8958
|
+
tool_call_id: content.tool_call_id || content.tool_use_id,
|
|
8959
|
+
});
|
|
8960
|
+
}
|
|
8961
|
+
}
|
|
8882
8962
|
}
|
|
8883
8963
|
}
|
|
8884
8964
|
else {
|
package/dist/models/action.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare class ActionImpl implements Action {
|
|
|
14
14
|
maxRounds?: number;
|
|
15
15
|
});
|
|
16
16
|
private executeSingleRound;
|
|
17
|
+
private handleHistoryImageMessages;
|
|
17
18
|
execute(input: unknown, context: ExecutionContext, outputSchema?: unknown): Promise<unknown>;
|
|
18
19
|
private formatSystemPrompt;
|
|
19
20
|
private formatUserPrompt;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function run_build_dom_tree(): void;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BrowserUseParam, BrowserUseResult } from '../../types/tools.types';
|
|
2
|
+
import { Tool, InputSchema, ExecutionContext } from '../../types/action.types';
|
|
3
|
+
/**
|
|
4
|
+
* Browser Use => `npx playwright install`
|
|
5
|
+
*/
|
|
6
|
+
export declare class BrowserUse implements Tool<BrowserUseParam, BrowserUseResult> {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
input_schema: InputSchema;
|
|
10
|
+
private browser;
|
|
11
|
+
private browser_context;
|
|
12
|
+
private current_page;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* browser
|
|
16
|
+
*
|
|
17
|
+
* @param {*} params { action: 'input_text', index: 1, text: 'string' }
|
|
18
|
+
* @returns > { success: true, image?: { type: 'base64', media_type: 'image/jpeg', data: '/9j...' }, text?: string }
|
|
19
|
+
*/
|
|
20
|
+
execute(context: ExecutionContext, params: BrowserUseParam): Promise<BrowserUseResult>;
|
|
21
|
+
private open_url;
|
|
22
|
+
private injectScript;
|
|
23
|
+
private get_highlight_element;
|
|
24
|
+
private extractHtmlContent;
|
|
25
|
+
private get_dropdown_options;
|
|
26
|
+
private select_dropdown_option;
|
|
27
|
+
destroy(context: ExecutionContext): void;
|
|
28
|
+
}
|