@eko-ai/eko 3.0.0 → 3.0.1-alpha.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/agent/base.d.ts.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/index.cjs.js +362 -89
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +362 -89
- package/dist/index.esm.js.map +1 -1
- package/dist/mcp/http.d.ts +1 -0
- package/dist/mcp/http.d.ts.map +1 -1
- package/dist/mcp/sse.d.ts +1 -1
- package/dist/mcp/sse.d.ts.map +1 -1
- package/dist/tools/task_result_check.d.ts +18 -0
- package/dist/tools/task_result_check.d.ts.map +1 -0
- package/dist/tools/todo_list_manager.d.ts +16 -0
- package/dist/tools/todo_list_manager.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -10,6 +10,8 @@ const config$1 = {
|
|
|
10
10
|
fileTextMaxLength: 20000,
|
|
11
11
|
maxDialogueImgFileNum: 1,
|
|
12
12
|
toolResultMultimodal: true,
|
|
13
|
+
expertMode: false,
|
|
14
|
+
expertModeTodoLoopNum: 10,
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
var LogLevel;
|
|
@@ -30811,10 +30813,10 @@ ${agents.join("\n")}
|
|
|
30811
30813
|
workflow.xml = xml;
|
|
30812
30814
|
}
|
|
30813
30815
|
|
|
30814
|
-
const TOOL_NAME$
|
|
30816
|
+
const TOOL_NAME$a = "task_snapshot";
|
|
30815
30817
|
class TaskSnapshotTool {
|
|
30816
30818
|
constructor() {
|
|
30817
|
-
this.name = TOOL_NAME$
|
|
30819
|
+
this.name = TOOL_NAME$a;
|
|
30818
30820
|
this.description = `Task snapshot archive, recording key information of the current task, updating task node status, facilitating subsequent continuation of operation.`;
|
|
30819
30821
|
this.parameters = {
|
|
30820
30822
|
type: "object",
|
|
@@ -30907,7 +30909,7 @@ async function compressAgentMessages(agentContext, rlm, messages, tools) {
|
|
|
30907
30909
|
return;
|
|
30908
30910
|
}
|
|
30909
30911
|
try {
|
|
30910
|
-
doCompressAgentMessages(agentContext, rlm, messages, tools);
|
|
30912
|
+
await doCompressAgentMessages(agentContext, rlm, messages, tools);
|
|
30911
30913
|
}
|
|
30912
30914
|
catch (e) {
|
|
30913
30915
|
Log.error("Error compressing agent messages:", e);
|
|
@@ -30915,9 +30917,9 @@ async function compressAgentMessages(agentContext, rlm, messages, tools) {
|
|
|
30915
30917
|
}
|
|
30916
30918
|
async function doCompressAgentMessages(agentContext, rlm, messages, tools) {
|
|
30917
30919
|
// extract used tool
|
|
30918
|
-
|
|
30919
|
-
|
|
30920
|
-
|
|
30920
|
+
const usedTools = extractUsedTool(messages, tools);
|
|
30921
|
+
const snapshotTool = new TaskSnapshotTool();
|
|
30922
|
+
const newTools = mergeTools(usedTools, [
|
|
30921
30923
|
{
|
|
30922
30924
|
type: "function",
|
|
30923
30925
|
name: snapshotTool.name,
|
|
@@ -30945,16 +30947,16 @@ async function doCompressAgentMessages(agentContext, rlm, messages, tools) {
|
|
|
30945
30947
|
],
|
|
30946
30948
|
});
|
|
30947
30949
|
// compress snapshot
|
|
30948
|
-
|
|
30950
|
+
const result = await callAgentLLM(agentContext, rlm, newMessages, newTools, true, {
|
|
30949
30951
|
type: "tool",
|
|
30950
30952
|
toolName: snapshotTool.name,
|
|
30951
30953
|
});
|
|
30952
|
-
|
|
30953
|
-
|
|
30954
|
+
const toolCall = result.filter((s) => s.type == "tool-call")[0];
|
|
30955
|
+
const args = typeof toolCall.input == "string"
|
|
30954
30956
|
? JSON.parse(toolCall.input || "{}")
|
|
30955
30957
|
: toolCall.input || {};
|
|
30956
|
-
|
|
30957
|
-
|
|
30958
|
+
const toolResult = await snapshotTool.execute(args, agentContext);
|
|
30959
|
+
const callback = agentContext.context.config.callback;
|
|
30958
30960
|
if (callback) {
|
|
30959
30961
|
await callback.onMessage({
|
|
30960
30962
|
taskId: agentContext.context.taskId,
|
|
@@ -33187,10 +33189,10 @@ function convertUserContent(content) {
|
|
|
33187
33189
|
});
|
|
33188
33190
|
}
|
|
33189
33191
|
|
|
33190
|
-
const TOOL_NAME$
|
|
33192
|
+
const TOOL_NAME$9 = "taskPlanner";
|
|
33191
33193
|
class TaskPlannerTool {
|
|
33192
33194
|
constructor(ekoDialogue, params) {
|
|
33193
|
-
this.name = TOOL_NAME$
|
|
33195
|
+
this.name = TOOL_NAME$9;
|
|
33194
33196
|
const agents = ekoDialogue.getConfig().agents || [];
|
|
33195
33197
|
const agentNames = agents.map((agent) => agent.Name).join(", ");
|
|
33196
33198
|
this.description = `Used for task planning, this tool is only responsible for generating task plans, not executing them, the following agents are available: ${agentNames}...`;
|
|
@@ -33256,17 +33258,17 @@ class TaskPlannerTool {
|
|
|
33256
33258
|
}
|
|
33257
33259
|
}
|
|
33258
33260
|
|
|
33259
|
-
const TOOL_NAME$
|
|
33261
|
+
const TOOL_NAME$8 = "executeTask";
|
|
33260
33262
|
class ExecuteTaskTool {
|
|
33261
33263
|
constructor(ekoDialogue) {
|
|
33262
|
-
this.name = TOOL_NAME$
|
|
33263
|
-
this.description = `Responsible for executing the task plan generated by the ${TOOL_NAME$
|
|
33264
|
+
this.name = TOOL_NAME$8;
|
|
33265
|
+
this.description = `Responsible for executing the task plan generated by the ${TOOL_NAME$9}. Use this tool if you need to execute planned tasks.`;
|
|
33264
33266
|
this.parameters = {
|
|
33265
33267
|
type: "object",
|
|
33266
33268
|
properties: {
|
|
33267
33269
|
taskId: {
|
|
33268
33270
|
type: "string",
|
|
33269
|
-
description: `Task ID, generated by the \`${TOOL_NAME$
|
|
33271
|
+
description: `Task ID, generated by the \`${TOOL_NAME$9}\` tool.`,
|
|
33270
33272
|
},
|
|
33271
33273
|
},
|
|
33272
33274
|
required: ["taskId"],
|
|
@@ -33331,10 +33333,10 @@ class ExecuteTaskTool {
|
|
|
33331
33333
|
}
|
|
33332
33334
|
}
|
|
33333
33335
|
|
|
33334
|
-
const TOOL_NAME$
|
|
33336
|
+
const TOOL_NAME$7 = "taskVariableStorage";
|
|
33335
33337
|
class TaskVariableStorageTool {
|
|
33336
33338
|
constructor(ekoDialogue) {
|
|
33337
|
-
this.name = TOOL_NAME$
|
|
33339
|
+
this.name = TOOL_NAME$7;
|
|
33338
33340
|
this.description = `Used for storing, reading, and retrieving variable data, and maintaining input/output variables in task nodes.`;
|
|
33339
33341
|
this.parameters = {
|
|
33340
33342
|
type: "object",
|
|
@@ -33413,9 +33415,9 @@ You are {name}, a helpful AI assistant.
|
|
|
33413
33415
|
|
|
33414
33416
|
# Tool Usage Instructions
|
|
33415
33417
|
For non-chat related tasks issued by users, the following tools need to be called to complete them:
|
|
33416
|
-
- ${TOOL_NAME$
|
|
33417
|
-
- ${TOOL_NAME$
|
|
33418
|
-
- ${TOOL_NAME$
|
|
33418
|
+
- ${TOOL_NAME$9}: This tool is used to plan tasks and generate task execution plans. For action tasks, this tool needs to be called for planning, then handed over to the \`${TOOL_NAME$8}\` tool for execution.
|
|
33419
|
+
- ${TOOL_NAME$8}: This tool is used to execute tasks planned by the \`${TOOL_NAME$9}\` tool.
|
|
33420
|
+
- ${TOOL_NAME$7}: This tool is used to read output variables from task nodes and write input variables to task nodes, mainly used to retrieve variable results after task execution is completed.
|
|
33419
33421
|
{prompt}
|
|
33420
33422
|
|
|
33421
33423
|
The output language should match the user's conversation language.
|
|
@@ -33444,7 +33446,7 @@ class EkoDialogue {
|
|
|
33444
33446
|
const messages = this.memory.getMessages();
|
|
33445
33447
|
const lastMessage = messages[messages.length - 1];
|
|
33446
33448
|
if (lastMessage.role !== "tool" ||
|
|
33447
|
-
!lastMessage.content.some((part) => part.toolName === TOOL_NAME$
|
|
33449
|
+
!lastMessage.content.some((part) => part.toolName === TOOL_NAME$9)) {
|
|
33448
33450
|
throw new Error("No task planner tool call found");
|
|
33449
33451
|
}
|
|
33450
33452
|
const userMessages = messages.filter((message) => message.role === "user");
|
|
@@ -33475,7 +33477,7 @@ class EkoDialogue {
|
|
|
33475
33477
|
return finalResult;
|
|
33476
33478
|
}
|
|
33477
33479
|
if (this.config.segmentedExecution &&
|
|
33478
|
-
results.some((r) => r.type == "tool-call" && r.toolName == TOOL_NAME$
|
|
33480
|
+
results.some((r) => r.type == "tool-call" && r.toolName == TOOL_NAME$9)) {
|
|
33479
33481
|
return "segmentedExecution";
|
|
33480
33482
|
}
|
|
33481
33483
|
}
|
|
@@ -33673,11 +33675,23 @@ class SimpleSseMcpClient {
|
|
|
33673
33675
|
version: "1.0.0",
|
|
33674
33676
|
},
|
|
33675
33677
|
});
|
|
33676
|
-
this.request("notifications/initialized", {});
|
|
33678
|
+
// this.request("notifications/initialized", {});
|
|
33677
33679
|
}
|
|
33678
33680
|
ping() {
|
|
33679
33681
|
this.request("ping", {});
|
|
33680
33682
|
}
|
|
33683
|
+
async listTools(param, signal) {
|
|
33684
|
+
const message = await this.request("tools/list", {
|
|
33685
|
+
...param,
|
|
33686
|
+
}, signal);
|
|
33687
|
+
return message.result.tools || [];
|
|
33688
|
+
}
|
|
33689
|
+
async callTool(param, signal) {
|
|
33690
|
+
const message = await this.request("tools/call", {
|
|
33691
|
+
...param,
|
|
33692
|
+
}, signal);
|
|
33693
|
+
return message.result;
|
|
33694
|
+
}
|
|
33681
33695
|
async request(method, params, signal) {
|
|
33682
33696
|
const id = uuidv4();
|
|
33683
33697
|
try {
|
|
@@ -33710,36 +33724,35 @@ class SimpleSseMcpClient {
|
|
|
33710
33724
|
});
|
|
33711
33725
|
const body = await response.text();
|
|
33712
33726
|
if (body == "Accepted") {
|
|
33713
|
-
|
|
33727
|
+
const message = await callback;
|
|
33728
|
+
if (message.error) {
|
|
33729
|
+
Log.error(`MCP ${method} error: ` + message.error);
|
|
33730
|
+
throw new Error(`MCP ${method} error: ` +
|
|
33731
|
+
(typeof message.error === "string"
|
|
33732
|
+
? message.error
|
|
33733
|
+
: message.error.message));
|
|
33734
|
+
}
|
|
33735
|
+
if (message.result?.isError == true) {
|
|
33736
|
+
if (message.result.content) {
|
|
33737
|
+
throw new Error(`MCP ${method} error: ` +
|
|
33738
|
+
(typeof message.result.content === "string"
|
|
33739
|
+
? message.result.content
|
|
33740
|
+
: message.result.content[0].text));
|
|
33741
|
+
}
|
|
33742
|
+
else {
|
|
33743
|
+
throw new Error(`MCP ${method} error: ` + JSON.stringify(message.result));
|
|
33744
|
+
}
|
|
33745
|
+
}
|
|
33746
|
+
return message;
|
|
33714
33747
|
}
|
|
33715
33748
|
else {
|
|
33716
|
-
throw new Error(
|
|
33749
|
+
throw new Error(`MCP ${method} error:` + body);
|
|
33717
33750
|
}
|
|
33718
33751
|
}
|
|
33719
33752
|
finally {
|
|
33720
33753
|
this.requestMap.delete(id);
|
|
33721
33754
|
}
|
|
33722
33755
|
}
|
|
33723
|
-
async listTools(param, signal) {
|
|
33724
|
-
const message = await this.request("tools/list", {
|
|
33725
|
-
...param,
|
|
33726
|
-
}, signal);
|
|
33727
|
-
if (message.error) {
|
|
33728
|
-
Log.error("McpClient listTools error: ", param, message);
|
|
33729
|
-
throw new Error("listTools Exception");
|
|
33730
|
-
}
|
|
33731
|
-
return message.result.tools || [];
|
|
33732
|
-
}
|
|
33733
|
-
async callTool(param, signal) {
|
|
33734
|
-
const message = await this.request("tools/call", {
|
|
33735
|
-
...param,
|
|
33736
|
-
}, signal);
|
|
33737
|
-
if (message.error) {
|
|
33738
|
-
Log.error("McpClient callTool error: ", param, message);
|
|
33739
|
-
throw new Error("callTool Exception");
|
|
33740
|
-
}
|
|
33741
|
-
return message.result;
|
|
33742
|
-
}
|
|
33743
33756
|
isConnected() {
|
|
33744
33757
|
if (this.sseHandler && this.sseHandler.readyState == 1) {
|
|
33745
33758
|
return true;
|
|
@@ -33865,20 +33878,12 @@ class SimpleHttpMcpClient {
|
|
|
33865
33878
|
const message = await this.request("tools/list", {
|
|
33866
33879
|
...param,
|
|
33867
33880
|
}, signal);
|
|
33868
|
-
if (message.error) {
|
|
33869
|
-
Log.error("McpClient listTools error: ", param, message);
|
|
33870
|
-
throw new Error("listTools Exception");
|
|
33871
|
-
}
|
|
33872
33881
|
return message.result.tools || [];
|
|
33873
33882
|
}
|
|
33874
33883
|
async callTool(param, signal) {
|
|
33875
33884
|
const message = await this.request("tools/call", {
|
|
33876
33885
|
...param,
|
|
33877
33886
|
}, signal);
|
|
33878
|
-
if (message.error) {
|
|
33879
|
-
Log.error("McpClient callTool error: ", param, message);
|
|
33880
|
-
throw new Error("callTool Exception");
|
|
33881
|
-
}
|
|
33882
33887
|
return message.result;
|
|
33883
33888
|
}
|
|
33884
33889
|
isConnected() {
|
|
@@ -33906,7 +33911,7 @@ class SimpleHttpMcpClient {
|
|
|
33906
33911
|
headers: {
|
|
33907
33912
|
"Cache-Control": "no-cache",
|
|
33908
33913
|
"Content-Type": "application/json",
|
|
33909
|
-
|
|
33914
|
+
Accept: "application/json, text/event-stream",
|
|
33910
33915
|
"MCP-Protocol-Version": this.protocolVersion,
|
|
33911
33916
|
...extHeaders,
|
|
33912
33917
|
...this.headers,
|
|
@@ -33958,11 +33963,13 @@ class SimpleHttpMcpClient {
|
|
|
33958
33963
|
str = chunks[chunks.length - 1];
|
|
33959
33964
|
}
|
|
33960
33965
|
}
|
|
33966
|
+
this.handleError(method, message);
|
|
33961
33967
|
return message;
|
|
33962
33968
|
}
|
|
33963
33969
|
else {
|
|
33964
33970
|
// JSON
|
|
33965
33971
|
const message = await response.json();
|
|
33972
|
+
this.handleError(method, message);
|
|
33966
33973
|
return message;
|
|
33967
33974
|
}
|
|
33968
33975
|
}
|
|
@@ -33973,6 +33980,29 @@ class SimpleHttpMcpClient {
|
|
|
33973
33980
|
throw e;
|
|
33974
33981
|
}
|
|
33975
33982
|
}
|
|
33983
|
+
handleError(method, message) {
|
|
33984
|
+
if (!message) {
|
|
33985
|
+
throw new Error(`MCP ${method} error: no response`);
|
|
33986
|
+
}
|
|
33987
|
+
if (message?.error) {
|
|
33988
|
+
Log.error(`MCP ${method} error: ` + message.error);
|
|
33989
|
+
throw new Error(`MCP ${method} error: ` +
|
|
33990
|
+
(typeof message.error === "string"
|
|
33991
|
+
? message.error
|
|
33992
|
+
: message.error.message));
|
|
33993
|
+
}
|
|
33994
|
+
if (message.result?.isError == true) {
|
|
33995
|
+
if (message.result.content) {
|
|
33996
|
+
throw new Error(`MCP ${method} error: ` +
|
|
33997
|
+
(typeof message.result.content === "string"
|
|
33998
|
+
? message.result.content
|
|
33999
|
+
: message.result.content[0].text));
|
|
34000
|
+
}
|
|
34001
|
+
else {
|
|
34002
|
+
throw new Error(`MCP ${method} error: ` + JSON.stringify(message.result));
|
|
34003
|
+
}
|
|
34004
|
+
}
|
|
34005
|
+
}
|
|
33976
34006
|
parseChunk(chunk) {
|
|
33977
34007
|
const lines = chunk.split("\n");
|
|
33978
34008
|
const chunk_obj = {};
|
|
@@ -34014,10 +34044,10 @@ class ToolWrapper {
|
|
|
34014
34044
|
}
|
|
34015
34045
|
}
|
|
34016
34046
|
|
|
34017
|
-
const TOOL_NAME$
|
|
34047
|
+
const TOOL_NAME$6 = "foreach_task";
|
|
34018
34048
|
class ForeachTaskTool {
|
|
34019
34049
|
constructor() {
|
|
34020
|
-
this.name = TOOL_NAME$
|
|
34050
|
+
this.name = TOOL_NAME$6;
|
|
34021
34051
|
this.description = `When executing the \`forEach\` node, please use the current tool for counting to ensure tasks are executed sequentially, the tool needs to be called with each loop iteration.`;
|
|
34022
34052
|
this.parameters = {
|
|
34023
34053
|
type: "object",
|
|
@@ -34073,10 +34103,10 @@ class ForeachTaskTool {
|
|
|
34073
34103
|
}
|
|
34074
34104
|
}
|
|
34075
34105
|
|
|
34076
|
-
const TOOL_NAME$
|
|
34106
|
+
const TOOL_NAME$5 = "human_interact";
|
|
34077
34107
|
class HumanInteractTool {
|
|
34078
34108
|
constructor() {
|
|
34079
|
-
this.name = TOOL_NAME$
|
|
34109
|
+
this.name = TOOL_NAME$5;
|
|
34080
34110
|
this.noPlan = true;
|
|
34081
34111
|
this.description = `AI interacts with humans:
|
|
34082
34112
|
confirm: Ask the user to confirm whether to execute an operation, especially when performing dangerous actions such as deleting system files, users will choose Yes or No.
|
|
@@ -34212,10 +34242,10 @@ request_help: Request assistance from the user; for instance, when an operation
|
|
|
34212
34242
|
}
|
|
34213
34243
|
}
|
|
34214
34244
|
|
|
34215
|
-
const TOOL_NAME$
|
|
34245
|
+
const TOOL_NAME$4 = "task_node_status";
|
|
34216
34246
|
class TaskNodeStatusTool {
|
|
34217
34247
|
constructor() {
|
|
34218
|
-
this.name = TOOL_NAME$
|
|
34248
|
+
this.name = TOOL_NAME$4;
|
|
34219
34249
|
this.description = `After completing each step of the task, you need to call this tool to update the status of the task node, and think about the tasks to be processed and the next action plan.`;
|
|
34220
34250
|
this.parameters = {
|
|
34221
34251
|
type: "object",
|
|
@@ -34267,11 +34297,11 @@ class TaskNodeStatusTool {
|
|
|
34267
34297
|
}
|
|
34268
34298
|
}
|
|
34269
34299
|
|
|
34270
|
-
const TOOL_NAME$
|
|
34300
|
+
const TOOL_NAME$3 = "variable_storage";
|
|
34271
34301
|
class VariableStorageTool {
|
|
34272
34302
|
constructor() {
|
|
34273
|
-
this.name = TOOL_NAME$
|
|
34274
|
-
this.description = `Used for storing, reading, and retrieving variable data, and maintaining input/output variables in task nodes.`;
|
|
34303
|
+
this.name = TOOL_NAME$3;
|
|
34304
|
+
this.description = `Used for storing, reading, and retrieving variable data, and maintaining input/output variables in task nodes. When the same variable is stored repeatedly, it will overwrite the previous value.`;
|
|
34275
34305
|
this.parameters = {
|
|
34276
34306
|
type: "object",
|
|
34277
34307
|
properties: {
|
|
@@ -34343,7 +34373,7 @@ class VariableStorageTool {
|
|
|
34343
34373
|
}
|
|
34344
34374
|
}
|
|
34345
34375
|
|
|
34346
|
-
const TOOL_NAME = "watch_trigger";
|
|
34376
|
+
const TOOL_NAME$2 = "watch_trigger";
|
|
34347
34377
|
const watch_system_prompt = `You are a tool for detecting element changes. Given a task description, compare two images to determine whether the changes described in the task have occurred.
|
|
34348
34378
|
If the changes have occurred, return an json with \`changed\` set to true and \`changeInfo\` containing a description of the changes. If no changes have occurred, return an object with \`changed\` set to false.
|
|
34349
34379
|
|
|
@@ -34362,7 +34392,7 @@ Output:
|
|
|
34362
34392
|
}`;
|
|
34363
34393
|
class WatchTriggerTool {
|
|
34364
34394
|
constructor() {
|
|
34365
|
-
this.name = TOOL_NAME;
|
|
34395
|
+
this.name = TOOL_NAME$2;
|
|
34366
34396
|
this.description = `When executing the \`watch\` node, please use it to monitor DOM element changes, it will block the listener until the element changes or times out.`;
|
|
34367
34397
|
this.parameters = {
|
|
34368
34398
|
type: "object",
|
|
@@ -34563,6 +34593,111 @@ class McpTool {
|
|
|
34563
34593
|
}
|
|
34564
34594
|
}
|
|
34565
34595
|
|
|
34596
|
+
const TOOL_NAME$1 = "task_result_check";
|
|
34597
|
+
class TaskResultCheckTool {
|
|
34598
|
+
constructor() {
|
|
34599
|
+
this.name = TOOL_NAME$1;
|
|
34600
|
+
this.description = `Check the current task execution process and results, evaluate the overall completion status of the current task, and whether the output variables in the nodes are stored.`;
|
|
34601
|
+
this.parameters = {
|
|
34602
|
+
type: "object",
|
|
34603
|
+
properties: {
|
|
34604
|
+
thought: {
|
|
34605
|
+
type: "string",
|
|
34606
|
+
description: "Please conduct thoughtful analysis of the overall execution process and results of the current task, analyzing whether the task has been completed.",
|
|
34607
|
+
},
|
|
34608
|
+
completionStatus: {
|
|
34609
|
+
type: "string",
|
|
34610
|
+
description: "The completion status of the current task is only considered complete when the entire current task is finished; partial completion or task failure is considered incomplete",
|
|
34611
|
+
enum: ["completed", "incomplete"],
|
|
34612
|
+
},
|
|
34613
|
+
todoList: {
|
|
34614
|
+
type: "string",
|
|
34615
|
+
description: "Pending task list for incomplete tasks, when tasks are not fully completed, please describe which tasks remain to be completed",
|
|
34616
|
+
},
|
|
34617
|
+
},
|
|
34618
|
+
required: ["thought", "completionStatus"],
|
|
34619
|
+
};
|
|
34620
|
+
}
|
|
34621
|
+
async execute(args, agentContext) {
|
|
34622
|
+
return {
|
|
34623
|
+
content: [
|
|
34624
|
+
{
|
|
34625
|
+
type: "text",
|
|
34626
|
+
text: "success",
|
|
34627
|
+
},
|
|
34628
|
+
],
|
|
34629
|
+
};
|
|
34630
|
+
}
|
|
34631
|
+
}
|
|
34632
|
+
async function doTaskResultCheck(agentContext, rlm, messages, tools) {
|
|
34633
|
+
try {
|
|
34634
|
+
// extract used tool
|
|
34635
|
+
const usedTools = extractUsedTool(messages, tools);
|
|
34636
|
+
const taskResultCheck = new TaskResultCheckTool();
|
|
34637
|
+
const newTools = mergeTools(usedTools, [
|
|
34638
|
+
{
|
|
34639
|
+
type: "function",
|
|
34640
|
+
name: taskResultCheck.name,
|
|
34641
|
+
description: taskResultCheck.description,
|
|
34642
|
+
inputSchema: taskResultCheck.parameters,
|
|
34643
|
+
},
|
|
34644
|
+
]);
|
|
34645
|
+
// handle messages
|
|
34646
|
+
const newMessages = [...messages];
|
|
34647
|
+
newMessages.push({
|
|
34648
|
+
role: "user",
|
|
34649
|
+
content: [
|
|
34650
|
+
{
|
|
34651
|
+
type: "text",
|
|
34652
|
+
text: `Task:\n${agentContext.agentChain.agent.xml}\n\nPlease check the completion status of the current task.`,
|
|
34653
|
+
},
|
|
34654
|
+
],
|
|
34655
|
+
});
|
|
34656
|
+
const result = await callAgentLLM(agentContext, rlm, newMessages, newTools, true, {
|
|
34657
|
+
type: "tool",
|
|
34658
|
+
toolName: taskResultCheck.name,
|
|
34659
|
+
});
|
|
34660
|
+
const toolCall = result.filter((s) => s.type == "tool-call")[0];
|
|
34661
|
+
const args = typeof toolCall.input == "string"
|
|
34662
|
+
? JSON.parse(toolCall.input || "{}")
|
|
34663
|
+
: toolCall.input || {};
|
|
34664
|
+
const toolResult = await taskResultCheck.execute(args, agentContext);
|
|
34665
|
+
const callback = agentContext.context.config.callback;
|
|
34666
|
+
if (callback) {
|
|
34667
|
+
await callback.onMessage({
|
|
34668
|
+
taskId: agentContext.context.taskId,
|
|
34669
|
+
agentName: agentContext.agent.Name,
|
|
34670
|
+
nodeId: agentContext.agentChain.agent.id,
|
|
34671
|
+
type: "tool_result",
|
|
34672
|
+
toolId: toolCall.toolCallId,
|
|
34673
|
+
toolName: toolCall.toolName,
|
|
34674
|
+
params: args,
|
|
34675
|
+
toolResult: toolResult,
|
|
34676
|
+
}, agentContext);
|
|
34677
|
+
}
|
|
34678
|
+
if (args.completionStatus == "incomplete") {
|
|
34679
|
+
messages.push({
|
|
34680
|
+
role: "user",
|
|
34681
|
+
content: [
|
|
34682
|
+
{
|
|
34683
|
+
type: "text",
|
|
34684
|
+
text: `It seems that your task has not been fully completed. Please continue with the remaining steps:\n${args.todoList || ""}`,
|
|
34685
|
+
},
|
|
34686
|
+
],
|
|
34687
|
+
});
|
|
34688
|
+
}
|
|
34689
|
+
return {
|
|
34690
|
+
completionStatus: args.completionStatus,
|
|
34691
|
+
};
|
|
34692
|
+
}
|
|
34693
|
+
catch (e) {
|
|
34694
|
+
Log.error("TaskResultCheckTool error", e);
|
|
34695
|
+
return {
|
|
34696
|
+
completionStatus: "completed",
|
|
34697
|
+
};
|
|
34698
|
+
}
|
|
34699
|
+
}
|
|
34700
|
+
|
|
34566
34701
|
const AGENT_SYSTEM_TEMPLATE = `
|
|
34567
34702
|
You are {name}, an autonomous AI agent for {agent} agent.
|
|
34568
34703
|
|
|
@@ -34587,14 +34722,14 @@ The output language should follow the language corresponding to the user's task.
|
|
|
34587
34722
|
`;
|
|
34588
34723
|
const HUMAN_PROMPT = `
|
|
34589
34724
|
* HUMAN INTERACT
|
|
34590
|
-
During the task execution process, you can use the \`${TOOL_NAME$
|
|
34725
|
+
During the task execution process, you can use the \`${TOOL_NAME$5}\` tool to interact with humans, please call it in the following situations:
|
|
34591
34726
|
- When performing dangerous operations such as deleting files, confirmation from humans is required.
|
|
34592
34727
|
- When encountering obstacles while accessing websites, such as requiring user login, captcha verification, QR code scanning, or human verification, you need to request manual assistance.
|
|
34593
|
-
- Please do not use the \`${TOOL_NAME$
|
|
34728
|
+
- Please do not use the \`${TOOL_NAME$5}\` tool frequently.
|
|
34594
34729
|
`;
|
|
34595
34730
|
const VARIABLE_PROMPT = `
|
|
34596
34731
|
* VARIABLE STORAGE
|
|
34597
|
-
When a step node has input/output variable attributes, use the \`${TOOL_NAME$
|
|
34732
|
+
When a step node has input/output variable attributes, use the \`${TOOL_NAME$3}\` tool to read from and write to these variables, these variables enable context sharing and coordination between multiple agents.
|
|
34598
34733
|
`;
|
|
34599
34734
|
const FOR_EACH_NODE = `
|
|
34600
34735
|
<!-- duplicate task node, items support list and variable -->
|
|
@@ -34603,7 +34738,7 @@ const FOR_EACH_NODE = `
|
|
|
34603
34738
|
</forEach>`;
|
|
34604
34739
|
const FOR_EACH_PROMPT = `
|
|
34605
34740
|
* forEach node
|
|
34606
|
-
repetitive tasks, when executing to the forEach node, require the use of the \`${TOOL_NAME$
|
|
34741
|
+
repetitive tasks, when executing to the forEach node, require the use of the \`${TOOL_NAME$6}\` tool.
|
|
34607
34742
|
`;
|
|
34608
34743
|
const WATCH_NODE = `
|
|
34609
34744
|
<!-- monitor task node, the loop attribute specifies whether to listen in a loop or listen once -->
|
|
@@ -34616,7 +34751,7 @@ const WATCH_NODE = `
|
|
|
34616
34751
|
</watch>`;
|
|
34617
34752
|
const WATCH_PROMPT = `
|
|
34618
34753
|
* watch node
|
|
34619
|
-
monitor changes in webpage DOM elements, when executing to the watch node, require the use of the \`${TOOL_NAME}\` tool.
|
|
34754
|
+
monitor changes in webpage DOM elements, when executing to the watch node, require the use of the \`${TOOL_NAME$2}\` tool.
|
|
34620
34755
|
`;
|
|
34621
34756
|
function getAgentSystemPrompt(agent, agentNode, context, tools, extSysPrompt) {
|
|
34622
34757
|
let prompt = "";
|
|
@@ -34625,10 +34760,10 @@ function getAgentSystemPrompt(agent, agentNode, context, tools, extSysPrompt) {
|
|
|
34625
34760
|
let agentNodeXml = agentNode.xml;
|
|
34626
34761
|
let hasWatchNode = agentNodeXml.indexOf("</watch>") > -1;
|
|
34627
34762
|
let hasForEachNode = agentNodeXml.indexOf("</forEach>") > -1;
|
|
34628
|
-
let hasHumanTool = tools.filter((tool) => tool.name == TOOL_NAME$
|
|
34763
|
+
let hasHumanTool = tools.filter((tool) => tool.name == TOOL_NAME$5).length > 0;
|
|
34629
34764
|
let hasVariable = agentNodeXml.indexOf("input=") > -1 ||
|
|
34630
34765
|
agentNodeXml.indexOf("output=") > -1 ||
|
|
34631
|
-
tools.filter((tool) => tool.name == TOOL_NAME$
|
|
34766
|
+
tools.filter((tool) => tool.name == TOOL_NAME$3).length > 0;
|
|
34632
34767
|
if (hasHumanTool) {
|
|
34633
34768
|
prompt += HUMAN_PROMPT;
|
|
34634
34769
|
}
|
|
@@ -34636,13 +34771,13 @@ function getAgentSystemPrompt(agent, agentNode, context, tools, extSysPrompt) {
|
|
|
34636
34771
|
prompt += VARIABLE_PROMPT;
|
|
34637
34772
|
}
|
|
34638
34773
|
if (hasForEachNode) {
|
|
34639
|
-
if (tools.filter((tool) => tool.name == TOOL_NAME$
|
|
34774
|
+
if (tools.filter((tool) => tool.name == TOOL_NAME$6).length > 0) {
|
|
34640
34775
|
prompt += FOR_EACH_PROMPT;
|
|
34641
34776
|
}
|
|
34642
34777
|
nodePrompt += FOR_EACH_NODE;
|
|
34643
34778
|
}
|
|
34644
34779
|
if (hasWatchNode) {
|
|
34645
|
-
if (tools.filter((tool) => tool.name == TOOL_NAME).length > 0) {
|
|
34780
|
+
if (tools.filter((tool) => tool.name == TOOL_NAME$2).length > 0) {
|
|
34646
34781
|
prompt += WATCH_PROMPT;
|
|
34647
34782
|
}
|
|
34648
34783
|
nodePrompt += WATCH_NODE;
|
|
@@ -34670,7 +34805,7 @@ function getAgentSystemPrompt(agent, agentNode, context, tools, extSysPrompt) {
|
|
|
34670
34805
|
.trim();
|
|
34671
34806
|
}
|
|
34672
34807
|
function getAgentUserPrompt(agent, agentNode, context, tools) {
|
|
34673
|
-
|
|
34808
|
+
const hasTaskNodeStatusTool = (tools || agent.Tools).filter((tool) => tool.name == TOOL_NAME$4)
|
|
34674
34809
|
.length > 0;
|
|
34675
34810
|
return buildAgentRootXml(agentNode.xml, context.chain.taskPrompt, (nodeId, node) => {
|
|
34676
34811
|
if (hasTaskNodeStatusTool) {
|
|
@@ -34679,6 +34814,129 @@ function getAgentUserPrompt(agent, agentNode, context, tools) {
|
|
|
34679
34814
|
});
|
|
34680
34815
|
}
|
|
34681
34816
|
|
|
34817
|
+
const TOOL_NAME = "todo_list_manager";
|
|
34818
|
+
class TodoListManagerTool {
|
|
34819
|
+
constructor() {
|
|
34820
|
+
this.name = TOOL_NAME;
|
|
34821
|
+
this.description =
|
|
34822
|
+
"Current task to-do list management, used for managing the to-do list of current tasks. During task execution, the to-do list needs to be updated according to the task execution status: completed, pending. It also detects whether tasks are being executed in repetitive loops during the execution process.";
|
|
34823
|
+
this.parameters = {
|
|
34824
|
+
type: "object",
|
|
34825
|
+
properties: {
|
|
34826
|
+
completedList: {
|
|
34827
|
+
type: "array",
|
|
34828
|
+
description: "Current completed task list items. Please update the completed list items based on the current task completion status.",
|
|
34829
|
+
items: {
|
|
34830
|
+
type: "string",
|
|
34831
|
+
},
|
|
34832
|
+
},
|
|
34833
|
+
todoList: {
|
|
34834
|
+
type: "array",
|
|
34835
|
+
description: "Current pending task list items. Please update the pending list items based on the current task pending status.",
|
|
34836
|
+
items: {
|
|
34837
|
+
type: "string",
|
|
34838
|
+
},
|
|
34839
|
+
},
|
|
34840
|
+
loopDetection: {
|
|
34841
|
+
type: "string",
|
|
34842
|
+
description: "Check if the current step is being repeatedly executed by comparing with previous steps.",
|
|
34843
|
+
enum: ["loop", "no_loop"],
|
|
34844
|
+
},
|
|
34845
|
+
},
|
|
34846
|
+
required: ["completedList", "todoList", "loopDetection"],
|
|
34847
|
+
};
|
|
34848
|
+
}
|
|
34849
|
+
async execute(args, agentContext) {
|
|
34850
|
+
return {
|
|
34851
|
+
content: [
|
|
34852
|
+
{
|
|
34853
|
+
type: "text",
|
|
34854
|
+
text: "success",
|
|
34855
|
+
},
|
|
34856
|
+
],
|
|
34857
|
+
};
|
|
34858
|
+
}
|
|
34859
|
+
}
|
|
34860
|
+
async function doTodoListManager(agentContext, rlm, messages, tools) {
|
|
34861
|
+
try {
|
|
34862
|
+
// extract used tool
|
|
34863
|
+
const usedTools = extractUsedTool(messages, tools);
|
|
34864
|
+
const todoListManager = new TodoListManagerTool();
|
|
34865
|
+
const newTools = mergeTools(usedTools, [
|
|
34866
|
+
{
|
|
34867
|
+
type: "function",
|
|
34868
|
+
name: todoListManager.name,
|
|
34869
|
+
description: todoListManager.description,
|
|
34870
|
+
inputSchema: todoListManager.parameters,
|
|
34871
|
+
},
|
|
34872
|
+
]);
|
|
34873
|
+
// handle messages
|
|
34874
|
+
const newMessages = [...messages];
|
|
34875
|
+
newMessages.push({
|
|
34876
|
+
role: "user",
|
|
34877
|
+
content: [
|
|
34878
|
+
{
|
|
34879
|
+
type: "text",
|
|
34880
|
+
text: `Task:\n${agentContext.agentChain.agent.xml}\n\nPlease check the completion status of the current task.`,
|
|
34881
|
+
},
|
|
34882
|
+
],
|
|
34883
|
+
});
|
|
34884
|
+
const result = await callAgentLLM(agentContext, rlm, newMessages, newTools, true, {
|
|
34885
|
+
type: "tool",
|
|
34886
|
+
toolName: todoListManager.name,
|
|
34887
|
+
});
|
|
34888
|
+
const toolCall = result.filter((s) => s.type == "tool-call")[0];
|
|
34889
|
+
const args = typeof toolCall.input == "string"
|
|
34890
|
+
? JSON.parse(toolCall.input || "{}")
|
|
34891
|
+
: toolCall.input || {};
|
|
34892
|
+
const toolResult = await todoListManager.execute(args, agentContext);
|
|
34893
|
+
const callback = agentContext.context.config.callback;
|
|
34894
|
+
if (callback) {
|
|
34895
|
+
await callback.onMessage({
|
|
34896
|
+
taskId: agentContext.context.taskId,
|
|
34897
|
+
agentName: agentContext.agent.Name,
|
|
34898
|
+
nodeId: agentContext.agentChain.agent.id,
|
|
34899
|
+
type: "tool_result",
|
|
34900
|
+
toolId: toolCall.toolCallId,
|
|
34901
|
+
toolName: toolCall.toolName,
|
|
34902
|
+
params: args,
|
|
34903
|
+
toolResult: toolResult,
|
|
34904
|
+
}, agentContext);
|
|
34905
|
+
}
|
|
34906
|
+
let userPrompt = "# Task Execution Status\n";
|
|
34907
|
+
if (args.completedList && args.completedList.length > 0) {
|
|
34908
|
+
userPrompt += "## Completed task list\n";
|
|
34909
|
+
for (let i = 0; i < args.completedList.length; i++) {
|
|
34910
|
+
userPrompt += `- ${args.completedList[i]}\n`;
|
|
34911
|
+
}
|
|
34912
|
+
userPrompt += "\n";
|
|
34913
|
+
}
|
|
34914
|
+
if (args.todoList && args.todoList.length > 0) {
|
|
34915
|
+
userPrompt += "## Pending task list\n";
|
|
34916
|
+
for (let i = 0; i < args.todoList.length; i++) {
|
|
34917
|
+
userPrompt += `- ${args.todoList[i]}\n`;
|
|
34918
|
+
}
|
|
34919
|
+
userPrompt += "\n";
|
|
34920
|
+
}
|
|
34921
|
+
if (args.loopDetection == "loop") {
|
|
34922
|
+
userPrompt += `## Loop detection\nIt seems that your task is being executed in a loop, Please change the execution strategy and try other methods to complete the current task.\n\n`;
|
|
34923
|
+
}
|
|
34924
|
+
userPrompt += "Please continue executing the remaining tasks.";
|
|
34925
|
+
messages.push({
|
|
34926
|
+
role: "user",
|
|
34927
|
+
content: [
|
|
34928
|
+
{
|
|
34929
|
+
type: "text",
|
|
34930
|
+
text: userPrompt.trim(),
|
|
34931
|
+
},
|
|
34932
|
+
],
|
|
34933
|
+
});
|
|
34934
|
+
}
|
|
34935
|
+
catch (e) {
|
|
34936
|
+
Log.error("TodoListManagerTool error", e);
|
|
34937
|
+
}
|
|
34938
|
+
}
|
|
34939
|
+
|
|
34682
34940
|
class Agent {
|
|
34683
34941
|
constructor(params) {
|
|
34684
34942
|
this.tools = [];
|
|
@@ -34706,21 +34964,24 @@ class Agent {
|
|
|
34706
34964
|
}
|
|
34707
34965
|
async runWithContext(agentContext, mcpClient, maxReactNum = 100, historyMessages = []) {
|
|
34708
34966
|
let loopNum = 0;
|
|
34967
|
+
let checkNum = 0;
|
|
34709
34968
|
this.agentContext = agentContext;
|
|
34710
34969
|
const context = agentContext.context;
|
|
34711
34970
|
const agentNode = agentContext.agentChain.agent;
|
|
34712
34971
|
const tools = [...this.tools, ...this.system_auto_tools(agentNode)];
|
|
34972
|
+
const systemPrompt = await this.buildSystemPrompt(agentContext, tools);
|
|
34973
|
+
const userPrompt = await this.buildUserPrompt(agentContext, tools);
|
|
34713
34974
|
const messages = [
|
|
34714
34975
|
{
|
|
34715
34976
|
role: "system",
|
|
34716
|
-
content:
|
|
34717
|
-
providerOptions: defaultMessageProviderOptions()
|
|
34977
|
+
content: systemPrompt,
|
|
34978
|
+
providerOptions: defaultMessageProviderOptions(),
|
|
34718
34979
|
},
|
|
34719
34980
|
...historyMessages,
|
|
34720
34981
|
{
|
|
34721
34982
|
role: "user",
|
|
34722
|
-
content:
|
|
34723
|
-
providerOptions: defaultMessageProviderOptions()
|
|
34983
|
+
content: userPrompt,
|
|
34984
|
+
providerOptions: defaultMessageProviderOptions(),
|
|
34724
34985
|
},
|
|
34725
34986
|
];
|
|
34726
34987
|
agentContext.messages = messages;
|
|
@@ -34738,20 +34999,32 @@ class Agent {
|
|
|
34738
34999
|
}
|
|
34739
35000
|
}
|
|
34740
35001
|
await this.handleMessages(agentContext, messages, tools);
|
|
34741
|
-
const
|
|
34742
|
-
const
|
|
34743
|
-
|
|
34744
|
-
|
|
35002
|
+
const llm_tools = convertTools(agentTools);
|
|
35003
|
+
const results = await callAgentLLM(agentContext, rlm, messages, llm_tools, false, undefined, 0, this.callback, this.requestHandler);
|
|
35004
|
+
const forceStop = agentContext.variables.get("forceStop");
|
|
35005
|
+
if (forceStop) {
|
|
35006
|
+
return forceStop;
|
|
34745
35007
|
}
|
|
35008
|
+
const finalResult = await this.handleCallResult(agentContext, messages, agentTools, results);
|
|
34746
35009
|
loopNum++;
|
|
35010
|
+
if (!finalResult) {
|
|
35011
|
+
if (config$1.expertMode && loopNum % config$1.expertModeTodoLoopNum == 0) {
|
|
35012
|
+
await doTodoListManager(agentContext, rlm, messages, llm_tools);
|
|
35013
|
+
}
|
|
35014
|
+
continue;
|
|
35015
|
+
}
|
|
35016
|
+
if (config$1.expertMode && checkNum == 0) {
|
|
35017
|
+
checkNum++;
|
|
35018
|
+
const { completionStatus } = await doTaskResultCheck(agentContext, rlm, messages, llm_tools);
|
|
35019
|
+
if (completionStatus == "incomplete") {
|
|
35020
|
+
continue;
|
|
35021
|
+
}
|
|
35022
|
+
}
|
|
35023
|
+
return finalResult;
|
|
34747
35024
|
}
|
|
34748
35025
|
return "Unfinished";
|
|
34749
35026
|
}
|
|
34750
35027
|
async handleCallResult(agentContext, messages, agentTools, results) {
|
|
34751
|
-
const forceStop = agentContext.variables.get("forceStop");
|
|
34752
|
-
if (forceStop) {
|
|
34753
|
-
return forceStop;
|
|
34754
|
-
}
|
|
34755
35028
|
let text = null;
|
|
34756
35029
|
let context = agentContext.context;
|
|
34757
35030
|
let user_messages = [];
|