@eko-ai/eko 2.1.9 → 2.2.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../../src/common/xml.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAMT,MAAM,qBAAqB,CAAC;AAE7B,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,EACb,QAAQ,CAAC,EAAE,MAAM,GAChB,QAAQ,GAAG,IAAI,CAyEjB;AA6DD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,UA0BtD;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,GAAG,IAAI,CAqBhB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAOjD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAGjD;AAED,wBAAgB,wBAAwB,CAAC,EACvC,MAAM,EACN,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,GACV,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,QAAQ,CA4BX;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,QA8DlD"}
1
+ {"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../../src/common/xml.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAMT,MAAM,qBAAqB,CAAC;AAG7B,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,EACb,QAAQ,CAAC,EAAE,MAAM,GAChB,QAAQ,GAAG,IAAI,CA6FjB;AA6DD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,UA0BtD;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,GAAG,IAAI,CAqBhB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAOjD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAGjD;AAED,wBAAgB,wBAAwB,CAAC,EACvC,MAAM,EACN,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,GACV,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,QAAQ,CA8BX;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,QA8DlD"}
@@ -11,6 +11,7 @@ export declare class Eko {
11
11
  run(taskPrompt: string, taskId?: string, contextParams?: Record<string, any>): Promise<EkoResult>;
12
12
  initContext(workflow: Workflow, contextParams?: Record<string, any>): Promise<Context>;
13
13
  private doRunWorkflow;
14
+ private runAgent;
14
15
  getTask(taskId: string): Context | undefined;
15
16
  getAllTaskId(): string[];
16
17
  deleteTask(taskId: string): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAMjC,OAAO,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,GAAG;IACd,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAuB;gBAE1B,MAAM,EAAE,SAAS;IAKhB,QAAQ,CACnB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAiB,EACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClC,OAAO,CAAC,QAAQ,CAAC;IAwBP,MAAM,CACjB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,QAAQ,CAAC;IAcP,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAyB3C,GAAG,CACd,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAiB,EACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClC,OAAO,CAAC,SAAS,CAAC;IAKR,WAAW,CACtB,QAAQ,EAAE,QAAQ,EAClB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC;YAoBL,aAAa;IA4EpB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI5C,YAAY,IAAI,MAAM,EAAE;IAIxB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IASnC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO;IAYnD,SAAS,CACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,gBAAgB,CAAC,EAAE,OAAO,EAC1B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO;IAWH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAQlE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;YAKrB,YAAY;CAa3B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAMjC,OAAO,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,GAAG;IACd,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAuB;gBAE1B,MAAM,EAAE,SAAS;IAKhB,QAAQ,CACnB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAiB,EACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClC,OAAO,CAAC,QAAQ,CAAC;IAwBP,MAAM,CACjB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,QAAQ,CAAC;IAcP,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAyB3C,GAAG,CACd,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAiB,EACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClC,OAAO,CAAC,SAAS,CAAC;IAKR,WAAW,CACtB,QAAQ,EAAE,QAAQ,EAClB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC;YAoBL,aAAa;YA0Fb,QAAQ;IA2Cf,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI5C,YAAY,IAAI,MAAM,EAAE;IAIxB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IASnC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO;IAYnD,SAAS,CACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,gBAAgB,CAAC,EAAE,OAAO,EAC1B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO;IAWH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAQlE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;YAKrB,YAAY;CAa3B"}
package/dist/index.cjs.js CHANGED
@@ -16880,6 +16880,159 @@ function requireDomParser () {
16880
16880
 
16881
16881
  var domParserExports = requireDomParser();
16882
16882
 
16883
+ function buildAgentTree(agents) {
16884
+ // Detect and handle circular dependencies
16885
+ const safeAgents = detectAndBreakCycles(agents);
16886
+ if (safeAgents.length === 0) {
16887
+ throw new Error("No executable agent");
16888
+ }
16889
+ // Establish dependency relationship mapping
16890
+ const agentMap = new Map();
16891
+ const dependents = new Map();
16892
+ for (const agent of safeAgents) {
16893
+ agentMap.set(agent.id, agent);
16894
+ dependents.set(agent.id, []);
16895
+ }
16896
+ for (const agent of safeAgents) {
16897
+ for (const depId of agent.dependsOn) {
16898
+ if (dependents.has(depId)) {
16899
+ dependents.get(depId).push(agent);
16900
+ }
16901
+ }
16902
+ }
16903
+ let entryAgents = safeAgents.filter((agent) => agent.dependsOn.length === 0);
16904
+ if (entryAgents.length === 0) {
16905
+ entryAgents = safeAgents.filter((agent) => agent.dependsOn.length == 1 && agent.dependsOn[0].endsWith("00"));
16906
+ }
16907
+ const processedAgents = new Set();
16908
+ function buildNodeRecursive(currentAgents) {
16909
+ if (currentAgents.length === 0) {
16910
+ return undefined;
16911
+ }
16912
+ for (const agent of currentAgents) {
16913
+ processedAgents.add(agent.id);
16914
+ }
16915
+ const nextLevelAgents = [];
16916
+ const nextLevelSet = new Set();
16917
+ for (const agent of currentAgents) {
16918
+ const dependentAgents = dependents.get(agent.id) || [];
16919
+ for (const dependentAgent of dependentAgents) {
16920
+ const allDependenciesProcessed = dependentAgent.dependsOn.every((depId) => processedAgents.has(depId));
16921
+ if (allDependenciesProcessed && !nextLevelSet.has(dependentAgent.id)) {
16922
+ nextLevelAgents.push(dependentAgent);
16923
+ nextLevelSet.add(dependentAgent.id);
16924
+ }
16925
+ }
16926
+ }
16927
+ const nextNode = buildNodeRecursive(nextLevelAgents);
16928
+ if (currentAgents.length === 1) {
16929
+ return {
16930
+ type: "normal",
16931
+ agent: currentAgents[0],
16932
+ nextAgent: nextNode,
16933
+ };
16934
+ }
16935
+ else {
16936
+ const parallelNodes = currentAgents.map((agent) => ({
16937
+ type: "normal",
16938
+ agent: agent,
16939
+ nextAgent: undefined,
16940
+ }));
16941
+ return {
16942
+ type: "parallel",
16943
+ agents: parallelNodes,
16944
+ nextAgent: nextNode,
16945
+ };
16946
+ }
16947
+ }
16948
+ const rootNode = buildNodeRecursive(entryAgents);
16949
+ if (!rootNode) {
16950
+ throw new Error("Unable to build execution tree");
16951
+ }
16952
+ return rootNode;
16953
+ }
16954
+ function detectAndBreakCycles(agents) {
16955
+ // Detect cyclic dependencies and return a safe dependency relationship
16956
+ // Use topological sorting algorithm to detect cycles, if a cycle is found, break some dependencies.
16957
+ const agentMap = new Map();
16958
+ const inDegree = new Map();
16959
+ const adjList = new Map();
16960
+ for (const agent of agents) {
16961
+ agentMap.set(agent.id, agent);
16962
+ inDegree.set(agent.id, 0);
16963
+ adjList.set(agent.id, []);
16964
+ }
16965
+ for (const agent of agents) {
16966
+ for (const depId of agent.dependsOn) {
16967
+ if (agentMap.has(depId)) {
16968
+ // depId -> agent.id indicates that the agent depends on depId.
16969
+ adjList.get(depId).push(agent.id);
16970
+ inDegree.set(agent.id, inDegree.get(agent.id) + 1);
16971
+ }
16972
+ }
16973
+ }
16974
+ // Topological Sorting Detects Cycles
16975
+ const queue = [];
16976
+ const processedCount = new Map();
16977
+ for (const [agentId, degree] of inDegree.entries()) {
16978
+ if (degree === 0) {
16979
+ queue.push(agentId);
16980
+ }
16981
+ processedCount.set(agentId, 0);
16982
+ }
16983
+ let processedNodes = 0;
16984
+ while (queue.length > 0) {
16985
+ const currentId = queue.shift();
16986
+ processedNodes++;
16987
+ for (const neighborId of adjList.get(currentId)) {
16988
+ const newInDegree = inDegree.get(neighborId) - 1;
16989
+ inDegree.set(neighborId, newInDegree);
16990
+ if (newInDegree === 0) {
16991
+ queue.push(neighborId);
16992
+ }
16993
+ }
16994
+ }
16995
+ if (processedNodes < agents.length) {
16996
+ console.warn("Detected a circular dependency, automatically disconnecting the circular link...");
16997
+ const cyclicNodes = new Set();
16998
+ for (const [agentId, degree] of inDegree.entries()) {
16999
+ if (degree > 0) {
17000
+ cyclicNodes.add(agentId);
17001
+ }
17002
+ }
17003
+ const fixedAgents = [];
17004
+ for (const agent of agents) {
17005
+ if (cyclicNodes.has(agent.id)) {
17006
+ const filteredDependsOn = agent.dependsOn.filter((depId) => !cyclicNodes.has(depId) || !agentMap.has(depId));
17007
+ // Preserve the shortest path dependency
17008
+ if (filteredDependsOn.length === 0 && agent.dependsOn.length > 0) {
17009
+ const firstValidDep = agent.dependsOn.find((depId) => agentMap.has(depId));
17010
+ if (firstValidDep && !cyclicNodes.has(firstValidDep)) {
17011
+ filteredDependsOn.push(firstValidDep);
17012
+ }
17013
+ }
17014
+ agent.dependsOn = filteredDependsOn;
17015
+ fixedAgents.push(agent);
17016
+ if (filteredDependsOn.length !== agent.dependsOn.length) {
17017
+ console.warn(`The partial cyclic dependency of agent ${agent.id} has been disconnected.`);
17018
+ }
17019
+ }
17020
+ else {
17021
+ // Non-cyclic node, filter out non-existent dependencies
17022
+ const validDependsOn = agent.dependsOn.filter((depId) => agentMap.has(depId));
17023
+ agent.dependsOn = validDependsOn;
17024
+ fixedAgents.push(agent);
17025
+ }
17026
+ }
17027
+ return fixedAgents;
17028
+ }
17029
+ // No loops, just need to filter out non-existent dependencies
17030
+ return agents.map((agent) => {
17031
+ agent.dependsOn = agent.dependsOn.filter((depId) => agentMap.has(depId));
17032
+ return agent;
17033
+ });
17034
+ }
17035
+
16883
17036
  function parseWorkflow(taskId, xml, done, thinking) {
16884
17037
  let _workflow = null;
16885
17038
  try {
@@ -16936,6 +17089,8 @@ function parseWorkflow(taskId, xml, done, thinking) {
16936
17089
  dependsOn: dependsOn.split(",").filter(idx => idx.trim() != "").map(idx => getAgentId(taskId, idx)),
16937
17090
  task: agentNode.getElementsByTagName("task")[0]?.textContent || "",
16938
17091
  nodes: nodes,
17092
+ status: "init",
17093
+ parallel: undefined,
16939
17094
  xml: agentNode.toString(),
16940
17095
  };
16941
17096
  let xmlNodes = agentNode.getElementsByTagName("nodes");
@@ -16944,6 +17099,25 @@ function parseWorkflow(taskId, xml, done, thinking) {
16944
17099
  }
16945
17100
  agents.push(agent);
16946
17101
  }
17102
+ if (done) {
17103
+ let agentTree = buildAgentTree(workflow.agents);
17104
+ while (true) {
17105
+ if (agentTree.type === "normal") {
17106
+ agentTree.agent.parallel = false;
17107
+ }
17108
+ else {
17109
+ const parallelAgents = agentTree.agents;
17110
+ for (let i = 0; i < parallelAgents.length; i++) {
17111
+ const agentNode = parallelAgents[i];
17112
+ agentNode.agent.parallel = true;
17113
+ }
17114
+ }
17115
+ if (!agentTree.nextAgent) {
17116
+ break;
17117
+ }
17118
+ agentTree = agentTree.nextAgent;
17119
+ }
17120
+ }
16947
17121
  return workflow;
16948
17122
  }
16949
17123
  catch (e) {
@@ -17084,6 +17258,8 @@ function buildSimpleAgentWorkflow({ taskId, name, agentName, task, taskNodes, })
17084
17258
  text: node,
17085
17259
  };
17086
17260
  }),
17261
+ status: "init",
17262
+ parallel: false,
17087
17263
  xml: "",
17088
17264
  },
17089
17265
  ],
@@ -18325,7 +18501,7 @@ During the task execution process, you can use the \`${TOOL_NAME$3}\` tool to in
18325
18501
  `;
18326
18502
  const VARIABLE_PROMPT = `
18327
18503
  * VARIABLE STORAGE
18328
- If you need to read and write the input/output variables in the node, require the use of the \`${TOOL_NAME$1}\` tool.
18504
+ When a step node has input/output variable attributes, use the \`${TOOL_NAME$1}\` tool to read from and write to these variables, these variables enable context sharing and coordination between multiple agents.
18329
18505
  `;
18330
18506
  const FOR_EACH_NODE = `
18331
18507
  <!-- duplicate task node, items support list and variable -->
@@ -19199,163 +19375,6 @@ class Planner {
19199
19375
  }
19200
19376
  }
19201
19377
 
19202
- function buildAgentTree(agents) {
19203
- // Detect and handle circular dependencies
19204
- const safeAgents = detectAndBreakCycles(agents);
19205
- if (safeAgents.length === 0) {
19206
- throw new Error("No executable agent");
19207
- }
19208
- // Establish dependency relationship mapping
19209
- const agentMap = new Map();
19210
- const dependents = new Map();
19211
- for (const agent of safeAgents) {
19212
- agentMap.set(agent.id, agent);
19213
- dependents.set(agent.id, []);
19214
- }
19215
- for (const agent of safeAgents) {
19216
- for (const depId of agent.dependsOn) {
19217
- if (dependents.has(depId)) {
19218
- dependents.get(depId).push(agent);
19219
- }
19220
- }
19221
- }
19222
- let entryAgents = safeAgents.filter((agent) => agent.dependsOn.length === 0);
19223
- if (entryAgents.length === 0) {
19224
- entryAgents = safeAgents.filter((agent) => agent.dependsOn.length == 1 && agent.dependsOn[0].endsWith("00"));
19225
- }
19226
- const processedAgents = new Set();
19227
- function buildNodeRecursive(currentAgents) {
19228
- if (currentAgents.length === 0) {
19229
- return undefined;
19230
- }
19231
- for (const agent of currentAgents) {
19232
- processedAgents.add(agent.id);
19233
- }
19234
- const nextLevelAgents = [];
19235
- const nextLevelSet = new Set();
19236
- for (const agent of currentAgents) {
19237
- const dependentAgents = dependents.get(agent.id) || [];
19238
- for (const dependentAgent of dependentAgents) {
19239
- const allDependenciesProcessed = dependentAgent.dependsOn.every((depId) => processedAgents.has(depId));
19240
- if (allDependenciesProcessed && !nextLevelSet.has(dependentAgent.id)) {
19241
- nextLevelAgents.push(dependentAgent);
19242
- nextLevelSet.add(dependentAgent.id);
19243
- }
19244
- }
19245
- }
19246
- const nextNode = buildNodeRecursive(nextLevelAgents);
19247
- if (currentAgents.length === 1) {
19248
- return {
19249
- type: "normal",
19250
- agent: currentAgents[0],
19251
- nextAgent: nextNode,
19252
- };
19253
- }
19254
- else {
19255
- const parallelNodes = currentAgents.map((agent) => ({
19256
- type: "normal",
19257
- agent: agent,
19258
- nextAgent: undefined,
19259
- }));
19260
- return {
19261
- type: "parallel",
19262
- agents: parallelNodes,
19263
- nextAgent: nextNode,
19264
- };
19265
- }
19266
- }
19267
- const rootNode = buildNodeRecursive(entryAgents);
19268
- if (!rootNode) {
19269
- throw new Error("Unable to build execution tree");
19270
- }
19271
- return rootNode;
19272
- }
19273
- function detectAndBreakCycles(agents) {
19274
- // Detect cyclic dependencies and return a safe dependency relationship
19275
- // Use topological sorting algorithm to detect cycles, if a cycle is found, break some dependencies.
19276
- const agentMap = new Map();
19277
- const inDegree = new Map();
19278
- const adjList = new Map();
19279
- for (const agent of agents) {
19280
- agentMap.set(agent.id, agent);
19281
- inDegree.set(agent.id, 0);
19282
- adjList.set(agent.id, []);
19283
- }
19284
- for (const agent of agents) {
19285
- for (const depId of agent.dependsOn) {
19286
- if (agentMap.has(depId)) {
19287
- // depId -> agent.id indicates that the agent depends on depId.
19288
- adjList.get(depId).push(agent.id);
19289
- inDegree.set(agent.id, inDegree.get(agent.id) + 1);
19290
- }
19291
- }
19292
- }
19293
- // Topological Sorting Detects Cycles
19294
- const queue = [];
19295
- const processedCount = new Map();
19296
- for (const [agentId, degree] of inDegree.entries()) {
19297
- if (degree === 0) {
19298
- queue.push(agentId);
19299
- }
19300
- processedCount.set(agentId, 0);
19301
- }
19302
- let processedNodes = 0;
19303
- while (queue.length > 0) {
19304
- const currentId = queue.shift();
19305
- processedNodes++;
19306
- for (const neighborId of adjList.get(currentId)) {
19307
- const newInDegree = inDegree.get(neighborId) - 1;
19308
- inDegree.set(neighborId, newInDegree);
19309
- if (newInDegree === 0) {
19310
- queue.push(neighborId);
19311
- }
19312
- }
19313
- }
19314
- if (processedNodes < agents.length) {
19315
- console.warn("Detected a circular dependency, automatically disconnecting the circular link...");
19316
- const cyclicNodes = new Set();
19317
- for (const [agentId, degree] of inDegree.entries()) {
19318
- if (degree > 0) {
19319
- cyclicNodes.add(agentId);
19320
- }
19321
- }
19322
- const fixedAgents = [];
19323
- for (const agent of agents) {
19324
- if (cyclicNodes.has(agent.id)) {
19325
- const filteredDependsOn = agent.dependsOn.filter((depId) => !cyclicNodes.has(depId) || !agentMap.has(depId));
19326
- // Preserve the shortest path dependency
19327
- if (filteredDependsOn.length === 0 && agent.dependsOn.length > 0) {
19328
- const firstValidDep = agent.dependsOn.find((depId) => agentMap.has(depId));
19329
- if (firstValidDep && !cyclicNodes.has(firstValidDep)) {
19330
- filteredDependsOn.push(firstValidDep);
19331
- }
19332
- }
19333
- fixedAgents.push({
19334
- ...agent,
19335
- dependsOn: filteredDependsOn,
19336
- });
19337
- if (filteredDependsOn.length !== agent.dependsOn.length) {
19338
- console.warn(`The partial cyclic dependency of agent ${agent.id} has been disconnected.`);
19339
- }
19340
- }
19341
- else {
19342
- // Non-cyclic node, filter out non-existent dependencies
19343
- const validDependsOn = agent.dependsOn.filter((depId) => agentMap.has(depId));
19344
- fixedAgents.push({
19345
- ...agent,
19346
- dependsOn: validDependsOn,
19347
- });
19348
- }
19349
- }
19350
- return fixedAgents;
19351
- }
19352
- // No loops, just need to filter out non-existent dependencies
19353
- return agents.map((agent) => ({
19354
- ...agent,
19355
- dependsOn: agent.dependsOn.filter((depId) => agentMap.has(depId)),
19356
- }));
19357
- }
19358
-
19359
19378
  class Eko {
19360
19379
  constructor(config) {
19361
19380
  this.config = config;
@@ -19463,7 +19482,7 @@ class Eko {
19463
19482
  const agentNode = agentTree.agent;
19464
19483
  const agentChain = new AgentChain(agentNode);
19465
19484
  context.chain.push(agentChain);
19466
- agentTree.result = await agent.run(context, agentChain);
19485
+ agentTree.result = await this.runAgent(context, agent, agentTree, agentChain);
19467
19486
  results.push(agentTree.result);
19468
19487
  }
19469
19488
  else {
@@ -19475,8 +19494,9 @@ class Eko {
19475
19494
  throw new Error("Unknown Agent: " + agentNode.agent.name);
19476
19495
  }
19477
19496
  const agentChain = new AgentChain(agentNode.agent);
19478
- agentNode.result = await agent.run(context, agentChain);
19479
- return { result: agentNode.result, agentChain, index };
19497
+ context.chain.push(agentChain);
19498
+ const result = await this.runAgent(context, agent, agentNode, agentChain);
19499
+ return { result: result, agentChain, index };
19480
19500
  };
19481
19501
  let agent_results = [];
19482
19502
  let agentParallel = context.variables.get("agentParallel");
@@ -19515,6 +19535,44 @@ class Eko {
19515
19535
  taskId: context.taskId,
19516
19536
  };
19517
19537
  }
19538
+ async runAgent(context, agent, agentNode, agentChain) {
19539
+ try {
19540
+ agentNode.agent.status = "running";
19541
+ this.config.callback &&
19542
+ (await this.config.callback.onMessage({
19543
+ taskId: context.taskId,
19544
+ agentName: agentNode.agent.name,
19545
+ nodeId: agentNode.agent.id,
19546
+ type: "agent_start",
19547
+ agentNode: agentNode.agent,
19548
+ }));
19549
+ agentNode.result = await agent.run(context, agentChain);
19550
+ agentNode.agent.status = "done";
19551
+ this.config.callback &&
19552
+ (await this.config.callback.onMessage({
19553
+ taskId: context.taskId,
19554
+ agentName: agentNode.agent.name,
19555
+ nodeId: agentNode.agent.id,
19556
+ type: "agent_result",
19557
+ agentNode: agentNode.agent,
19558
+ result: agentNode.result,
19559
+ }, agent.AgentContext));
19560
+ return agentNode.result;
19561
+ }
19562
+ catch (e) {
19563
+ agentNode.agent.status = "error";
19564
+ this.config.callback &&
19565
+ (await this.config.callback.onMessage({
19566
+ taskId: context.taskId,
19567
+ agentName: agentNode.agent.name,
19568
+ nodeId: agentNode.agent.id,
19569
+ type: "agent_result",
19570
+ agentNode: agentNode.agent,
19571
+ error: e,
19572
+ }, agent.AgentContext));
19573
+ throw e;
19574
+ }
19575
+ }
19518
19576
  getTask(taskId) {
19519
19577
  return this.taskMap.get(taskId);
19520
19578
  }
@@ -21195,7 +21253,7 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
21195
21253
  constructor(llms, ext_tools, mcpClient) {
21196
21254
  const description = `You are a browser operation agent, use structured commands to interact with the browser.
21197
21255
  * This is a browser GUI interface where you need to analyze webpages by taking screenshot and page element structures, and specify action sequences to complete designated tasks.
21198
- * For the first visit, please call the \`navigate_to\` or \`current_page\` tool first. After that, each of your actions will return a screenshot of the page and structured element information, both of which have been specially processed.
21256
+ * For your first visit, please start by calling either the \`navigate_to\` or \`current_page\` tool. After each action you perform, I will provide you with updated information about the current state, including page screenshots and structured element data that has been specially processed for easier analysis.
21199
21257
  * Screenshot description:
21200
21258
  - Screenshot are used to understand page layouts, with labeled bounding boxes corresponding to element indexes. Each bounding box and its label share the same color, with labels typically positioned in the top-right corner of the box.
21201
21259
  - Screenshot help verify element positions and relationships. Labels may sometimes overlap, so extracted elements are used to verify the correct elements.
@@ -21213,7 +21271,7 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
21213
21271
  - Handle popups/cookies by accepting or closing them
21214
21272
  * BROWSER OPERATION:
21215
21273
  - Use scroll to find elements you are looking for, When extracting content, prioritize using extract_page_content, only scroll when you need to load more content
21216
- * During execution, please output user-friendly step information. Do not output element and index information to users, as this would cause user confusion.
21274
+ * During execution, please output user-friendly step information. Do not output HTML-related element and index information to users, as this would cause user confusion.
21217
21275
  `;
21218
21276
  const _tools_ = [];
21219
21277
  super({
@@ -21597,7 +21655,7 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
21597
21655
  return true;
21598
21656
  }
21599
21657
  async handleMessages(agentContext, messages, tools) {
21600
- const pseudoHtmlDescription = "This is the latest screenshot and page element information.\nindex and element:\n";
21658
+ const pseudoHtmlDescription = "This is the environmental information after the operation, including the latest browser screenshot and page elements. Please perform the next operation based on the environmental information. Do not output the following elements and index information in your response.\n\nIndex and elements:\n";
21601
21659
  let lastTool = this.lastToolResult(messages);
21602
21660
  if (lastTool &&
21603
21661
  lastTool.toolName !== "extract_page_content" &&
@@ -21627,7 +21685,7 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
21627
21685
  ...image_contents,
21628
21686
  {
21629
21687
  type: "text",
21630
- text: pseudoHtmlDescription + result.pseudoHtml,
21688
+ text: pseudoHtmlDescription + "```html\n" + result.pseudoHtml + "\n```",
21631
21689
  },
21632
21690
  ],
21633
21691
  });