@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.
- package/dist/common/xml.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/index.cjs.js +223 -165
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +223 -165
- package/dist/index.esm.js.map +1 -1
- package/dist/types/core.types.d.ts +10 -0
- package/dist/types/core.types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/common/xml.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -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;
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
19479
|
-
|
|
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
|
|
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
|
|
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
|
});
|