@eko-ai/eko 1.3.1 → 1.3.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/dist/common/context-compressor.d.ts +10 -0
- package/dist/extension.cjs.js +3 -2
- package/dist/extension.esm.js +3 -2
- package/dist/index.cjs.js +140 -63
- package/dist/index.esm.js +140 -63
- package/dist/schemas/workflow.schema.d.ts +1 -29
- package/dist/utils/sleep.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Message } from "@/types";
|
|
2
|
+
export declare abstract class ContextComporessor {
|
|
3
|
+
abstract comporess(messages: Message[]): Message[];
|
|
4
|
+
}
|
|
5
|
+
export declare class NoComporess extends ContextComporessor {
|
|
6
|
+
comporess(messages: Message[]): Message[];
|
|
7
|
+
}
|
|
8
|
+
export declare class SimpleQAComporess extends ContextComporessor {
|
|
9
|
+
comporess(messages: Message[]): Message[];
|
|
10
|
+
}
|
package/dist/extension.cjs.js
CHANGED
|
@@ -694,6 +694,7 @@ async function getTabId(context) {
|
|
|
694
694
|
tabId = await getCurrentTabId(context.ekoConfig.chromeProxy);
|
|
695
695
|
logger.debug("getCurrentTabId(context.ekoConfig.chromeProxy) #2 returns " + tabId);
|
|
696
696
|
}
|
|
697
|
+
logger.debug("tabId:", tabId);
|
|
697
698
|
if (!tabId) {
|
|
698
699
|
const fellouTabId = window.__FELLOU_TAB_ID__;
|
|
699
700
|
if (fellouTabId) {
|
|
@@ -721,7 +722,7 @@ function getCurrentTabId(chromeProxy, windowId) {
|
|
|
721
722
|
logger.debug(`get the active tabId on current window`);
|
|
722
723
|
queryInfo = { active: true, currentWindow: true };
|
|
723
724
|
}
|
|
724
|
-
|
|
725
|
+
chromeProxy.tabs.query(queryInfo, (tabs) => {
|
|
725
726
|
if (chromeProxy.runtime.lastError) {
|
|
726
727
|
logger.error(`failed to get: `, chromeProxy.runtime.lastError);
|
|
727
728
|
reject(chromeProxy.runtime.lastError);
|
|
@@ -2092,7 +2093,7 @@ class WebSearch {
|
|
|
2092
2093
|
let searchs = [{ url: url, keyword: query }];
|
|
2093
2094
|
let searchInfo = await deepSearch(context, taskId, searchs, maxResults || 5, context.ekoConfig.workingWindowId);
|
|
2094
2095
|
let links = ((_b = searchInfo.result[0]) === null || _b === void 0 ? void 0 : _b.links) || [];
|
|
2095
|
-
return links.filter((s) => s.content);
|
|
2096
|
+
return links.filter((s) => s.content.slice(0, 8000));
|
|
2096
2097
|
}
|
|
2097
2098
|
}
|
|
2098
2099
|
const deepSearchInjects = {
|
package/dist/extension.esm.js
CHANGED
|
@@ -692,6 +692,7 @@ async function getTabId(context) {
|
|
|
692
692
|
tabId = await getCurrentTabId(context.ekoConfig.chromeProxy);
|
|
693
693
|
logger.debug("getCurrentTabId(context.ekoConfig.chromeProxy) #2 returns " + tabId);
|
|
694
694
|
}
|
|
695
|
+
logger.debug("tabId:", tabId);
|
|
695
696
|
if (!tabId) {
|
|
696
697
|
const fellouTabId = window.__FELLOU_TAB_ID__;
|
|
697
698
|
if (fellouTabId) {
|
|
@@ -719,7 +720,7 @@ function getCurrentTabId(chromeProxy, windowId) {
|
|
|
719
720
|
logger.debug(`get the active tabId on current window`);
|
|
720
721
|
queryInfo = { active: true, currentWindow: true };
|
|
721
722
|
}
|
|
722
|
-
|
|
723
|
+
chromeProxy.tabs.query(queryInfo, (tabs) => {
|
|
723
724
|
if (chromeProxy.runtime.lastError) {
|
|
724
725
|
logger.error(`failed to get: `, chromeProxy.runtime.lastError);
|
|
725
726
|
reject(chromeProxy.runtime.lastError);
|
|
@@ -2090,7 +2091,7 @@ class WebSearch {
|
|
|
2090
2091
|
let searchs = [{ url: url, keyword: query }];
|
|
2091
2092
|
let searchInfo = await deepSearch(context, taskId, searchs, maxResults || 5, context.ekoConfig.workingWindowId);
|
|
2092
2093
|
let links = ((_b = searchInfo.result[0]) === null || _b === void 0 ? void 0 : _b.links) || [];
|
|
2093
|
-
return links.filter((s) => s.content);
|
|
2094
|
+
return links.filter((s) => s.content.slice(0, 8000));
|
|
2094
2095
|
}
|
|
2095
2096
|
}
|
|
2096
2097
|
const deepSearchInjects = {
|
package/dist/index.cjs.js
CHANGED
|
@@ -1140,7 +1140,7 @@ let APIClient$1 = class APIClient {
|
|
|
1140
1140
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
1141
1141
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
1142
1142
|
}
|
|
1143
|
-
await sleep$
|
|
1143
|
+
await sleep$2(timeoutMillis);
|
|
1144
1144
|
return this.makeRequest(options, retriesRemaining - 1);
|
|
1145
1145
|
}
|
|
1146
1146
|
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
@@ -1411,7 +1411,7 @@ const startsWithSchemeRegexp$1 = /^[a-z][a-z0-9+.-]*:/i;
|
|
|
1411
1411
|
const isAbsoluteURL$1 = (url) => {
|
|
1412
1412
|
return startsWithSchemeRegexp$1.test(url);
|
|
1413
1413
|
};
|
|
1414
|
-
const sleep$
|
|
1414
|
+
const sleep$2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1415
1415
|
const validatePositiveInteger$1 = (name, n) => {
|
|
1416
1416
|
if (typeof n !== 'number' || !Number.isInteger(n)) {
|
|
1417
1417
|
throw new AnthropicError(`${name} must be an integer`);
|
|
@@ -5102,7 +5102,7 @@ class APIClient {
|
|
|
5102
5102
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
5103
5103
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
5104
5104
|
}
|
|
5105
|
-
await sleep(timeoutMillis);
|
|
5105
|
+
await sleep$1(timeoutMillis);
|
|
5106
5106
|
return this.makeRequest(options, retriesRemaining - 1);
|
|
5107
5107
|
}
|
|
5108
5108
|
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
@@ -5374,7 +5374,7 @@ const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
|
|
|
5374
5374
|
const isAbsoluteURL = (url) => {
|
|
5375
5375
|
return startsWithSchemeRegexp.test(url);
|
|
5376
5376
|
};
|
|
5377
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
5377
|
+
const sleep$1 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
5378
5378
|
const validatePositiveInteger = (name, n) => {
|
|
5379
5379
|
if (typeof n !== 'number' || !Number.isInteger(n)) {
|
|
5380
5380
|
throw new OpenAIError(`${name} must be an integer`);
|
|
@@ -8056,7 +8056,7 @@ class Runs extends APIResource {
|
|
|
8056
8056
|
}
|
|
8057
8057
|
}
|
|
8058
8058
|
}
|
|
8059
|
-
await sleep(sleepInterval);
|
|
8059
|
+
await sleep$1(sleepInterval);
|
|
8060
8060
|
break;
|
|
8061
8061
|
//We return the run in any terminal state.
|
|
8062
8062
|
case 'requires_action':
|
|
@@ -8285,7 +8285,7 @@ let Files$1 = class Files extends APIResource {
|
|
|
8285
8285
|
const start = Date.now();
|
|
8286
8286
|
let file = await this.retrieve(id);
|
|
8287
8287
|
while (!file.status || !TERMINAL_STATES.has(file.status)) {
|
|
8288
|
-
await sleep(pollInterval);
|
|
8288
|
+
await sleep$1(pollInterval);
|
|
8289
8289
|
file = await this.retrieve(id);
|
|
8290
8290
|
if (Date.now() - start > maxWait) {
|
|
8291
8291
|
throw new APIConnectionTimeoutError({
|
|
@@ -9052,7 +9052,7 @@ class Files extends APIResource {
|
|
|
9052
9052
|
}
|
|
9053
9053
|
}
|
|
9054
9054
|
}
|
|
9055
|
-
await sleep(sleepInterval);
|
|
9055
|
+
await sleep$1(sleepInterval);
|
|
9056
9056
|
break;
|
|
9057
9057
|
case 'failed':
|
|
9058
9058
|
case 'completed':
|
|
@@ -9169,7 +9169,7 @@ class FileBatches extends APIResource {
|
|
|
9169
9169
|
}
|
|
9170
9170
|
}
|
|
9171
9171
|
}
|
|
9172
|
-
await sleep(sleepInterval);
|
|
9172
|
+
await sleep$1(sleepInterval);
|
|
9173
9173
|
break;
|
|
9174
9174
|
case 'failed':
|
|
9175
9175
|
case 'cancelled':
|
|
@@ -10238,6 +10238,84 @@ class WriteContextTool {
|
|
|
10238
10238
|
}
|
|
10239
10239
|
}
|
|
10240
10240
|
|
|
10241
|
+
class ContextComporessor {
|
|
10242
|
+
}
|
|
10243
|
+
class NoComporess extends ContextComporessor {
|
|
10244
|
+
comporess(messages) {
|
|
10245
|
+
logger.debug("ContextComporessor = NoComporess");
|
|
10246
|
+
let comporessed = JSON.parse(JSON.stringify(messages));
|
|
10247
|
+
logger.debug("comporessed:", comporessed);
|
|
10248
|
+
return comporessed;
|
|
10249
|
+
}
|
|
10250
|
+
}
|
|
10251
|
+
class SimpleQAComporess extends ContextComporessor {
|
|
10252
|
+
comporess(messages) {
|
|
10253
|
+
logger.debug("ContextComporessor = SimpleQAComporess");
|
|
10254
|
+
messages = JSON.parse(JSON.stringify(messages));
|
|
10255
|
+
let comporessed = [];
|
|
10256
|
+
const compress = (msg, idx) => {
|
|
10257
|
+
if (msg.role == "system") {
|
|
10258
|
+
return msg;
|
|
10259
|
+
}
|
|
10260
|
+
else if (msg.role == "assistant") {
|
|
10261
|
+
if (idx == messages.length - 2) {
|
|
10262
|
+
return msg;
|
|
10263
|
+
}
|
|
10264
|
+
else if (typeof msg.content == "string") {
|
|
10265
|
+
const nextMessage = messages[idx + 1];
|
|
10266
|
+
if (nextMessage.role == "assistant" && Array.isArray(nextMessage.content)) {
|
|
10267
|
+
return null;
|
|
10268
|
+
}
|
|
10269
|
+
else {
|
|
10270
|
+
return msg;
|
|
10271
|
+
}
|
|
10272
|
+
}
|
|
10273
|
+
else {
|
|
10274
|
+
const task = msg.content[0].input.userSidePrompt;
|
|
10275
|
+
const details = msg.content[0].input.thinking;
|
|
10276
|
+
return {
|
|
10277
|
+
"role": "assistant",
|
|
10278
|
+
"content": `<task>${task}</task><details>${details}</details>`,
|
|
10279
|
+
};
|
|
10280
|
+
}
|
|
10281
|
+
}
|
|
10282
|
+
else if (msg.role == "user" || typeof msg.content == "string") {
|
|
10283
|
+
if (idx == messages.length - 1 || idx == 1) {
|
|
10284
|
+
return msg;
|
|
10285
|
+
}
|
|
10286
|
+
else {
|
|
10287
|
+
let aiResponseMsg = messages[idx + 1];
|
|
10288
|
+
if (typeof aiResponseMsg.content == "string") {
|
|
10289
|
+
aiResponseMsg = messages[idx + 2];
|
|
10290
|
+
}
|
|
10291
|
+
const result = aiResponseMsg.content[0].input.observation;
|
|
10292
|
+
return {
|
|
10293
|
+
"role": "user",
|
|
10294
|
+
"content": `<result>${result}</result>`,
|
|
10295
|
+
};
|
|
10296
|
+
}
|
|
10297
|
+
}
|
|
10298
|
+
else {
|
|
10299
|
+
logger.warn("unknown message type, return null");
|
|
10300
|
+
return null;
|
|
10301
|
+
}
|
|
10302
|
+
};
|
|
10303
|
+
messages.forEach((msg, idx) => {
|
|
10304
|
+
logger.debug({ idx, msg });
|
|
10305
|
+
const compressedMsg = compress(msg, idx);
|
|
10306
|
+
logger.debug(compressedMsg);
|
|
10307
|
+
if (compressedMsg) {
|
|
10308
|
+
comporessed.push(compressedMsg);
|
|
10309
|
+
}
|
|
10310
|
+
});
|
|
10311
|
+
return comporessed;
|
|
10312
|
+
}
|
|
10313
|
+
}
|
|
10314
|
+
|
|
10315
|
+
function sleep(time) {
|
|
10316
|
+
return new Promise((resolve) => setTimeout(() => resolve(), time));
|
|
10317
|
+
}
|
|
10318
|
+
|
|
10241
10319
|
// src/models/action.ts
|
|
10242
10320
|
function createReturnTool(actionName, outputDescription, outputSchema) {
|
|
10243
10321
|
return {
|
|
@@ -10283,7 +10361,7 @@ class ActionImpl {
|
|
|
10283
10361
|
this.tools = tools;
|
|
10284
10362
|
this.llmProvider = llmProvider;
|
|
10285
10363
|
this.llmConfig = llmConfig;
|
|
10286
|
-
this.maxRounds =
|
|
10364
|
+
this.maxRounds = 25; // Default max rounds
|
|
10287
10365
|
this.toolResults = new Map();
|
|
10288
10366
|
this.logger = new ExecutionLogger();
|
|
10289
10367
|
this.tabs = [];
|
|
@@ -10300,6 +10378,7 @@ class ActionImpl {
|
|
|
10300
10378
|
let roundMessages = [];
|
|
10301
10379
|
let params_copy = JSON.parse(JSON.stringify(params));
|
|
10302
10380
|
params_copy.tools = (_a = params_copy.tools) === null || _a === void 0 ? void 0 : _a.map(this.wrapToolInputSchema);
|
|
10381
|
+
let retry_counter = 3;
|
|
10303
10382
|
while (!((_b = context.signal) === null || _b === void 0 ? void 0 : _b.aborted)) {
|
|
10304
10383
|
roundMessages = [];
|
|
10305
10384
|
hasToolUse = false;
|
|
@@ -10395,7 +10474,7 @@ class ActionImpl {
|
|
|
10395
10474
|
// unwrap the toolCall
|
|
10396
10475
|
let unwrapped = this.unwrapToolCall(toolCall);
|
|
10397
10476
|
let input = unwrapped.toolCall.input;
|
|
10398
|
-
logger.
|
|
10477
|
+
logger.info("LLM Response:", unwrapped);
|
|
10399
10478
|
if (unwrapped.thinking) {
|
|
10400
10479
|
(_d = (_b = context.callback) === null || _b === void 0 ? void 0 : (_c = _b.hooks).onLlmMessage) === null || _d === void 0 ? void 0 : _d.call(_c, unwrapped.thinking);
|
|
10401
10480
|
}
|
|
@@ -10499,11 +10578,43 @@ class ActionImpl {
|
|
|
10499
10578
|
throw new Error('LLM provider not set');
|
|
10500
10579
|
}
|
|
10501
10580
|
try {
|
|
10502
|
-
|
|
10581
|
+
let compressedMessages;
|
|
10582
|
+
try {
|
|
10583
|
+
const comporessor = new SimpleQAComporess();
|
|
10584
|
+
logger.debug("uncompressed messages:", messages);
|
|
10585
|
+
compressedMessages = comporessor.comporess(messages);
|
|
10586
|
+
}
|
|
10587
|
+
catch (e) {
|
|
10588
|
+
logger.error("an error occurs when comporess context, use NoComporess");
|
|
10589
|
+
logger.error(e);
|
|
10590
|
+
const comporessor = new NoComporess();
|
|
10591
|
+
compressedMessages = comporessor.comporess(messages);
|
|
10592
|
+
}
|
|
10593
|
+
logger.debug("compressed messages:", compressedMessages);
|
|
10594
|
+
await sleep(5000);
|
|
10595
|
+
try {
|
|
10596
|
+
await this.llmProvider.generateStream(compressedMessages, params_copy, handler);
|
|
10597
|
+
}
|
|
10598
|
+
catch (e) {
|
|
10599
|
+
logger.warn("LLM API raise an error, try to use NoComporess");
|
|
10600
|
+
const comporessor = new NoComporess();
|
|
10601
|
+
compressedMessages = comporessor.comporess(messages);
|
|
10602
|
+
logger.debug("compressed messages:", compressedMessages);
|
|
10603
|
+
await sleep(5000);
|
|
10604
|
+
await this.llmProvider.generateStream(compressedMessages, params_copy, handler);
|
|
10605
|
+
}
|
|
10503
10606
|
}
|
|
10504
10607
|
catch (e) {
|
|
10505
|
-
logger.warn(
|
|
10506
|
-
|
|
10608
|
+
logger.warn(`an error occurs when LLM generate response, retry(n=${retry_counter})...`, e);
|
|
10609
|
+
await sleep(3000);
|
|
10610
|
+
retry_counter -= 1;
|
|
10611
|
+
if (retry_counter > 0) {
|
|
10612
|
+
continue;
|
|
10613
|
+
}
|
|
10614
|
+
else {
|
|
10615
|
+
logger.error("too many errors when calling LLM API in executing");
|
|
10616
|
+
throw e;
|
|
10617
|
+
}
|
|
10507
10618
|
}
|
|
10508
10619
|
// Wait for tool execution to complete if it was started
|
|
10509
10620
|
if (toolExecutionPromise) {
|
|
@@ -10585,9 +10696,11 @@ class ActionImpl {
|
|
|
10585
10696
|
toolMap.set(returnTool.name, returnTool);
|
|
10586
10697
|
// get already existing tabs as task background
|
|
10587
10698
|
const currentWindow = await context.ekoConfig.chromeProxy.windows.getCurrent();
|
|
10588
|
-
|
|
10699
|
+
let existingTabs = await context.ekoConfig.chromeProxy.tabs.query({
|
|
10589
10700
|
windowId: currentWindow.id,
|
|
10590
10701
|
});
|
|
10702
|
+
existingTabs = existingTabs.filter((tab) => { tab.title && tab.url; });
|
|
10703
|
+
logger.debug("existingTabs:", existingTabs);
|
|
10591
10704
|
// get patchs for task
|
|
10592
10705
|
let patchs = [];
|
|
10593
10706
|
if (context.ekoConfig.patchServerUrl) {
|
|
@@ -10825,22 +10938,9 @@ Navigation Bar or Menu Changes: After logging in, the navigation bar will includ
|
|
|
10825
10938
|
definition.input_schema = {
|
|
10826
10939
|
type: "object",
|
|
10827
10940
|
properties: {
|
|
10828
|
-
|
|
10829
|
-
// observation: {
|
|
10830
|
-
// "type": "string",
|
|
10831
|
-
// "description": 'Your observation of the previous steps. Should start with "In the previous step, I\'ve ...".',
|
|
10832
|
-
// },
|
|
10833
|
-
evaluate_previous_goal: {
|
|
10834
|
-
"type": "string",
|
|
10835
|
-
"description": "Success|Failed|Unknown - Analyze the current elements and the image to check if the previous goals/actions are successful like intended by the task. Mention if something unexpected happened. Shortly state why/why not"
|
|
10836
|
-
},
|
|
10837
|
-
memory: {
|
|
10838
|
-
"type": "string",
|
|
10839
|
-
"description": "Description of what has been done and what you need to remember. Be very specific. Count here ALWAYS how many times you have done something and how many remain. E.g. 0 out of 10 websites analyzed. Continue with abc and xyz",
|
|
10840
|
-
},
|
|
10841
|
-
next_goal: {
|
|
10941
|
+
observation: {
|
|
10842
10942
|
"type": "string",
|
|
10843
|
-
"description":
|
|
10943
|
+
"description": 'Your observation of the previous steps. Should start with "In the previous step, I\'ve ...".',
|
|
10844
10944
|
},
|
|
10845
10945
|
thinking: {
|
|
10846
10946
|
"type": "string",
|
|
@@ -10854,12 +10954,9 @@ Navigation Bar or Menu Changes: After logging in, the navigation bar will includ
|
|
|
10854
10954
|
},
|
|
10855
10955
|
required: [
|
|
10856
10956
|
// comment for backup
|
|
10857
|
-
|
|
10957
|
+
"observation",
|
|
10858
10958
|
"thinking",
|
|
10859
10959
|
"userSidePrompt",
|
|
10860
|
-
"memory",
|
|
10861
|
-
"next_goal",
|
|
10862
|
-
"evaluate_previous_goal",
|
|
10863
10960
|
"toolCall",
|
|
10864
10961
|
],
|
|
10865
10962
|
};
|
|
@@ -10870,15 +10967,15 @@ Navigation Bar or Menu Changes: After logging in, the navigation bar will includ
|
|
|
10870
10967
|
observation: toolCall.input.observation,
|
|
10871
10968
|
thinking: toolCall.input.thinking,
|
|
10872
10969
|
userSidePrompt: toolCall.input.userSidePrompt,
|
|
10873
|
-
evaluate_previous_goal: toolCall.input.evaluate_previous_goal,
|
|
10874
|
-
memory: toolCall.input.memory,
|
|
10875
|
-
next_goal: toolCall.input.next_goal,
|
|
10876
10970
|
toolCall: {
|
|
10877
10971
|
id: toolCall.id,
|
|
10878
10972
|
name: toolCall.name,
|
|
10879
10973
|
input: toolCall.input.toolCall,
|
|
10880
10974
|
},
|
|
10881
10975
|
};
|
|
10976
|
+
if (!toolCall.input.toolCall) {
|
|
10977
|
+
logger.error("LLM returned a broken function call:", toolCall);
|
|
10978
|
+
}
|
|
10882
10979
|
return result;
|
|
10883
10980
|
}
|
|
10884
10981
|
}
|
|
@@ -10989,6 +11086,7 @@ class WorkflowGenerator {
|
|
|
10989
11086
|
catch (e) {
|
|
10990
11087
|
logger.warn("an error occured when generating workflow:", e);
|
|
10991
11088
|
logger.info(`retry...${retry_counter}`);
|
|
11089
|
+
await sleep(3000);
|
|
10992
11090
|
retry_counter -= 1;
|
|
10993
11091
|
}
|
|
10994
11092
|
}
|
|
@@ -11063,44 +11161,23 @@ const workflowSchema = {
|
|
|
11063
11161
|
type: "array",
|
|
11064
11162
|
items: {
|
|
11065
11163
|
type: "object",
|
|
11066
|
-
required: ["id", "
|
|
11164
|
+
required: ["id", "action"],
|
|
11067
11165
|
properties: {
|
|
11068
11166
|
id: { type: "string" },
|
|
11069
|
-
type: {
|
|
11070
|
-
type: "string",
|
|
11071
|
-
enum: ["action"], // only action nodes for now; reserved for future types like condition, loop, etc.
|
|
11072
|
-
},
|
|
11073
|
-
dependencies: {
|
|
11074
|
-
type: "array",
|
|
11075
|
-
items: { type: "string" },
|
|
11076
|
-
},
|
|
11077
|
-
output: {
|
|
11078
|
-
type: "object",
|
|
11079
|
-
properties: {
|
|
11080
|
-
name: { type: "string" },
|
|
11081
|
-
description: { type: "string" },
|
|
11082
|
-
},
|
|
11083
|
-
},
|
|
11084
11167
|
action: {
|
|
11085
11168
|
type: "object",
|
|
11086
|
-
required: ["
|
|
11169
|
+
required: ["name", "description"],
|
|
11087
11170
|
properties: {
|
|
11088
|
-
type:
|
|
11171
|
+
name: { type: "string" },
|
|
11172
|
+
description: {
|
|
11089
11173
|
type: "string",
|
|
11090
|
-
|
|
11091
|
-
enum: ["prompt"],
|
|
11174
|
+
description: "Note that do not use \" mark.",
|
|
11092
11175
|
},
|
|
11093
|
-
name: { type: "string" },
|
|
11094
|
-
description: { type: "string" },
|
|
11095
11176
|
},
|
|
11096
11177
|
},
|
|
11097
11178
|
},
|
|
11098
11179
|
},
|
|
11099
11180
|
},
|
|
11100
|
-
variables: {
|
|
11101
|
-
type: "object",
|
|
11102
|
-
additionalProperties: true,
|
|
11103
|
-
},
|
|
11104
11181
|
},
|
|
11105
11182
|
};
|
|
11106
11183
|
|
|
@@ -11163,7 +11240,7 @@ class Eko {
|
|
|
11163
11240
|
this.llmProvider = LLMProviderFactory.buildLLMProvider(llmConfig);
|
|
11164
11241
|
this.ekoConfig = this.buildEkoConfig(ekoConfig);
|
|
11165
11242
|
this.registerTools();
|
|
11166
|
-
logger.info("using Eko@" + "
|
|
11243
|
+
logger.info("using Eko@" + "8aef68f294c16840224e6656e0a04a2b87b4ac96");
|
|
11167
11244
|
logger.debug("caller's ekoConfig:", ekoConfig);
|
|
11168
11245
|
}
|
|
11169
11246
|
static getLogger() {
|
package/dist/index.esm.js
CHANGED
|
@@ -1136,7 +1136,7 @@ let APIClient$1 = class APIClient {
|
|
|
1136
1136
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
1137
1137
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
1138
1138
|
}
|
|
1139
|
-
await sleep$
|
|
1139
|
+
await sleep$2(timeoutMillis);
|
|
1140
1140
|
return this.makeRequest(options, retriesRemaining - 1);
|
|
1141
1141
|
}
|
|
1142
1142
|
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
@@ -1407,7 +1407,7 @@ const startsWithSchemeRegexp$1 = /^[a-z][a-z0-9+.-]*:/i;
|
|
|
1407
1407
|
const isAbsoluteURL$1 = (url) => {
|
|
1408
1408
|
return startsWithSchemeRegexp$1.test(url);
|
|
1409
1409
|
};
|
|
1410
|
-
const sleep$
|
|
1410
|
+
const sleep$2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1411
1411
|
const validatePositiveInteger$1 = (name, n) => {
|
|
1412
1412
|
if (typeof n !== 'number' || !Number.isInteger(n)) {
|
|
1413
1413
|
throw new AnthropicError(`${name} must be an integer`);
|
|
@@ -5098,7 +5098,7 @@ class APIClient {
|
|
|
5098
5098
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
5099
5099
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
5100
5100
|
}
|
|
5101
|
-
await sleep(timeoutMillis);
|
|
5101
|
+
await sleep$1(timeoutMillis);
|
|
5102
5102
|
return this.makeRequest(options, retriesRemaining - 1);
|
|
5103
5103
|
}
|
|
5104
5104
|
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
@@ -5370,7 +5370,7 @@ const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
|
|
|
5370
5370
|
const isAbsoluteURL = (url) => {
|
|
5371
5371
|
return startsWithSchemeRegexp.test(url);
|
|
5372
5372
|
};
|
|
5373
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
5373
|
+
const sleep$1 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
5374
5374
|
const validatePositiveInteger = (name, n) => {
|
|
5375
5375
|
if (typeof n !== 'number' || !Number.isInteger(n)) {
|
|
5376
5376
|
throw new OpenAIError(`${name} must be an integer`);
|
|
@@ -8052,7 +8052,7 @@ class Runs extends APIResource {
|
|
|
8052
8052
|
}
|
|
8053
8053
|
}
|
|
8054
8054
|
}
|
|
8055
|
-
await sleep(sleepInterval);
|
|
8055
|
+
await sleep$1(sleepInterval);
|
|
8056
8056
|
break;
|
|
8057
8057
|
//We return the run in any terminal state.
|
|
8058
8058
|
case 'requires_action':
|
|
@@ -8281,7 +8281,7 @@ let Files$1 = class Files extends APIResource {
|
|
|
8281
8281
|
const start = Date.now();
|
|
8282
8282
|
let file = await this.retrieve(id);
|
|
8283
8283
|
while (!file.status || !TERMINAL_STATES.has(file.status)) {
|
|
8284
|
-
await sleep(pollInterval);
|
|
8284
|
+
await sleep$1(pollInterval);
|
|
8285
8285
|
file = await this.retrieve(id);
|
|
8286
8286
|
if (Date.now() - start > maxWait) {
|
|
8287
8287
|
throw new APIConnectionTimeoutError({
|
|
@@ -9048,7 +9048,7 @@ class Files extends APIResource {
|
|
|
9048
9048
|
}
|
|
9049
9049
|
}
|
|
9050
9050
|
}
|
|
9051
|
-
await sleep(sleepInterval);
|
|
9051
|
+
await sleep$1(sleepInterval);
|
|
9052
9052
|
break;
|
|
9053
9053
|
case 'failed':
|
|
9054
9054
|
case 'completed':
|
|
@@ -9165,7 +9165,7 @@ class FileBatches extends APIResource {
|
|
|
9165
9165
|
}
|
|
9166
9166
|
}
|
|
9167
9167
|
}
|
|
9168
|
-
await sleep(sleepInterval);
|
|
9168
|
+
await sleep$1(sleepInterval);
|
|
9169
9169
|
break;
|
|
9170
9170
|
case 'failed':
|
|
9171
9171
|
case 'cancelled':
|
|
@@ -10234,6 +10234,84 @@ class WriteContextTool {
|
|
|
10234
10234
|
}
|
|
10235
10235
|
}
|
|
10236
10236
|
|
|
10237
|
+
class ContextComporessor {
|
|
10238
|
+
}
|
|
10239
|
+
class NoComporess extends ContextComporessor {
|
|
10240
|
+
comporess(messages) {
|
|
10241
|
+
logger.debug("ContextComporessor = NoComporess");
|
|
10242
|
+
let comporessed = JSON.parse(JSON.stringify(messages));
|
|
10243
|
+
logger.debug("comporessed:", comporessed);
|
|
10244
|
+
return comporessed;
|
|
10245
|
+
}
|
|
10246
|
+
}
|
|
10247
|
+
class SimpleQAComporess extends ContextComporessor {
|
|
10248
|
+
comporess(messages) {
|
|
10249
|
+
logger.debug("ContextComporessor = SimpleQAComporess");
|
|
10250
|
+
messages = JSON.parse(JSON.stringify(messages));
|
|
10251
|
+
let comporessed = [];
|
|
10252
|
+
const compress = (msg, idx) => {
|
|
10253
|
+
if (msg.role == "system") {
|
|
10254
|
+
return msg;
|
|
10255
|
+
}
|
|
10256
|
+
else if (msg.role == "assistant") {
|
|
10257
|
+
if (idx == messages.length - 2) {
|
|
10258
|
+
return msg;
|
|
10259
|
+
}
|
|
10260
|
+
else if (typeof msg.content == "string") {
|
|
10261
|
+
const nextMessage = messages[idx + 1];
|
|
10262
|
+
if (nextMessage.role == "assistant" && Array.isArray(nextMessage.content)) {
|
|
10263
|
+
return null;
|
|
10264
|
+
}
|
|
10265
|
+
else {
|
|
10266
|
+
return msg;
|
|
10267
|
+
}
|
|
10268
|
+
}
|
|
10269
|
+
else {
|
|
10270
|
+
const task = msg.content[0].input.userSidePrompt;
|
|
10271
|
+
const details = msg.content[0].input.thinking;
|
|
10272
|
+
return {
|
|
10273
|
+
"role": "assistant",
|
|
10274
|
+
"content": `<task>${task}</task><details>${details}</details>`,
|
|
10275
|
+
};
|
|
10276
|
+
}
|
|
10277
|
+
}
|
|
10278
|
+
else if (msg.role == "user" || typeof msg.content == "string") {
|
|
10279
|
+
if (idx == messages.length - 1 || idx == 1) {
|
|
10280
|
+
return msg;
|
|
10281
|
+
}
|
|
10282
|
+
else {
|
|
10283
|
+
let aiResponseMsg = messages[idx + 1];
|
|
10284
|
+
if (typeof aiResponseMsg.content == "string") {
|
|
10285
|
+
aiResponseMsg = messages[idx + 2];
|
|
10286
|
+
}
|
|
10287
|
+
const result = aiResponseMsg.content[0].input.observation;
|
|
10288
|
+
return {
|
|
10289
|
+
"role": "user",
|
|
10290
|
+
"content": `<result>${result}</result>`,
|
|
10291
|
+
};
|
|
10292
|
+
}
|
|
10293
|
+
}
|
|
10294
|
+
else {
|
|
10295
|
+
logger.warn("unknown message type, return null");
|
|
10296
|
+
return null;
|
|
10297
|
+
}
|
|
10298
|
+
};
|
|
10299
|
+
messages.forEach((msg, idx) => {
|
|
10300
|
+
logger.debug({ idx, msg });
|
|
10301
|
+
const compressedMsg = compress(msg, idx);
|
|
10302
|
+
logger.debug(compressedMsg);
|
|
10303
|
+
if (compressedMsg) {
|
|
10304
|
+
comporessed.push(compressedMsg);
|
|
10305
|
+
}
|
|
10306
|
+
});
|
|
10307
|
+
return comporessed;
|
|
10308
|
+
}
|
|
10309
|
+
}
|
|
10310
|
+
|
|
10311
|
+
function sleep(time) {
|
|
10312
|
+
return new Promise((resolve) => setTimeout(() => resolve(), time));
|
|
10313
|
+
}
|
|
10314
|
+
|
|
10237
10315
|
// src/models/action.ts
|
|
10238
10316
|
function createReturnTool(actionName, outputDescription, outputSchema) {
|
|
10239
10317
|
return {
|
|
@@ -10279,7 +10357,7 @@ class ActionImpl {
|
|
|
10279
10357
|
this.tools = tools;
|
|
10280
10358
|
this.llmProvider = llmProvider;
|
|
10281
10359
|
this.llmConfig = llmConfig;
|
|
10282
|
-
this.maxRounds =
|
|
10360
|
+
this.maxRounds = 25; // Default max rounds
|
|
10283
10361
|
this.toolResults = new Map();
|
|
10284
10362
|
this.logger = new ExecutionLogger();
|
|
10285
10363
|
this.tabs = [];
|
|
@@ -10296,6 +10374,7 @@ class ActionImpl {
|
|
|
10296
10374
|
let roundMessages = [];
|
|
10297
10375
|
let params_copy = JSON.parse(JSON.stringify(params));
|
|
10298
10376
|
params_copy.tools = (_a = params_copy.tools) === null || _a === void 0 ? void 0 : _a.map(this.wrapToolInputSchema);
|
|
10377
|
+
let retry_counter = 3;
|
|
10299
10378
|
while (!((_b = context.signal) === null || _b === void 0 ? void 0 : _b.aborted)) {
|
|
10300
10379
|
roundMessages = [];
|
|
10301
10380
|
hasToolUse = false;
|
|
@@ -10391,7 +10470,7 @@ class ActionImpl {
|
|
|
10391
10470
|
// unwrap the toolCall
|
|
10392
10471
|
let unwrapped = this.unwrapToolCall(toolCall);
|
|
10393
10472
|
let input = unwrapped.toolCall.input;
|
|
10394
|
-
logger.
|
|
10473
|
+
logger.info("LLM Response:", unwrapped);
|
|
10395
10474
|
if (unwrapped.thinking) {
|
|
10396
10475
|
(_d = (_b = context.callback) === null || _b === void 0 ? void 0 : (_c = _b.hooks).onLlmMessage) === null || _d === void 0 ? void 0 : _d.call(_c, unwrapped.thinking);
|
|
10397
10476
|
}
|
|
@@ -10495,11 +10574,43 @@ class ActionImpl {
|
|
|
10495
10574
|
throw new Error('LLM provider not set');
|
|
10496
10575
|
}
|
|
10497
10576
|
try {
|
|
10498
|
-
|
|
10577
|
+
let compressedMessages;
|
|
10578
|
+
try {
|
|
10579
|
+
const comporessor = new SimpleQAComporess();
|
|
10580
|
+
logger.debug("uncompressed messages:", messages);
|
|
10581
|
+
compressedMessages = comporessor.comporess(messages);
|
|
10582
|
+
}
|
|
10583
|
+
catch (e) {
|
|
10584
|
+
logger.error("an error occurs when comporess context, use NoComporess");
|
|
10585
|
+
logger.error(e);
|
|
10586
|
+
const comporessor = new NoComporess();
|
|
10587
|
+
compressedMessages = comporessor.comporess(messages);
|
|
10588
|
+
}
|
|
10589
|
+
logger.debug("compressed messages:", compressedMessages);
|
|
10590
|
+
await sleep(5000);
|
|
10591
|
+
try {
|
|
10592
|
+
await this.llmProvider.generateStream(compressedMessages, params_copy, handler);
|
|
10593
|
+
}
|
|
10594
|
+
catch (e) {
|
|
10595
|
+
logger.warn("LLM API raise an error, try to use NoComporess");
|
|
10596
|
+
const comporessor = new NoComporess();
|
|
10597
|
+
compressedMessages = comporessor.comporess(messages);
|
|
10598
|
+
logger.debug("compressed messages:", compressedMessages);
|
|
10599
|
+
await sleep(5000);
|
|
10600
|
+
await this.llmProvider.generateStream(compressedMessages, params_copy, handler);
|
|
10601
|
+
}
|
|
10499
10602
|
}
|
|
10500
10603
|
catch (e) {
|
|
10501
|
-
logger.warn(
|
|
10502
|
-
|
|
10604
|
+
logger.warn(`an error occurs when LLM generate response, retry(n=${retry_counter})...`, e);
|
|
10605
|
+
await sleep(3000);
|
|
10606
|
+
retry_counter -= 1;
|
|
10607
|
+
if (retry_counter > 0) {
|
|
10608
|
+
continue;
|
|
10609
|
+
}
|
|
10610
|
+
else {
|
|
10611
|
+
logger.error("too many errors when calling LLM API in executing");
|
|
10612
|
+
throw e;
|
|
10613
|
+
}
|
|
10503
10614
|
}
|
|
10504
10615
|
// Wait for tool execution to complete if it was started
|
|
10505
10616
|
if (toolExecutionPromise) {
|
|
@@ -10581,9 +10692,11 @@ class ActionImpl {
|
|
|
10581
10692
|
toolMap.set(returnTool.name, returnTool);
|
|
10582
10693
|
// get already existing tabs as task background
|
|
10583
10694
|
const currentWindow = await context.ekoConfig.chromeProxy.windows.getCurrent();
|
|
10584
|
-
|
|
10695
|
+
let existingTabs = await context.ekoConfig.chromeProxy.tabs.query({
|
|
10585
10696
|
windowId: currentWindow.id,
|
|
10586
10697
|
});
|
|
10698
|
+
existingTabs = existingTabs.filter((tab) => { tab.title && tab.url; });
|
|
10699
|
+
logger.debug("existingTabs:", existingTabs);
|
|
10587
10700
|
// get patchs for task
|
|
10588
10701
|
let patchs = [];
|
|
10589
10702
|
if (context.ekoConfig.patchServerUrl) {
|
|
@@ -10821,22 +10934,9 @@ Navigation Bar or Menu Changes: After logging in, the navigation bar will includ
|
|
|
10821
10934
|
definition.input_schema = {
|
|
10822
10935
|
type: "object",
|
|
10823
10936
|
properties: {
|
|
10824
|
-
|
|
10825
|
-
// observation: {
|
|
10826
|
-
// "type": "string",
|
|
10827
|
-
// "description": 'Your observation of the previous steps. Should start with "In the previous step, I\'ve ...".',
|
|
10828
|
-
// },
|
|
10829
|
-
evaluate_previous_goal: {
|
|
10830
|
-
"type": "string",
|
|
10831
|
-
"description": "Success|Failed|Unknown - Analyze the current elements and the image to check if the previous goals/actions are successful like intended by the task. Mention if something unexpected happened. Shortly state why/why not"
|
|
10832
|
-
},
|
|
10833
|
-
memory: {
|
|
10834
|
-
"type": "string",
|
|
10835
|
-
"description": "Description of what has been done and what you need to remember. Be very specific. Count here ALWAYS how many times you have done something and how many remain. E.g. 0 out of 10 websites analyzed. Continue with abc and xyz",
|
|
10836
|
-
},
|
|
10837
|
-
next_goal: {
|
|
10937
|
+
observation: {
|
|
10838
10938
|
"type": "string",
|
|
10839
|
-
"description":
|
|
10939
|
+
"description": 'Your observation of the previous steps. Should start with "In the previous step, I\'ve ...".',
|
|
10840
10940
|
},
|
|
10841
10941
|
thinking: {
|
|
10842
10942
|
"type": "string",
|
|
@@ -10850,12 +10950,9 @@ Navigation Bar or Menu Changes: After logging in, the navigation bar will includ
|
|
|
10850
10950
|
},
|
|
10851
10951
|
required: [
|
|
10852
10952
|
// comment for backup
|
|
10853
|
-
|
|
10953
|
+
"observation",
|
|
10854
10954
|
"thinking",
|
|
10855
10955
|
"userSidePrompt",
|
|
10856
|
-
"memory",
|
|
10857
|
-
"next_goal",
|
|
10858
|
-
"evaluate_previous_goal",
|
|
10859
10956
|
"toolCall",
|
|
10860
10957
|
],
|
|
10861
10958
|
};
|
|
@@ -10866,15 +10963,15 @@ Navigation Bar or Menu Changes: After logging in, the navigation bar will includ
|
|
|
10866
10963
|
observation: toolCall.input.observation,
|
|
10867
10964
|
thinking: toolCall.input.thinking,
|
|
10868
10965
|
userSidePrompt: toolCall.input.userSidePrompt,
|
|
10869
|
-
evaluate_previous_goal: toolCall.input.evaluate_previous_goal,
|
|
10870
|
-
memory: toolCall.input.memory,
|
|
10871
|
-
next_goal: toolCall.input.next_goal,
|
|
10872
10966
|
toolCall: {
|
|
10873
10967
|
id: toolCall.id,
|
|
10874
10968
|
name: toolCall.name,
|
|
10875
10969
|
input: toolCall.input.toolCall,
|
|
10876
10970
|
},
|
|
10877
10971
|
};
|
|
10972
|
+
if (!toolCall.input.toolCall) {
|
|
10973
|
+
logger.error("LLM returned a broken function call:", toolCall);
|
|
10974
|
+
}
|
|
10878
10975
|
return result;
|
|
10879
10976
|
}
|
|
10880
10977
|
}
|
|
@@ -10985,6 +11082,7 @@ class WorkflowGenerator {
|
|
|
10985
11082
|
catch (e) {
|
|
10986
11083
|
logger.warn("an error occured when generating workflow:", e);
|
|
10987
11084
|
logger.info(`retry...${retry_counter}`);
|
|
11085
|
+
await sleep(3000);
|
|
10988
11086
|
retry_counter -= 1;
|
|
10989
11087
|
}
|
|
10990
11088
|
}
|
|
@@ -11059,44 +11157,23 @@ const workflowSchema = {
|
|
|
11059
11157
|
type: "array",
|
|
11060
11158
|
items: {
|
|
11061
11159
|
type: "object",
|
|
11062
|
-
required: ["id", "
|
|
11160
|
+
required: ["id", "action"],
|
|
11063
11161
|
properties: {
|
|
11064
11162
|
id: { type: "string" },
|
|
11065
|
-
type: {
|
|
11066
|
-
type: "string",
|
|
11067
|
-
enum: ["action"], // only action nodes for now; reserved for future types like condition, loop, etc.
|
|
11068
|
-
},
|
|
11069
|
-
dependencies: {
|
|
11070
|
-
type: "array",
|
|
11071
|
-
items: { type: "string" },
|
|
11072
|
-
},
|
|
11073
|
-
output: {
|
|
11074
|
-
type: "object",
|
|
11075
|
-
properties: {
|
|
11076
|
-
name: { type: "string" },
|
|
11077
|
-
description: { type: "string" },
|
|
11078
|
-
},
|
|
11079
|
-
},
|
|
11080
11163
|
action: {
|
|
11081
11164
|
type: "object",
|
|
11082
|
-
required: ["
|
|
11165
|
+
required: ["name", "description"],
|
|
11083
11166
|
properties: {
|
|
11084
|
-
type:
|
|
11167
|
+
name: { type: "string" },
|
|
11168
|
+
description: {
|
|
11085
11169
|
type: "string",
|
|
11086
|
-
|
|
11087
|
-
enum: ["prompt"],
|
|
11170
|
+
description: "Note that do not use \" mark.",
|
|
11088
11171
|
},
|
|
11089
|
-
name: { type: "string" },
|
|
11090
|
-
description: { type: "string" },
|
|
11091
11172
|
},
|
|
11092
11173
|
},
|
|
11093
11174
|
},
|
|
11094
11175
|
},
|
|
11095
11176
|
},
|
|
11096
|
-
variables: {
|
|
11097
|
-
type: "object",
|
|
11098
|
-
additionalProperties: true,
|
|
11099
|
-
},
|
|
11100
11177
|
},
|
|
11101
11178
|
};
|
|
11102
11179
|
|
|
@@ -11159,7 +11236,7 @@ class Eko {
|
|
|
11159
11236
|
this.llmProvider = LLMProviderFactory.buildLLMProvider(llmConfig);
|
|
11160
11237
|
this.ekoConfig = this.buildEkoConfig(ekoConfig);
|
|
11161
11238
|
this.registerTools();
|
|
11162
|
-
logger.info("using Eko@" + "
|
|
11239
|
+
logger.info("using Eko@" + "8aef68f294c16840224e6656e0a04a2b87b4ac96");
|
|
11163
11240
|
logger.debug("caller's ekoConfig:", ekoConfig);
|
|
11164
11241
|
}
|
|
11165
11242
|
static getLogger() {
|
|
@@ -24,49 +24,21 @@ export declare const workflowSchema: {
|
|
|
24
24
|
id: {
|
|
25
25
|
type: string;
|
|
26
26
|
};
|
|
27
|
-
type: {
|
|
28
|
-
type: string;
|
|
29
|
-
enum: string[];
|
|
30
|
-
};
|
|
31
|
-
dependencies: {
|
|
32
|
-
type: string;
|
|
33
|
-
items: {
|
|
34
|
-
type: string;
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
output: {
|
|
38
|
-
type: string;
|
|
39
|
-
properties: {
|
|
40
|
-
name: {
|
|
41
|
-
type: string;
|
|
42
|
-
};
|
|
43
|
-
description: {
|
|
44
|
-
type: string;
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
27
|
action: {
|
|
49
28
|
type: string;
|
|
50
29
|
required: string[];
|
|
51
30
|
properties: {
|
|
52
|
-
type: {
|
|
53
|
-
type: string;
|
|
54
|
-
enum: string[];
|
|
55
|
-
};
|
|
56
31
|
name: {
|
|
57
32
|
type: string;
|
|
58
33
|
};
|
|
59
34
|
description: {
|
|
60
35
|
type: string;
|
|
36
|
+
description: string;
|
|
61
37
|
};
|
|
62
38
|
};
|
|
63
39
|
};
|
|
64
40
|
};
|
|
65
41
|
};
|
|
66
42
|
};
|
|
67
|
-
variables: {
|
|
68
|
-
type: string;
|
|
69
|
-
additionalProperties: boolean;
|
|
70
|
-
};
|
|
71
43
|
};
|
|
72
44
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sleep(time: number): Promise<void>;
|