@eko-ai/eko 1.0.1 → 1.0.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 +56 -44
- package/dist/core/eko.d.ts +1 -0
- package/dist/core/tool-registry.d.ts +1 -1
- package/dist/extension/script/build_dom_tree.d.ts +40 -0
- package/dist/extension/tools/index.d.ts +1 -2
- package/dist/extension.cjs.js +171 -190
- package/dist/extension.esm.js +171 -190
- package/dist/index.cjs.js +59 -49
- package/dist/index.esm.js +59 -49
- package/dist/models/action.d.ts +3 -2
- package/dist/nodejs/core.d.ts +2 -0
- package/dist/nodejs/index.d.ts +1 -0
- package/dist/nodejs/tools/command_execute.d.ts +12 -0
- package/dist/nodejs/tools/file_read.d.ts +11 -0
- package/dist/nodejs/tools/file_write.d.ts +15 -0
- package/dist/nodejs/tools/index.d.ts +3 -1
- package/dist/nodejs.cjs.js +227 -3
- package/dist/nodejs.esm.js +226 -3
- package/dist/schemas/workflow.schema.d.ts +3 -0
- package/dist/services/llm/claude-provider.d.ts +1 -0
- package/dist/services/llm/openai-provider.d.ts +1 -0
- package/dist/types/action.types.d.ts +1 -0
- package/dist/web/core.d.ts +2 -0
- package/dist/web/index.d.ts +3 -0
- package/dist/web/script/build_dom_tree.d.ts +12 -0
- package/dist/web/tools/browser.d.ts +10 -0
- package/dist/web/tools/browser_use.d.ts +18 -0
- package/dist/web/tools/element_click.d.ts +12 -0
- package/dist/web/tools/export_file.d.ts +18 -0
- package/dist/web/tools/extract_content.d.ts +17 -0
- package/dist/web/tools/find_element_position.d.ts +12 -0
- package/dist/web/tools/html_script.d.ts +21 -0
- package/dist/web/tools/index.d.ts +7 -1
- package/dist/web/tools/screenshot.d.ts +18 -0
- package/dist/web.cjs.js +9307 -3
- package/dist/web.esm.js +9305 -3
- package/package.json +2 -1
package/dist/extension.esm.js
CHANGED
|
@@ -233,6 +233,177 @@ var utils = /*#__PURE__*/Object.freeze({
|
|
|
233
233
|
waitForTabComplete: waitForTabComplete
|
|
234
234
|
});
|
|
235
235
|
|
|
236
|
+
function exportFile(filename, type, content) {
|
|
237
|
+
const blob = new Blob([content], { type: type });
|
|
238
|
+
const link = document.createElement('a');
|
|
239
|
+
link.href = URL.createObjectURL(blob);
|
|
240
|
+
link.download = filename;
|
|
241
|
+
document.body.appendChild(link);
|
|
242
|
+
link.click();
|
|
243
|
+
document.body.removeChild(link);
|
|
244
|
+
URL.revokeObjectURL(link.href);
|
|
245
|
+
}
|
|
246
|
+
function getDropdownOptions(xpath) {
|
|
247
|
+
const select = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)
|
|
248
|
+
.singleNodeValue;
|
|
249
|
+
if (!select) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
options: Array.from(select.options).map((opt) => ({
|
|
254
|
+
index: opt.index,
|
|
255
|
+
text: opt.text.trim(),
|
|
256
|
+
value: opt.value,
|
|
257
|
+
})),
|
|
258
|
+
id: select.id,
|
|
259
|
+
name: select.name,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function selectDropdownOption(xpath, text) {
|
|
263
|
+
const select = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)
|
|
264
|
+
.singleNodeValue;
|
|
265
|
+
if (!select || select.tagName.toUpperCase() !== 'SELECT') {
|
|
266
|
+
return { success: false, error: 'Select not found or invalid element type' };
|
|
267
|
+
}
|
|
268
|
+
const option = Array.from(select.options).find((opt) => opt.text.trim() === text);
|
|
269
|
+
if (!option) {
|
|
270
|
+
return {
|
|
271
|
+
success: false,
|
|
272
|
+
error: 'Option not found',
|
|
273
|
+
availableOptions: Array.from(select.options).map((o) => o.text.trim()),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
select.value = option.value;
|
|
277
|
+
select.dispatchEvent(new Event('change'));
|
|
278
|
+
return {
|
|
279
|
+
success: true,
|
|
280
|
+
selectedValue: option.value,
|
|
281
|
+
selectedText: option.text.trim(),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Extract the elements related to html operability and wrap them into pseudo-html code.
|
|
286
|
+
*/
|
|
287
|
+
function extractOperableElements() {
|
|
288
|
+
// visible
|
|
289
|
+
const isElementVisible = (element) => {
|
|
290
|
+
const style = window.getComputedStyle(element);
|
|
291
|
+
return (style.display !== 'none' &&
|
|
292
|
+
style.visibility !== 'hidden' &&
|
|
293
|
+
style.opacity !== '0' &&
|
|
294
|
+
element.offsetWidth > 0 &&
|
|
295
|
+
element.offsetHeight > 0);
|
|
296
|
+
};
|
|
297
|
+
// element original index
|
|
298
|
+
const getElementIndex = (element) => {
|
|
299
|
+
const xpath = document.evaluate('preceding::*', element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
|
300
|
+
return xpath.snapshotLength;
|
|
301
|
+
};
|
|
302
|
+
// exclude
|
|
303
|
+
const addExclude = (excludes, children) => {
|
|
304
|
+
for (let i = 0; i < children.length; i++) {
|
|
305
|
+
excludes.push(children[i]);
|
|
306
|
+
if (children[i].children) {
|
|
307
|
+
addExclude(excludes, children[i].children);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
// { pseudoId: element }
|
|
312
|
+
let elementMap = {};
|
|
313
|
+
let nextId = 1;
|
|
314
|
+
let elements = [];
|
|
315
|
+
let excludes = [];
|
|
316
|
+
// operable element
|
|
317
|
+
const operableSelectors = 'a, button, input, textarea, select';
|
|
318
|
+
document.querySelectorAll(operableSelectors).forEach((element) => {
|
|
319
|
+
if (isElementVisible(element) && excludes.indexOf(element) == -1) {
|
|
320
|
+
const id = nextId++;
|
|
321
|
+
elementMap[id.toString()] = element;
|
|
322
|
+
const tagName = element.tagName.toLowerCase();
|
|
323
|
+
const attributes = Array.from(element.attributes)
|
|
324
|
+
.filter((attr) => ['id', 'name', 'type', 'value', 'href', 'title', 'placeholder'].includes(attr.name))
|
|
325
|
+
.map((attr) => `${attr.name == 'id' ? 'target' : attr.name}="${attr.value}"`)
|
|
326
|
+
.join(' ');
|
|
327
|
+
elements.push({
|
|
328
|
+
originalIndex: getElementIndex(element),
|
|
329
|
+
id: id,
|
|
330
|
+
html: `<${tagName} id="${id}" ${attributes}>${tagName == 'select' ? element.innerHTML : element.innerText || ''}</${tagName}>`,
|
|
331
|
+
});
|
|
332
|
+
addExclude(excludes, element.children);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
// short text element
|
|
336
|
+
const textWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
|
|
337
|
+
acceptNode: function (node) {
|
|
338
|
+
var _a;
|
|
339
|
+
if (node.matches(operableSelectors) || excludes.indexOf(node) != -1) {
|
|
340
|
+
// skip
|
|
341
|
+
return NodeFilter.FILTER_SKIP;
|
|
342
|
+
}
|
|
343
|
+
// text <= 100
|
|
344
|
+
const text = (_a = node.innerText) === null || _a === void 0 ? void 0 : _a.trim();
|
|
345
|
+
if (isElementVisible(node) &&
|
|
346
|
+
text &&
|
|
347
|
+
text.length <= 100 &&
|
|
348
|
+
text.length > 0 &&
|
|
349
|
+
node.children.length === 0) {
|
|
350
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
351
|
+
}
|
|
352
|
+
// skip
|
|
353
|
+
return NodeFilter.FILTER_SKIP;
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
let currentNode;
|
|
357
|
+
while ((currentNode = textWalker.nextNode())) {
|
|
358
|
+
const id = nextId++;
|
|
359
|
+
elementMap[id.toString()] = currentNode;
|
|
360
|
+
const tagName = currentNode.tagName.toLowerCase();
|
|
361
|
+
elements.push({
|
|
362
|
+
originalIndex: getElementIndex(currentNode),
|
|
363
|
+
id: id,
|
|
364
|
+
html: `<${tagName} id="${id}">${currentNode.innerText.trim()}</${tagName}>`,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
// element sort
|
|
368
|
+
elements.sort((a, b) => a.originalIndex - b.originalIndex);
|
|
369
|
+
// cache
|
|
370
|
+
window.operableElementMap = elementMap;
|
|
371
|
+
// pseudo html
|
|
372
|
+
return elements.map((e) => e.html).join('\n');
|
|
373
|
+
}
|
|
374
|
+
function clickOperableElement(id) {
|
|
375
|
+
let element = window.operableElementMap[id];
|
|
376
|
+
if (!element) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
if (element.click) {
|
|
380
|
+
element.click();
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
element.dispatchEvent(new MouseEvent('click', {
|
|
384
|
+
view: window,
|
|
385
|
+
bubbles: true,
|
|
386
|
+
cancelable: true,
|
|
387
|
+
}));
|
|
388
|
+
}
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
function getOperableElementRect(id) {
|
|
392
|
+
let element = window.operableElementMap[id];
|
|
393
|
+
if (!element) {
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
const rect = element.getBoundingClientRect();
|
|
397
|
+
return {
|
|
398
|
+
left: rect.left + window.scrollX,
|
|
399
|
+
top: rect.top + window.scrollY,
|
|
400
|
+
right: rect.right + window.scrollX,
|
|
401
|
+
bottom: rect.bottom + window.scrollY,
|
|
402
|
+
width: rect.right - rect.left,
|
|
403
|
+
height: rect.bottom - rect.top,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
236
407
|
async function key(tabId, key, coordinate) {
|
|
237
408
|
if (!coordinate) {
|
|
238
409
|
coordinate = (await cursor_position(tabId)).coordinate;
|
|
@@ -442,177 +613,6 @@ var browser = /*#__PURE__*/Object.freeze({
|
|
|
442
613
|
type_by_xpath: type_by_xpath
|
|
443
614
|
});
|
|
444
615
|
|
|
445
|
-
function exportFile(filename, type, content) {
|
|
446
|
-
const blob = new Blob([content], { type: type });
|
|
447
|
-
const link = document.createElement('a');
|
|
448
|
-
link.href = URL.createObjectURL(blob);
|
|
449
|
-
link.download = filename;
|
|
450
|
-
document.body.appendChild(link);
|
|
451
|
-
link.click();
|
|
452
|
-
document.body.removeChild(link);
|
|
453
|
-
URL.revokeObjectURL(link.href);
|
|
454
|
-
}
|
|
455
|
-
function getDropdownOptions(xpath) {
|
|
456
|
-
const select = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)
|
|
457
|
-
.singleNodeValue;
|
|
458
|
-
if (!select) {
|
|
459
|
-
return null;
|
|
460
|
-
}
|
|
461
|
-
return {
|
|
462
|
-
options: Array.from(select.options).map((opt) => ({
|
|
463
|
-
index: opt.index,
|
|
464
|
-
text: opt.text.trim(),
|
|
465
|
-
value: opt.value,
|
|
466
|
-
})),
|
|
467
|
-
id: select.id,
|
|
468
|
-
name: select.name,
|
|
469
|
-
};
|
|
470
|
-
}
|
|
471
|
-
function selectDropdownOption(xpath, text) {
|
|
472
|
-
const select = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)
|
|
473
|
-
.singleNodeValue;
|
|
474
|
-
if (!select || select.tagName.toUpperCase() !== 'SELECT') {
|
|
475
|
-
return { success: false, error: 'Select not found or invalid element type' };
|
|
476
|
-
}
|
|
477
|
-
const option = Array.from(select.options).find((opt) => opt.text.trim() === text);
|
|
478
|
-
if (!option) {
|
|
479
|
-
return {
|
|
480
|
-
success: false,
|
|
481
|
-
error: 'Option not found',
|
|
482
|
-
availableOptions: Array.from(select.options).map((o) => o.text.trim()),
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
select.value = option.value;
|
|
486
|
-
select.dispatchEvent(new Event('change'));
|
|
487
|
-
return {
|
|
488
|
-
success: true,
|
|
489
|
-
selectedValue: option.value,
|
|
490
|
-
selectedText: option.text.trim(),
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
/**
|
|
494
|
-
* Extract the elements related to html operability and wrap them into pseudo-html code.
|
|
495
|
-
*/
|
|
496
|
-
function extractOperableElements() {
|
|
497
|
-
// visible
|
|
498
|
-
const isElementVisible = (element) => {
|
|
499
|
-
const style = window.getComputedStyle(element);
|
|
500
|
-
return (style.display !== 'none' &&
|
|
501
|
-
style.visibility !== 'hidden' &&
|
|
502
|
-
style.opacity !== '0' &&
|
|
503
|
-
element.offsetWidth > 0 &&
|
|
504
|
-
element.offsetHeight > 0);
|
|
505
|
-
};
|
|
506
|
-
// element original index
|
|
507
|
-
const getElementIndex = (element) => {
|
|
508
|
-
const xpath = document.evaluate('preceding::*', element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
|
509
|
-
return xpath.snapshotLength;
|
|
510
|
-
};
|
|
511
|
-
// exclude
|
|
512
|
-
const addExclude = (excludes, children) => {
|
|
513
|
-
for (let i = 0; i < children.length; i++) {
|
|
514
|
-
excludes.push(children[i]);
|
|
515
|
-
if (children[i].children) {
|
|
516
|
-
addExclude(excludes, children[i].children);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
};
|
|
520
|
-
// { pseudoId: element }
|
|
521
|
-
let elementMap = {};
|
|
522
|
-
let nextId = 1;
|
|
523
|
-
let elements = [];
|
|
524
|
-
let excludes = [];
|
|
525
|
-
// operable element
|
|
526
|
-
const operableSelectors = 'a, button, input, textarea, select';
|
|
527
|
-
document.querySelectorAll(operableSelectors).forEach((element) => {
|
|
528
|
-
if (isElementVisible(element) && excludes.indexOf(element) == -1) {
|
|
529
|
-
const id = nextId++;
|
|
530
|
-
elementMap[id.toString()] = element;
|
|
531
|
-
const tagName = element.tagName.toLowerCase();
|
|
532
|
-
const attributes = Array.from(element.attributes)
|
|
533
|
-
.filter((attr) => ['id', 'name', 'type', 'value', 'href', 'title', 'placeholder'].includes(attr.name))
|
|
534
|
-
.map((attr) => `${attr.name == 'id' ? 'target' : attr.name}="${attr.value}"`)
|
|
535
|
-
.join(' ');
|
|
536
|
-
elements.push({
|
|
537
|
-
originalIndex: getElementIndex(element),
|
|
538
|
-
id: id,
|
|
539
|
-
html: `<${tagName} id="${id}" ${attributes}>${tagName == 'select' ? element.innerHTML : element.innerText || ''}</${tagName}>`,
|
|
540
|
-
});
|
|
541
|
-
addExclude(excludes, element.children);
|
|
542
|
-
}
|
|
543
|
-
});
|
|
544
|
-
// short text element
|
|
545
|
-
const textWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
|
|
546
|
-
acceptNode: function (node) {
|
|
547
|
-
var _a;
|
|
548
|
-
if (node.matches(operableSelectors) || excludes.indexOf(node) != -1) {
|
|
549
|
-
// skip
|
|
550
|
-
return NodeFilter.FILTER_SKIP;
|
|
551
|
-
}
|
|
552
|
-
// text <= 100
|
|
553
|
-
const text = (_a = node.innerText) === null || _a === void 0 ? void 0 : _a.trim();
|
|
554
|
-
if (isElementVisible(node) &&
|
|
555
|
-
text &&
|
|
556
|
-
text.length <= 100 &&
|
|
557
|
-
text.length > 0 &&
|
|
558
|
-
node.children.length === 0) {
|
|
559
|
-
return NodeFilter.FILTER_ACCEPT;
|
|
560
|
-
}
|
|
561
|
-
// skip
|
|
562
|
-
return NodeFilter.FILTER_SKIP;
|
|
563
|
-
},
|
|
564
|
-
});
|
|
565
|
-
let currentNode;
|
|
566
|
-
while ((currentNode = textWalker.nextNode())) {
|
|
567
|
-
const id = nextId++;
|
|
568
|
-
elementMap[id.toString()] = currentNode;
|
|
569
|
-
const tagName = currentNode.tagName.toLowerCase();
|
|
570
|
-
elements.push({
|
|
571
|
-
originalIndex: getElementIndex(currentNode),
|
|
572
|
-
id: id,
|
|
573
|
-
html: `<${tagName} id="${id}">${currentNode.innerText.trim()}</${tagName}>`,
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
// element sort
|
|
577
|
-
elements.sort((a, b) => a.originalIndex - b.originalIndex);
|
|
578
|
-
// cache
|
|
579
|
-
window.operableElementMap = elementMap;
|
|
580
|
-
// pseudo html
|
|
581
|
-
return elements.map((e) => e.html).join('\n');
|
|
582
|
-
}
|
|
583
|
-
function clickOperableElement(id) {
|
|
584
|
-
let element = window.operableElementMap[id];
|
|
585
|
-
if (!element) {
|
|
586
|
-
return false;
|
|
587
|
-
}
|
|
588
|
-
if (element.click) {
|
|
589
|
-
element.click();
|
|
590
|
-
}
|
|
591
|
-
else {
|
|
592
|
-
element.dispatchEvent(new MouseEvent('click', {
|
|
593
|
-
view: window,
|
|
594
|
-
bubbles: true,
|
|
595
|
-
cancelable: true,
|
|
596
|
-
}));
|
|
597
|
-
}
|
|
598
|
-
return true;
|
|
599
|
-
}
|
|
600
|
-
function getOperableElementRect(id) {
|
|
601
|
-
let element = window.operableElementMap[id];
|
|
602
|
-
if (!element) {
|
|
603
|
-
return null;
|
|
604
|
-
}
|
|
605
|
-
const rect = element.getBoundingClientRect();
|
|
606
|
-
return {
|
|
607
|
-
left: rect.left + window.scrollX,
|
|
608
|
-
top: rect.top + window.scrollY,
|
|
609
|
-
right: rect.right + window.scrollX,
|
|
610
|
-
bottom: rect.bottom + window.scrollY,
|
|
611
|
-
width: rect.right - rect.left,
|
|
612
|
-
height: rect.bottom - rect.top,
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
|
|
616
616
|
/**
|
|
617
617
|
* Browser Use for general
|
|
618
618
|
*/
|
|
@@ -1183,24 +1183,6 @@ async function executeWithBrowserUse(context, task_prompt) {
|
|
|
1183
1183
|
};
|
|
1184
1184
|
}
|
|
1185
1185
|
|
|
1186
|
-
/**
|
|
1187
|
-
* Form Autofill
|
|
1188
|
-
*/
|
|
1189
|
-
class FormAutofill {
|
|
1190
|
-
constructor() {
|
|
1191
|
-
this.name = 'form_autofill';
|
|
1192
|
-
this.description = 'Automatically fill in form data on web pages';
|
|
1193
|
-
this.input_schema = {
|
|
1194
|
-
type: 'object',
|
|
1195
|
-
properties: {}
|
|
1196
|
-
};
|
|
1197
|
-
}
|
|
1198
|
-
async execute(context, params) {
|
|
1199
|
-
// form -> input, textarea, select ...
|
|
1200
|
-
throw new Error('Not implemented');
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
1186
|
/**
|
|
1205
1187
|
* Open Url
|
|
1206
1188
|
*/
|
|
@@ -1738,7 +1720,6 @@ var tools = /*#__PURE__*/Object.freeze({
|
|
|
1738
1720
|
ExportFile: ExportFile,
|
|
1739
1721
|
ExtractContent: ExtractContent,
|
|
1740
1722
|
FindElementPosition: FindElementPosition,
|
|
1741
|
-
FormAutofill: FormAutofill,
|
|
1742
1723
|
OpenUrl: OpenUrl,
|
|
1743
1724
|
Screenshot: Screenshot,
|
|
1744
1725
|
TabManagement: TabManagement,
|
package/dist/index.cjs.js
CHANGED
|
@@ -169,9 +169,10 @@ function createReturnTool(outputSchema) {
|
|
|
169
169
|
}
|
|
170
170
|
class ActionImpl {
|
|
171
171
|
constructor(type, // Only support prompt type
|
|
172
|
-
name, tools, llmProvider, llmConfig, config) {
|
|
172
|
+
name, description, tools, llmProvider, llmConfig, config) {
|
|
173
173
|
this.type = type;
|
|
174
174
|
this.name = name;
|
|
175
|
+
this.description = description;
|
|
175
176
|
this.tools = tools;
|
|
176
177
|
this.llmProvider = llmProvider;
|
|
177
178
|
this.llmConfig = llmConfig;
|
|
@@ -195,7 +196,6 @@ class ActionImpl {
|
|
|
195
196
|
const handler = {
|
|
196
197
|
onContent: (content) => {
|
|
197
198
|
if (content.trim()) {
|
|
198
|
-
console.log('LLM:', content);
|
|
199
199
|
assistantTextMessage += content;
|
|
200
200
|
}
|
|
201
201
|
},
|
|
@@ -313,12 +313,10 @@ class ActionImpl {
|
|
|
313
313
|
(_a = context.tools) === null || _a === void 0 ? void 0 : _a.forEach((tool) => toolMap.set(tool.name, tool));
|
|
314
314
|
toolMap.set(returnTool.name, returnTool);
|
|
315
315
|
// Prepare initial messages
|
|
316
|
-
const messages =
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
]
|
|
321
|
-
: [{ role: 'user', content: this.formatSystemPrompt(context) }];
|
|
316
|
+
const messages = [
|
|
317
|
+
{ role: 'system', content: this.formatSystemPrompt() },
|
|
318
|
+
{ role: 'user', content: this.formatUserPrompt(context, input) },
|
|
319
|
+
];
|
|
322
320
|
console.log('Starting LLM conversation...');
|
|
323
321
|
console.log('Initial messages:', messages);
|
|
324
322
|
console.log('Output schema:', outputSchema);
|
|
@@ -343,6 +341,7 @@ class ActionImpl {
|
|
|
343
341
|
if (!hasToolUse && response) {
|
|
344
342
|
// LLM sent a message without using tools - request explicit return
|
|
345
343
|
console.log('No tool use detected, requesting explicit return');
|
|
344
|
+
console.log('Response:', response);
|
|
346
345
|
const returnOnlyParams = {
|
|
347
346
|
...params,
|
|
348
347
|
tools: [
|
|
@@ -395,32 +394,30 @@ class ActionImpl {
|
|
|
395
394
|
}
|
|
396
395
|
return output;
|
|
397
396
|
}
|
|
398
|
-
formatSystemPrompt(
|
|
397
|
+
formatSystemPrompt() {
|
|
398
|
+
return `You are a task executor. You need to complete the task specified by the user, using the tools provided. When you need to store results or outputs, use the write_context tool. When you are ready to return the final output, use the return_output tool.
|
|
399
|
+
|
|
400
|
+
Remember to:
|
|
401
|
+
1. Use tools when needed to accomplish the task
|
|
402
|
+
2. Store important results using write_context, including intermediate and final results
|
|
403
|
+
3. Think step by step about what needs to be done`;
|
|
404
|
+
}
|
|
405
|
+
formatUserPrompt(context, input) {
|
|
399
406
|
// Create a description of the current context
|
|
400
407
|
const contextDescription = Array.from(context.variables.entries())
|
|
401
408
|
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
|
402
409
|
.join('\n');
|
|
403
|
-
return `You are executing the action "${this.name}". You have access to the following context:
|
|
404
|
-
|
|
405
|
-
${contextDescription || 'No context variables set'}
|
|
410
|
+
return `You are executing the action "${this.name}". The specific instructions are: "${this.description}". You have access to the following context:
|
|
406
411
|
|
|
407
|
-
|
|
408
|
-
use the write_context tool to save them to the workflow context.
|
|
412
|
+
${contextDescription || 'No context variables set'}
|
|
409
413
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
3. Think step by step about what needs to be done`;
|
|
414
|
-
}
|
|
415
|
-
formatUserPrompt(input) {
|
|
416
|
-
if (typeof input === 'string') {
|
|
417
|
-
return input;
|
|
418
|
-
}
|
|
419
|
-
return JSON.stringify(input, null, 2);
|
|
414
|
+
You have been provided with the following input:
|
|
415
|
+
${(typeof input === 'string' ? input : JSON.stringify(input, null, 2)) || 'No additional input provided'}
|
|
416
|
+
`;
|
|
420
417
|
}
|
|
421
418
|
// Static factory method
|
|
422
|
-
static createPromptAction(name, tools, llmProvider, llmConfig) {
|
|
423
|
-
return new ActionImpl('prompt', name, tools, llmProvider, llmConfig);
|
|
419
|
+
static createPromptAction(name, description, tools, llmProvider, llmConfig) {
|
|
420
|
+
return new ActionImpl('prompt', name, description, tools, llmProvider, llmConfig);
|
|
424
421
|
}
|
|
425
422
|
}
|
|
426
423
|
|
|
@@ -444,7 +441,8 @@ Generate a complete workflow that:
|
|
|
444
441
|
1. Only uses the tools listed above
|
|
445
442
|
2. Properly sequences tool usage based on dependencies
|
|
446
443
|
3. Ensures each action has appropriate input/output schemas
|
|
447
|
-
4. Creates a clear, logical flow to accomplish the user's goal
|
|
444
|
+
4. Creates a clear, logical flow to accomplish the user's goal
|
|
445
|
+
5. Includes detailed descriptions for each action, ensuring that the actions, when combined, is a complete solution to the user's problem`;
|
|
448
446
|
},
|
|
449
447
|
formatUserPrompt: (requirement) => `Create a workflow for the following requirement: ${requirement}`,
|
|
450
448
|
};
|
|
@@ -564,7 +562,7 @@ class WorkflowGenerator {
|
|
|
564
562
|
if (Array.isArray(data.nodes)) {
|
|
565
563
|
data.nodes.forEach((nodeData) => {
|
|
566
564
|
const tools = nodeData.action.tools.map((toolName) => this.toolRegistry.getTool(toolName));
|
|
567
|
-
const action = ActionImpl.createPromptAction(nodeData.action.name, tools, this.llmProvider, { maxTokens: 1000 });
|
|
565
|
+
const action = ActionImpl.createPromptAction(nodeData.action.name, nodeData.action.description, tools, this.llmProvider, { maxTokens: 1000 });
|
|
568
566
|
const node = {
|
|
569
567
|
id: nodeData.id,
|
|
570
568
|
name: nodeData.name || nodeData.id,
|
|
@@ -3286,16 +3284,21 @@ Anthropic.ModelInfosPage = ModelInfosPage;
|
|
|
3286
3284
|
Anthropic.Beta = Beta$1;
|
|
3287
3285
|
|
|
3288
3286
|
class ClaudeProvider {
|
|
3289
|
-
constructor(
|
|
3287
|
+
constructor(param, defaultModel, options) {
|
|
3290
3288
|
this.defaultModel = 'claude-3-5-sonnet-20241022';
|
|
3291
3289
|
if (defaultModel) {
|
|
3292
3290
|
this.defaultModel = defaultModel;
|
|
3293
3291
|
}
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3292
|
+
if (typeof param == 'string') {
|
|
3293
|
+
this.client = new Anthropic({
|
|
3294
|
+
apiKey: param,
|
|
3295
|
+
dangerouslyAllowBrowser: true,
|
|
3296
|
+
...options,
|
|
3297
|
+
});
|
|
3298
|
+
}
|
|
3299
|
+
else {
|
|
3300
|
+
this.client = new Anthropic(param);
|
|
3301
|
+
}
|
|
3299
3302
|
}
|
|
3300
3303
|
processResponse(response) {
|
|
3301
3304
|
const toolCalls = response.content
|
|
@@ -3389,7 +3392,7 @@ class ClaudeProvider {
|
|
|
3389
3392
|
const toolCall = {
|
|
3390
3393
|
id: currentToolUse.id,
|
|
3391
3394
|
name: currentToolUse.name,
|
|
3392
|
-
input: JSON.parse(currentToolUse.accumulatedJson),
|
|
3395
|
+
input: JSON.parse(currentToolUse.accumulatedJson || '{}'),
|
|
3393
3396
|
};
|
|
3394
3397
|
(_d = handler.onToolUse) === null || _d === void 0 ? void 0 : _d.call(handler, toolCall);
|
|
3395
3398
|
currentToolUse = null;
|
|
@@ -8688,16 +8691,21 @@ OpenAI.BatchesPage = BatchesPage;
|
|
|
8688
8691
|
OpenAI.Uploads = Uploads;
|
|
8689
8692
|
|
|
8690
8693
|
class OpenaiProvider {
|
|
8691
|
-
constructor(
|
|
8694
|
+
constructor(param, defaultModel, options) {
|
|
8692
8695
|
this.defaultModel = 'gpt-4o';
|
|
8693
8696
|
if (defaultModel) {
|
|
8694
8697
|
this.defaultModel = defaultModel;
|
|
8695
8698
|
}
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
8699
|
+
if (typeof param == 'string') {
|
|
8700
|
+
this.client = new OpenAI({
|
|
8701
|
+
apiKey: param,
|
|
8702
|
+
dangerouslyAllowBrowser: true,
|
|
8703
|
+
...options,
|
|
8704
|
+
});
|
|
8705
|
+
}
|
|
8706
|
+
else {
|
|
8707
|
+
this.client = new OpenAI(param);
|
|
8708
|
+
}
|
|
8701
8709
|
}
|
|
8702
8710
|
buildParams(messages, params, stream) {
|
|
8703
8711
|
let tools = undefined;
|
|
@@ -8975,7 +8983,7 @@ const workflowSchema = {
|
|
|
8975
8983
|
},
|
|
8976
8984
|
action: {
|
|
8977
8985
|
type: "object",
|
|
8978
|
-
required: ["type", "name"],
|
|
8986
|
+
required: ["type", "name", "description"],
|
|
8979
8987
|
properties: {
|
|
8980
8988
|
type: {
|
|
8981
8989
|
type: "string",
|
|
@@ -8983,6 +8991,7 @@ const workflowSchema = {
|
|
|
8983
8991
|
enum: ["prompt"],
|
|
8984
8992
|
},
|
|
8985
8993
|
name: { type: "string" },
|
|
8994
|
+
description: { type: "string" },
|
|
8986
8995
|
params: { type: "object" },
|
|
8987
8996
|
tools: {
|
|
8988
8997
|
type: "array",
|
|
@@ -9006,16 +9015,10 @@ class ToolRegistry {
|
|
|
9006
9015
|
this.tools = new Map();
|
|
9007
9016
|
}
|
|
9008
9017
|
registerTool(tool) {
|
|
9009
|
-
if (this.tools.has(tool.name)) {
|
|
9010
|
-
throw new Error(`Tool with name ${tool.name} already registered`);
|
|
9011
|
-
}
|
|
9012
9018
|
this.tools.set(tool.name, tool);
|
|
9013
9019
|
}
|
|
9014
9020
|
unregisterTool(toolName) {
|
|
9015
|
-
|
|
9016
|
-
throw new Error(`Tool with name ${toolName} not found`);
|
|
9017
|
-
}
|
|
9018
|
-
this.tools.delete(toolName);
|
|
9021
|
+
return this.tools.delete(toolName);
|
|
9019
9022
|
}
|
|
9020
9023
|
getTool(toolName) {
|
|
9021
9024
|
const tool = this.tools.get(toolName);
|
|
@@ -9081,6 +9084,7 @@ class Eko {
|
|
|
9081
9084
|
else {
|
|
9082
9085
|
this.llmProvider = config;
|
|
9083
9086
|
}
|
|
9087
|
+
Eko.tools.forEach((tool) => this.toolRegistry.registerTool(tool));
|
|
9084
9088
|
}
|
|
9085
9089
|
async generateWorkflow(prompt, param) {
|
|
9086
9090
|
let toolRegistry = this.toolRegistry;
|
|
@@ -9107,6 +9111,9 @@ class Eko {
|
|
|
9107
9111
|
if (this.toolRegistry.hasTools([toolName])) {
|
|
9108
9112
|
tool = this.toolRegistry.getTool(toolName);
|
|
9109
9113
|
}
|
|
9114
|
+
else if (Eko.tools.has(toolName)) {
|
|
9115
|
+
tool = Eko.tools.get(toolName);
|
|
9116
|
+
}
|
|
9110
9117
|
else {
|
|
9111
9118
|
throw new Error(`Tool with name ${toolName} not found`);
|
|
9112
9119
|
}
|
|
@@ -9135,6 +9142,7 @@ class Eko {
|
|
|
9135
9142
|
this.toolRegistry.unregisterTool(toolName);
|
|
9136
9143
|
}
|
|
9137
9144
|
}
|
|
9145
|
+
Eko.tools = new Map();
|
|
9138
9146
|
|
|
9139
9147
|
class WorkflowParser {
|
|
9140
9148
|
/**
|
|
@@ -9293,6 +9301,7 @@ class WorkflowParser {
|
|
|
9293
9301
|
action: {
|
|
9294
9302
|
type: nodeJson.action.type,
|
|
9295
9303
|
name: nodeJson.action.name,
|
|
9304
|
+
description: nodeJson.action.description,
|
|
9296
9305
|
tools: nodeJson.action.tools || [],
|
|
9297
9306
|
execute: async (input, context) => {
|
|
9298
9307
|
// Default implementation - should be overridden by specific action types
|
|
@@ -9323,6 +9332,7 @@ class WorkflowParser {
|
|
|
9323
9332
|
action: {
|
|
9324
9333
|
type: node.action.type,
|
|
9325
9334
|
name: node.action.name,
|
|
9335
|
+
description: node.action.description,
|
|
9326
9336
|
tools: node.action.tools,
|
|
9327
9337
|
},
|
|
9328
9338
|
})),
|