@eko-ai/eko 2.1.8 → 2.1.9-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/index.cjs.js CHANGED
@@ -9,6 +9,8 @@ const config = {
9
9
  platform: "mac",
10
10
  maxReactNum: 500,
11
11
  maxTokens: 16000,
12
+ maxRetryNum: 3,
13
+ agentParallel: false,
12
14
  compressThreshold: 80,
13
15
  largeTextLength: 5000,
14
16
  fileTextMaxLength: 20000,
@@ -323,6 +325,8 @@ function fixXmlTag(code) {
323
325
  code += '""';
324
326
  }
325
327
  else if (endStr == "name" ||
328
+ endStr == "id" ||
329
+ endStr == "dependsOn" ||
326
330
  endStr == "input" ||
327
331
  endStr == "output" ||
328
332
  endStr == "items" ||
@@ -388,13 +392,13 @@ class Context {
388
392
  this.variables = new Map();
389
393
  this.controller = new AbortController();
390
394
  }
391
- async checkAborted() {
395
+ async checkAborted(noCheckPause) {
392
396
  if (this.controller.signal.aborted) {
393
397
  const error = new Error("Operation was interrupted");
394
398
  error.name = "AbortError";
395
399
  throw error;
396
400
  }
397
- while (this.pauseStatus > 0) {
401
+ while (this.pauseStatus > 0 && !noCheckPause) {
398
402
  await sleep(500);
399
403
  if (this.pauseStatus == 2) {
400
404
  this.currentStepControllers.forEach((c) => {
@@ -14157,10 +14161,11 @@ createOpenRouter({
14157
14161
  });
14158
14162
 
14159
14163
  class RetryLanguageModel {
14160
- constructor(llms, names, stream_first_timeout) {
14164
+ constructor(llms, names, stream_first_timeout, stream_token_timeout) {
14161
14165
  this.llms = llms;
14162
14166
  this.names = names || [];
14163
14167
  this.stream_first_timeout = stream_first_timeout || 30000;
14168
+ this.stream_token_timeout = stream_token_timeout || 180000;
14164
14169
  if (this.names.indexOf("default") == -1) {
14165
14170
  this.names.push("default");
14166
14171
  }
@@ -14178,6 +14183,7 @@ class RetryLanguageModel {
14178
14183
  temperature: request.temperature,
14179
14184
  topP: request.topP,
14180
14185
  topK: request.topK,
14186
+ stopSequences: request.stopSequences,
14181
14187
  abortSignal: request.abortSignal,
14182
14188
  });
14183
14189
  }
@@ -14188,25 +14194,29 @@ class RetryLanguageModel {
14188
14194
  let lastError;
14189
14195
  for (let i = 0; i < names.length; i++) {
14190
14196
  const name = names[i];
14197
+ const llmConfig = this.llms[name];
14191
14198
  const llm = await this.getLLM(name);
14192
14199
  if (!llm) {
14193
14200
  continue;
14194
14201
  }
14195
14202
  if (!maxTokens) {
14196
- options.maxTokens =
14197
- this.llms[name].config?.maxTokens || config.maxTokens;
14203
+ options.maxTokens = llmConfig.config?.maxTokens || config.maxTokens;
14198
14204
  }
14199
14205
  if (!providerMetadata) {
14200
14206
  options.providerMetadata = {};
14201
- options.providerMetadata[llm.provider] = this.llms[name].options || {};
14207
+ options.providerMetadata[llm.provider] = llmConfig.options || {};
14208
+ }
14209
+ let _options = options;
14210
+ if (llmConfig.handler) {
14211
+ _options = await llmConfig.handler(_options);
14202
14212
  }
14203
14213
  try {
14204
- let result = (await llm.doGenerate(options));
14214
+ let result = (await llm.doGenerate(_options));
14205
14215
  if (Log.isEnableDebug()) {
14206
14216
  Log.debug(`LLM nonstream body, name: ${name} => `, result.request?.body);
14207
14217
  }
14208
14218
  result.llm = name;
14209
- result.llmConfig = this.llms[name];
14219
+ result.llmConfig = llmConfig;
14210
14220
  return result;
14211
14221
  }
14212
14222
  catch (e) {
@@ -14216,8 +14226,8 @@ class RetryLanguageModel {
14216
14226
  lastError = e;
14217
14227
  if (Log.isEnableInfo()) {
14218
14228
  Log.info(`LLM nonstream request, name: ${name} => `, {
14219
- tools: options.mode?.tools,
14220
- messages: options.prompt,
14229
+ tools: _options.mode?.tools,
14230
+ messages: _options.prompt,
14221
14231
  });
14222
14232
  }
14223
14233
  Log.error(`LLM error, name: ${name} => `, e);
@@ -14238,6 +14248,7 @@ class RetryLanguageModel {
14238
14248
  temperature: request.temperature,
14239
14249
  topP: request.topP,
14240
14250
  topK: request.topK,
14251
+ stopSequences: request.stopSequences,
14241
14252
  abortSignal: request.abortSignal,
14242
14253
  });
14243
14254
  }
@@ -14248,24 +14259,28 @@ class RetryLanguageModel {
14248
14259
  let lastError;
14249
14260
  for (let i = 0; i < names.length; i++) {
14250
14261
  const name = names[i];
14262
+ const llmConfig = this.llms[name];
14251
14263
  const llm = await this.getLLM(name);
14252
14264
  if (!llm) {
14253
14265
  continue;
14254
14266
  }
14255
14267
  if (!maxTokens) {
14256
- options.maxTokens =
14257
- this.llms[name].config?.maxTokens || config.maxTokens;
14268
+ options.maxTokens = llmConfig.config?.maxTokens || config.maxTokens;
14258
14269
  }
14259
14270
  if (!providerMetadata) {
14260
14271
  options.providerMetadata = {};
14261
- options.providerMetadata[llm.provider] = this.llms[name].options || {};
14272
+ options.providerMetadata[llm.provider] = llmConfig.options || {};
14273
+ }
14274
+ let _options = options;
14275
+ if (llmConfig.handler) {
14276
+ _options = await llmConfig.handler(_options);
14262
14277
  }
14263
14278
  try {
14264
14279
  const controller = new AbortController();
14265
- const signal = options.abortSignal
14266
- ? AbortSignal.any([options.abortSignal, controller.signal])
14280
+ const signal = _options.abortSignal
14281
+ ? AbortSignal.any([_options.abortSignal, controller.signal])
14267
14282
  : controller.signal;
14268
- const result = (await call_timeout(async () => await llm.doStream({ ...options, abortSignal: signal }), this.stream_first_timeout, (e) => {
14283
+ const result = (await call_timeout(async () => await llm.doStream({ ..._options, abortSignal: signal }), this.stream_first_timeout, (e) => {
14269
14284
  controller.abort();
14270
14285
  }));
14271
14286
  const stream = result.stream;
@@ -14290,8 +14305,8 @@ class RetryLanguageModel {
14290
14305
  continue;
14291
14306
  }
14292
14307
  result.llm = name;
14293
- result.llmConfig = this.llms[name];
14294
- result.stream = this.streamWrapper([chunk], reader);
14308
+ result.llmConfig = llmConfig;
14309
+ result.stream = this.streamWrapper([chunk], reader, controller);
14295
14310
  return result;
14296
14311
  }
14297
14312
  catch (e) {
@@ -14301,8 +14316,8 @@ class RetryLanguageModel {
14301
14316
  lastError = e;
14302
14317
  if (Log.isEnableInfo()) {
14303
14318
  Log.info(`LLM stream request, name: ${name} => `, {
14304
- tools: options.mode?.tools,
14305
- messages: options.prompt,
14319
+ tools: _options.mode?.tools,
14320
+ messages: _options.prompt,
14306
14321
  });
14307
14322
  }
14308
14323
  Log.error(`LLM error, name: ${name} => `, e);
@@ -14383,7 +14398,8 @@ class RetryLanguageModel {
14383
14398
  return llm.provider.languageModel(llm.model);
14384
14399
  }
14385
14400
  }
14386
- streamWrapper(parts, reader) {
14401
+ streamWrapper(parts, reader, abortController) {
14402
+ let timer = null;
14387
14403
  return new ReadableStream({
14388
14404
  start: (controller) => {
14389
14405
  if (parts != null && parts.length > 0) {
@@ -14393,7 +14409,11 @@ class RetryLanguageModel {
14393
14409
  }
14394
14410
  },
14395
14411
  pull: async (controller) => {
14412
+ timer = setTimeout(() => {
14413
+ abortController.abort("Streaming request timeout");
14414
+ }, this.stream_token_timeout);
14396
14415
  const { done, value } = await reader.read();
14416
+ clearTimeout(timer);
14397
14417
  if (done) {
14398
14418
  controller.close();
14399
14419
  reader.releaseLock();
@@ -14402,6 +14422,7 @@ class RetryLanguageModel {
14402
14422
  controller.enqueue(value);
14403
14423
  },
14404
14424
  cancel: (reason) => {
14425
+ timer && clearTimeout(timer);
14405
14426
  reader.cancel(reason);
14406
14427
  },
14407
14428
  });
@@ -16859,6 +16880,159 @@ function requireDomParser () {
16859
16880
 
16860
16881
  var domParserExports = requireDomParser();
16861
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
+
16862
17036
  function parseWorkflow(taskId, xml, done, thinking) {
16863
17037
  let _workflow = null;
16864
17038
  try {
@@ -16906,12 +17080,17 @@ function parseWorkflow(taskId, xml, done, thinking) {
16906
17080
  if (!name) {
16907
17081
  break;
16908
17082
  }
17083
+ let index = agentNode.getAttribute("id") || i;
17084
+ let dependsOn = agentNode.getAttribute("dependsOn") || "";
16909
17085
  let nodes = [];
16910
17086
  let agent = {
16911
17087
  name: name,
16912
- id: taskId + "-" + (i < 10 ? "0" + i : i),
17088
+ id: getAgentId(taskId, index),
17089
+ dependsOn: dependsOn.split(",").filter(idx => idx.trim() != "").map(idx => getAgentId(taskId, idx)),
16913
17090
  task: agentNode.getElementsByTagName("task")[0]?.textContent || "",
16914
17091
  nodes: nodes,
17092
+ status: "init",
17093
+ parallel: undefined,
16915
17094
  xml: agentNode.toString(),
16916
17095
  };
16917
17096
  let xmlNodes = agentNode.getElementsByTagName("nodes");
@@ -16920,6 +17099,25 @@ function parseWorkflow(taskId, xml, done, thinking) {
16920
17099
  }
16921
17100
  agents.push(agent);
16922
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
+ }
16923
17121
  return workflow;
16924
17122
  }
16925
17123
  catch (e) {
@@ -16931,6 +17129,9 @@ function parseWorkflow(taskId, xml, done, thinking) {
16931
17129
  }
16932
17130
  }
16933
17131
  }
17132
+ function getAgentId(taskId, index) {
17133
+ return taskId + "-" + (+index < 10 ? "0" + index : index);
17134
+ }
16934
17135
  function parseWorkflowNodes(nodes, xmlNodes) {
16935
17136
  for (let i = 0; i < xmlNodes.length; i++) {
16936
17137
  if (xmlNodes[i].nodeType !== 1) {
@@ -17048,6 +17249,7 @@ function buildSimpleAgentWorkflow({ taskId, name, agentName, task, taskNodes, })
17048
17249
  agents: [
17049
17250
  {
17050
17251
  id: taskId + "-00",
17252
+ dependsOn: [],
17051
17253
  name: agentName,
17052
17254
  task: task,
17053
17255
  nodes: taskNodes.map((node) => {
@@ -17056,6 +17258,8 @@ function buildSimpleAgentWorkflow({ taskId, name, agentName, task, taskNodes, })
17056
17258
  text: node,
17057
17259
  };
17058
17260
  }),
17261
+ status: "init",
17262
+ parallel: false,
17059
17263
  xml: "",
17060
17264
  },
17061
17265
  ],
@@ -17069,6 +17273,7 @@ function resetWorkflowXml(workflow) {
17069
17273
  const agents = [];
17070
17274
  for (let i = 0; i < workflow.agents.length; i++) {
17071
17275
  const agent = workflow.agents[i];
17276
+ const agentDependsAttr = ` id="${i}" dependsOn="${(agent.dependsOn || []).filter(s => parseInt(s.split("-")[s.split("-").length - 1])).join(",")}"`;
17072
17277
  const nodes = agent.nodes
17073
17278
  .map((node) => {
17074
17279
  if (node.type == "forEach") {
@@ -17105,7 +17310,7 @@ ${watchNodes.join("\n")}
17105
17310
  }
17106
17311
  })
17107
17312
  .join("\n");
17108
- const agentXml = ` <agent name="${agent.name}">
17313
+ const agentXml = ` <agent name="${agent.name}"${agentDependsAttr}>
17109
17314
  <task>${agent.task}</task>
17110
17315
  <nodes>
17111
17316
  ${nodes}
@@ -17172,7 +17377,7 @@ class TaskSnapshotTool {
17172
17377
  }
17173
17378
  }
17174
17379
 
17175
- async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, retry, callback) {
17380
+ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, retryNum = 0, callback, requestHandler) {
17176
17381
  await agentContext.context.checkAborted();
17177
17382
  if (messages.length >= config.compressThreshold && !noCompress) {
17178
17383
  await compressAgentMessages(agentContext, rlm, messages, tools);
@@ -17199,6 +17404,7 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
17199
17404
  messages: messages,
17200
17405
  abortSignal: signal,
17201
17406
  };
17407
+ requestHandler && requestHandler(request);
17202
17408
  agentChain.agentRequest = request;
17203
17409
  let result;
17204
17410
  try {
@@ -17209,13 +17415,13 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
17209
17415
  context.currentStepControllers.delete(stepController);
17210
17416
  await context.checkAborted();
17211
17417
  if (!noCompress &&
17212
- messages.length > 10 &&
17418
+ messages.length >= 5 &&
17213
17419
  ((e + "").indexOf("tokens") > -1 || (e + "").indexOf("too long") > -1)) {
17214
17420
  await compressAgentMessages(agentContext, rlm, messages, tools);
17215
17421
  }
17216
- if (!retry) {
17217
- await sleep(200);
17218
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
17422
+ if (retryNum < config.maxRetryNum) {
17423
+ await sleep(200 * (retryNum + 1) * (retryNum + 1));
17424
+ return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
17219
17425
  }
17220
17426
  throw e;
17221
17427
  }
@@ -17394,11 +17600,11 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
17394
17600
  usage: chunk.usage,
17395
17601
  }, agentContext);
17396
17602
  if (chunk.finishReason === "length" &&
17397
- messages.length >= 10 &&
17603
+ messages.length >= 5 &&
17398
17604
  !noCompress &&
17399
- !retry) {
17605
+ retryNum < config.maxRetryNum) {
17400
17606
  await compressAgentMessages(agentContext, rlm, messages, tools);
17401
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
17607
+ return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
17402
17608
  }
17403
17609
  break;
17404
17610
  }
@@ -17407,8 +17613,9 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
17407
17613
  }
17408
17614
  catch (e) {
17409
17615
  await context.checkAborted();
17410
- if (!retry) {
17411
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
17616
+ if (retryNum < config.maxRetryNum) {
17617
+ await sleep(200 * (retryNum + 1) * (retryNum + 1));
17618
+ return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
17412
17619
  }
17413
17620
  throw e;
17414
17621
  }
@@ -17429,7 +17636,8 @@ function appendUserConversation(agentContext, messages) {
17429
17636
  .splice(0, agentContext.context.conversation.length)
17430
17637
  .filter((s) => !!s);
17431
17638
  if (userPrompts.length > 0) {
17432
- const prompt = "The user is intervening in the current task. Please replan and execute according to the following instructions:\n" + userPrompts.map(s => `- ${s.trim()}`).join("\n");
17639
+ const prompt = "The user is intervening in the current task, please replan and execute according to the following instructions:\n" +
17640
+ userPrompts.map((s) => `- ${s.trim()}`).join("\n");
17433
17641
  messages.push({
17434
17642
  role: "user",
17435
17643
  content: [{ type: "text", text: prompt }],
@@ -17481,9 +17689,17 @@ function removeDuplicateToolUse(results) {
17481
17689
  return _results;
17482
17690
  }
17483
17691
  async function compressAgentMessages(agentContext, rlm, messages, tools) {
17484
- if (messages.length < 10) {
17692
+ if (messages.length < 5) {
17485
17693
  return;
17486
17694
  }
17695
+ try {
17696
+ doCompressAgentMessages(agentContext, rlm, messages, tools);
17697
+ }
17698
+ catch (e) {
17699
+ Log.error("Error compressing agent messages:", e);
17700
+ }
17701
+ }
17702
+ async function doCompressAgentMessages(agentContext, rlm, messages, tools) {
17487
17703
  // extract used tool
17488
17704
  let usedTools = extractUsedTool(messages, tools);
17489
17705
  let snapshotTool = new TaskSnapshotTool();
@@ -17605,7 +17821,8 @@ function handleLargeContextMessages(messages) {
17605
17821
  }
17606
17822
  for (let r = 0; r < toolContent.length; r++) {
17607
17823
  let _content = toolContent[r];
17608
- if (_content.type == "text" && _content.text?.length > config.largeTextLength) {
17824
+ if (_content.type == "text" &&
17825
+ _content.text?.length > config.largeTextLength) {
17609
17826
  if (!longTextTools[toolResult.toolName]) {
17610
17827
  longTextTools[toolResult.toolName] = 1;
17611
17828
  break;
@@ -18378,6 +18595,7 @@ class Agent {
18378
18595
  this.llms = params.llms;
18379
18596
  this.mcpClient = params.mcpClient;
18380
18597
  this.planDescription = params.planDescription;
18598
+ this.requestHandler = params.requestHandler;
18381
18599
  }
18382
18600
  async run(context, agentChain) {
18383
18601
  let mcpClient = this.mcpClient || context.config.defaultMcpClient;
@@ -18423,7 +18641,7 @@ class Agent {
18423
18641
  }
18424
18642
  }
18425
18643
  await this.handleMessages(agentContext, messages, tools);
18426
- let results = await callAgentLLM(agentContext, rlm, messages, this.convertTools(agentTools), false, undefined, false, this.callback);
18644
+ let results = await callAgentLLM(agentContext, rlm, messages, this.convertTools(agentTools), false, undefined, 0, this.callback, this.requestHandler);
18427
18645
  let finalResult = await this.handleCallResult(agentContext, messages, agentTools, results);
18428
18646
  if (finalResult) {
18429
18647
  return finalResult;
@@ -18433,6 +18651,10 @@ class Agent {
18433
18651
  return "Unfinished";
18434
18652
  }
18435
18653
  async handleCallResult(agentContext, messages, agentTools, results) {
18654
+ const forceStop = agentContext.variables.get("forceStop");
18655
+ if (forceStop) {
18656
+ return forceStop;
18657
+ }
18436
18658
  let text = null;
18437
18659
  let context = agentContext.context;
18438
18660
  let user_messages = [];
@@ -18721,11 +18943,11 @@ class Agent {
18721
18943
  }
18722
18944
  }
18723
18945
 
18724
- const AGENT_NAME$5 = "Chat";
18946
+ const AGENT_NAME$4 = "Chat";
18725
18947
  class BaseChatAgent extends Agent {
18726
18948
  constructor(llms, ext_tools, mcpClient) {
18727
18949
  super({
18728
- name: AGENT_NAME$5,
18950
+ name: AGENT_NAME$4,
18729
18951
  description: "You are a helpful assistant.",
18730
18952
  tools: ext_tools || [],
18731
18953
  llms: llms,
@@ -18759,8 +18981,13 @@ Your task is to understand the user's requirements, dynamically plan the user's
18759
18981
  <thought>Your thought process on user demand planning</thought>
18760
18982
  <!-- Multiple Agents work together to complete the task -->
18761
18983
  <agents>
18762
- <!-- The required Agent, where the name can only be an available name in the Agent list -->
18763
- <agent name="Agent name">
18984
+ <!--
18985
+ Multi-Agent supports parallelism, coordinating parallel tasks through dependencies, and passing dependent context information through node variables.
18986
+ name: The name of the Agent, where the name can only be an available name in the Agent list.
18987
+ id: Use subscript order as ID for dependency relationships between multiple agents.
18988
+ dependsOn: The IDs of agents that the current agent depends on, separated by commas when there are multiple dependencies.
18989
+ -->
18990
+ <agent name="Agent name" id="0" dependsOn="">
18764
18991
  <!-- The current Agent needs to complete the task -->
18765
18992
  <task>current agent task</task>
18766
18993
  <nodes>
@@ -18782,6 +19009,22 @@ Your task is to understand the user's requirements, dynamically plan the user's
18782
19009
  </watch>
18783
19010
  </nodes>
18784
19011
  </agent>
19012
+ <!--
19013
+ Multi-agent Collaboration Dependency Example:
19014
+
19015
+ Execution Flow:
19016
+ 1. Agent 0: Initial agent with no dependencies (executes first)
19017
+ 2. Agent 1: Depends on Agent 0 completion (executes after Agent 0)
19018
+ 3. Agent 2 & 3: Both depend on Agent 1 completion (execute in parallel after Agent 1)
19019
+ 4. Agent 4: Depends on both Agent 2 and Agent 3 completion (executes last)
19020
+
19021
+ Dependency Chain: Agent 0 → Agent 1 → (Agent 2 ∥ Agent 3) → Agent 4
19022
+ -->
19023
+ <agent name="Agent name" id="0" dependsOn="">...</agent>
19024
+ <agent name="Agent name" id="1" dependsOn="0">...</agent>
19025
+ <agent name="Agent name" id="2" dependsOn="1">...</agent>
19026
+ <agent name="Agent name" id="3" dependsOn="1">...</agent>
19027
+ <agent name="Agent name" id="4" dependsOn="2,3">...</agent>
18785
19028
  </agents>
18786
19029
  </root>
18787
19030
 
@@ -18794,7 +19037,7 @@ Output result:
18794
19037
  <thought>Alright, the user wrote "hello". That's pretty straightforward. I need to respond in a friendly and welcoming manner.</thought>
18795
19038
  <agents>
18796
19039
  <!-- Chat agents can exist without the <task> and <nodes> nodes. -->
18797
- <agent name="Chat"></agent>
19040
+ <agent name="Chat" id="0" dependsOn=""></agent>
18798
19041
  </agents>
18799
19042
  </root>`;
18800
19043
  const PLAN_EXAMPLE_LIST = [
@@ -18804,7 +19047,7 @@ Output result:
18804
19047
  <name>Submit resume</name>
18805
19048
  <thought>OK, now the user requests me to create a workflow that involves opening the Boss Zhipin website, finding 10 operation positions in Chengdu, and sending personal resumes to the recruiters based on the job information.</thought>
18806
19049
  <agents>
18807
- <agent name="Browser">
19050
+ <agent name="Browser" id="0" dependsOn="">
18808
19051
  <task>Open Boss Zhipin, find 10 operation positions in Chengdu, and send a personal introduction to the recruiters based on the page information.</task>
18809
19052
  <nodes>
18810
19053
  <node>Open Boss Zhipin, enter the job search page</node>
@@ -18824,7 +19067,7 @@ Output result:
18824
19067
  <name>Latest AI News</name>
18825
19068
  <thought>OK, users need to collect the latest AI news, summarize it, and send it to a WeChat group named "AI news information" This requires automation, including the steps of data collection, processing, and distribution.</thought>
18826
19069
  <agents>
18827
- <agent name="Browser">
19070
+ <agent name="Browser" id="0" dependsOn="">
18828
19071
  <task>Search for the latest updates on AI</task>
18829
19072
  <nodes>
18830
19073
  <node>Open Google</node>
@@ -18835,7 +19078,7 @@ Output result:
18835
19078
  <node output="summaryInfo">Summarize search information</node>
18836
19079
  </nodes>
18837
19080
  </agent>
18838
- <agent name="Computer">
19081
+ <agent name="Computer" id="1" dependsOn="0">
18839
19082
  <task>Send a message to the WeChat group chat "AI news information"</task>
18840
19083
  <nodes>
18841
19084
  <node>Open WeChat</node>
@@ -18851,7 +19094,7 @@ Output result:
18851
19094
  <name>Statistics of Google Team Developers' Geographic Distribution</name>
18852
19095
  <thought>Okay, I need to first visit GitHub, then find Google's organization page on GitHub, extract the team member list, and individually visit each developer's homepage to obtain location information for each developer. This requires using a browser to complete all operations.</thought>
18853
19096
  <agents>
18854
- <agent name="Browser">
19097
+ <agent name="Browser" id="0" dependsOn="">
18855
19098
  <task>Visit Google GitHub Organization Page and Analyze Developer Geographic Distribution</task>
18856
19099
  <nodes>
18857
19100
  <node>Visit https://github.com/google</node>
@@ -18873,7 +19116,7 @@ Output result:
18873
19116
  <name>Automatic reply to Discord messages</name>
18874
19117
  <thought>OK, monitor the chat messages in Discord group A and automatically reply.</thought>
18875
19118
  <agents>
18876
- <agent name="Browser">
19119
+ <agent name="Browser" id="0" dependsOn="">
18877
19120
  <task>Open Group A in Discord</task>
18878
19121
  <nodes>
18879
19122
  <node>Open Discord page</node>
@@ -18888,6 +19131,59 @@ Output result:
18888
19131
  </nodes>
18889
19132
  </agent>
18890
19133
  </agents>
19134
+ </root>`,
19135
+ `User: Search for information about "fellou," compile the results into a summary profile, then share it across social media platforms including Twitter, Facebook, and Reddit. Finally, export the platform sharing operation results to an Excel file.
19136
+ Output result:
19137
+ <root>
19138
+ <name>Fellou Research and Social Media Campaign</name>
19139
+ <thought>The user wants me to research information about 'Fellou', create a summary profile, share it on multiple social media platforms (Twitter, Facebook, Reddit), and then compile the results into an Excel file. This requires multiple agents working together: Browser for research, Browser for social media posting (Twitter, Facebook, and Reddit in parallel), and File for creating the Excel export. I need to break this down into sequential steps with proper variable passing between agents.</thought>
19140
+ <agents>
19141
+ <agent name="Browser" id="0" dependsOn="">
19142
+ <task>Research comprehensive information about 'Fellou'</task>
19143
+ <nodes>
19144
+ <node>Search for the latest information about 'Fellou' - its identity, purpose, and core features</node>
19145
+ <node>Search for Fellou's functionalities, capabilities, and technical specifications</node>
19146
+ <node>Search for recent news, updates, announcements, and developments related to Fellou</node>
19147
+ <node>Search for user reviews, feedback, and community discussions about Fellou</node>
19148
+ <node>Search for Fellou's market position, competitors, and industry context</node>
19149
+ <node output="researchData">Compile all research findings into a comprehensive summary profile</node>
19150
+ </nodes>
19151
+ </agent>
19152
+ <agent name="Browser" id="1" dependsOn="0">
19153
+ <task>Share Fellou's summary and collected interaction data on Twitter/X</task>
19154
+ <nodes>
19155
+ <node>Navigate to Twitter/X platform</node>
19156
+ <node input="researchData">Create and post Twitter-optimized content about Fellou (within character limits, using hashtags)</node>
19157
+ <node output="twitterResults">Capture Twitter post URL and initial engagement metrics</node>
19158
+ </nodes>
19159
+ </agent>
19160
+ <agent name="Browser" id="2" dependsOn="0">
19161
+ <task>Share Fellou's summary and collected interaction data on Facebook</task>
19162
+ <nodes>
19163
+ <node>Navigate to Facebook platform</node>
19164
+ <node input="researchData">Create and post Facebook-optimized content about Fellou (longer format, engaging description)</node>
19165
+ <node output="facebookResults">Capture Facebook post URL and initial engagement metrics</node>
19166
+ </nodes>
19167
+ </agent>
19168
+ <agent name="Browser" id="3" dependsOn="0">
19169
+ <task>Share Fellou's summary and collected interaction data on Reddit</task>
19170
+ <nodes>
19171
+ <node>Navigate to Reddit platform</node>
19172
+ <node input="researchData">Find appropriate subreddit and create Reddit-optimized post about Fellou (community-focused, informative)</node>
19173
+ <node output="redditResults">Capture Reddit post URL and initial engagement metrics</node>
19174
+ </nodes>
19175
+ </agent>
19176
+ <agent name="File" id="4" dependsOn="1,2,3">
19177
+ <task>Compile social media results into Excel file</task>
19178
+ <nodes>
19179
+ <node input="twitterResults,facebookResults,redditResults">Create Excel file with social media campaign results</node>
19180
+ <node>Include columns for Platform, Post URL, Content Summary, Timestamp, Initial Likes/Shares/Comments</node>
19181
+ <node>Format the Excel file with proper headers and styling</node>
19182
+ <node>Save the file as 'Fellou_Social_Media_Campaign_Results.xlsx'</node>
19183
+ </nodes>
19184
+ </agent>
19185
+ </agents>
19186
+ </agents>
18891
19187
  </root>`,
18892
19188
  ];
18893
19189
  const PLAN_USER_TEMPLATE = `
@@ -18918,7 +19214,7 @@ async function getPlanSystemPrompt(context) {
18918
19214
  "\n</agent>\n\n";
18919
19215
  }
18920
19216
  let plan_example_list = context.variables.get("plan_example_list") || PLAN_EXAMPLE_LIST;
18921
- let hasChatAgent = context.agents.filter((a) => a.Name == AGENT_NAME$5).length > 0;
19217
+ let hasChatAgent = context.agents.filter((a) => a.Name == AGENT_NAME$4).length > 0;
18922
19218
  let example_prompt = "";
18923
19219
  const example_list = hasChatAgent
18924
19220
  ? [PLAN_CHAT_EXAMPLE, ...plan_example_list]
@@ -18951,9 +19247,10 @@ function getPlanUserPrompt(task_prompt, task_website, ext_prompt) {
18951
19247
  }
18952
19248
 
18953
19249
  class Planner {
18954
- constructor(context, taskId) {
19250
+ constructor(context, callback) {
18955
19251
  this.context = context;
18956
- this.taskId = taskId || context.taskId;
19252
+ this.taskId = context.taskId;
19253
+ this.callback = callback || context.config.callback;
18957
19254
  }
18958
19255
  async plan(taskPrompt, saveHistory = true) {
18959
19256
  let taskPromptStr;
@@ -19017,7 +19314,7 @@ class Planner {
19017
19314
  let thinkingText = "";
19018
19315
  try {
19019
19316
  while (true) {
19020
- await this.context.checkAborted();
19317
+ await this.context.checkAborted(true);
19021
19318
  const { done, value } = await reader.read();
19022
19319
  if (done) {
19023
19320
  break;
@@ -19033,10 +19330,10 @@ class Planner {
19033
19330
  if (chunk.type == "text-delta") {
19034
19331
  streamText += chunk.textDelta || "";
19035
19332
  }
19036
- if (config.callback) {
19333
+ if (this.callback) {
19037
19334
  let workflow = parseWorkflow(this.taskId, streamText, false, thinkingText);
19038
19335
  if (workflow) {
19039
- await config.callback.onMessage({
19336
+ await this.callback.onMessage({
19040
19337
  taskId: this.taskId,
19041
19338
  agentName: "Planer",
19042
19339
  type: "workflow",
@@ -19059,8 +19356,8 @@ class Planner {
19059
19356
  chain.planResult = streamText;
19060
19357
  }
19061
19358
  let workflow = parseWorkflow(this.taskId, streamText, true, thinkingText);
19062
- if (config.callback) {
19063
- await config.callback.onMessage({
19359
+ if (this.callback) {
19360
+ await this.callback.onMessage({
19064
19361
  taskId: this.taskId,
19065
19362
  agentName: "Planer",
19066
19363
  type: "workflow",
@@ -19085,18 +19382,18 @@ class Eko {
19085
19382
  }
19086
19383
  async generate(taskPrompt, taskId = uuidv4(), contextParams) {
19087
19384
  const agents = [...(this.config.agents || [])];
19088
- let chain = new Chain(taskPrompt);
19089
- let context = new Context(taskId, this.config, agents, chain);
19385
+ const chain = new Chain(taskPrompt);
19386
+ const context = new Context(taskId, this.config, agents, chain);
19090
19387
  if (contextParams) {
19091
19388
  Object.keys(contextParams).forEach((key) => context.variables.set(key, contextParams[key]));
19092
19389
  }
19093
19390
  try {
19094
19391
  this.taskMap.set(taskId, context);
19095
19392
  if (this.config.a2aClient) {
19096
- let a2aList = await this.config.a2aClient.listAgents(taskPrompt);
19393
+ const a2aList = await this.config.a2aClient.listAgents(taskPrompt);
19097
19394
  context.agents = mergeAgents(context.agents, a2aList);
19098
19395
  }
19099
- let planner = new Planner(context, taskId);
19396
+ const planner = new Planner(context);
19100
19397
  context.workflow = await planner.plan(taskPrompt);
19101
19398
  return context.workflow;
19102
19399
  }
@@ -19106,20 +19403,20 @@ class Eko {
19106
19403
  }
19107
19404
  }
19108
19405
  async modify(taskId, modifyTaskPrompt) {
19109
- let context = this.taskMap.get(taskId);
19406
+ const context = this.taskMap.get(taskId);
19110
19407
  if (!context) {
19111
19408
  return await this.generate(modifyTaskPrompt, taskId);
19112
19409
  }
19113
19410
  if (this.config.a2aClient) {
19114
- let a2aList = await this.config.a2aClient.listAgents(modifyTaskPrompt);
19411
+ const a2aList = await this.config.a2aClient.listAgents(modifyTaskPrompt);
19115
19412
  context.agents = mergeAgents(context.agents, a2aList);
19116
19413
  }
19117
- let planner = new Planner(context, taskId);
19414
+ const planner = new Planner(context);
19118
19415
  context.workflow = await planner.replan(modifyTaskPrompt);
19119
19416
  return context.workflow;
19120
19417
  }
19121
19418
  async execute(taskId) {
19122
- let context = this.getTask(taskId);
19419
+ const context = this.getTask(taskId);
19123
19420
  if (!context) {
19124
19421
  throw new Error("The task does not exist");
19125
19422
  }
@@ -19149,10 +19446,10 @@ class Eko {
19149
19446
  }
19150
19447
  async initContext(workflow, contextParams) {
19151
19448
  const agents = this.config.agents || [];
19152
- let chain = new Chain(workflow.taskPrompt || workflow.name);
19153
- let context = new Context(workflow.taskId, this.config, agents, chain);
19449
+ const chain = new Chain(workflow.taskPrompt || workflow.name);
19450
+ const context = new Context(workflow.taskId, this.config, agents, chain);
19154
19451
  if (this.config.a2aClient) {
19155
- let a2aList = await this.config.a2aClient.listAgents(workflow.taskPrompt || workflow.name);
19452
+ const a2aList = await this.config.a2aClient.listAgents(workflow.taskPrompt || workflow.name);
19156
19453
  context.agents = mergeAgents(context.agents, a2aList);
19157
19454
  }
19158
19455
  if (contextParams) {
@@ -19163,30 +19460,88 @@ class Eko {
19163
19460
  return context;
19164
19461
  }
19165
19462
  async doRunWorkflow(context) {
19166
- let agents = context.agents;
19167
- let workflow = context.workflow;
19463
+ const agents = context.agents;
19464
+ const workflow = context.workflow;
19168
19465
  if (!workflow || workflow.agents.length == 0) {
19169
19466
  throw new Error("Workflow error");
19170
19467
  }
19171
- let agentMap = agents.reduce((map, item) => {
19468
+ const agentNameMap = agents.reduce((map, item) => {
19172
19469
  map[item.Name] = item;
19173
19470
  return map;
19174
19471
  }, {});
19175
- let results = [];
19176
- for (let i = 0; i < workflow.agents.length; i++) {
19472
+ let agentTree = buildAgentTree(workflow.agents);
19473
+ const results = [];
19474
+ while (true) {
19177
19475
  await context.checkAborted();
19178
- let agentNode = workflow.agents[i];
19179
- let agent = agentMap[agentNode.name];
19180
- if (!agent) {
19181
- throw new Error("Unknown Agent: " + agentNode.name);
19182
- }
19183
- let agentChain = new AgentChain(agentNode);
19184
- context.chain.push(agentChain);
19185
- agent.result = await agent.run(context, agentChain);
19186
- results.push(agent.result);
19187
- if (agentNode.name === "Timer") {
19476
+ if (agentTree.type === "normal") {
19477
+ // normal agent
19478
+ const agent = agentNameMap[agentTree.agent.name];
19479
+ if (!agent) {
19480
+ throw new Error("Unknown Agent: " + agentTree.agent.name);
19481
+ }
19482
+ const agentNode = agentTree.agent;
19483
+ const agentChain = new AgentChain(agentNode);
19484
+ context.chain.push(agentChain);
19485
+ try {
19486
+ agentNode.status = "running";
19487
+ agentTree.result = await agent.run(context, agentChain);
19488
+ agentNode.status = "done";
19489
+ results.push(agentTree.result);
19490
+ }
19491
+ catch (e) {
19492
+ agentNode.status = "error";
19493
+ throw e;
19494
+ }
19495
+ }
19496
+ else {
19497
+ // parallel agent
19498
+ const parallelAgents = agentTree.agents;
19499
+ const doRunAgent = async (agentNode, index) => {
19500
+ const agent = agentNameMap[agentNode.agent.name];
19501
+ if (!agent) {
19502
+ throw new Error("Unknown Agent: " + agentNode.agent.name);
19503
+ }
19504
+ const agentChain = new AgentChain(agentNode.agent);
19505
+ try {
19506
+ agentNode.agent.status = "running";
19507
+ agentNode.result = await agent.run(context, agentChain);
19508
+ agentNode.agent.status = "done";
19509
+ }
19510
+ catch (e) {
19511
+ agentNode.agent.status = "error";
19512
+ throw e;
19513
+ }
19514
+ return { result: agentNode.result, agentChain, index };
19515
+ };
19516
+ let agent_results = [];
19517
+ let agentParallel = context.variables.get("agentParallel");
19518
+ if (agentParallel === undefined) {
19519
+ agentParallel = config.agentParallel;
19520
+ }
19521
+ if (agentParallel) {
19522
+ // parallel execution
19523
+ const parallelResults = await Promise.all(parallelAgents.map((agent, index) => doRunAgent(agent, index)));
19524
+ parallelResults.sort((a, b) => a.index - b.index);
19525
+ parallelResults.forEach(({ agentChain }) => {
19526
+ context.chain.push(agentChain);
19527
+ });
19528
+ agent_results = parallelResults.map(({ result }) => result);
19529
+ }
19530
+ else {
19531
+ // serial execution
19532
+ for (let i = 0; i < parallelAgents.length; i++) {
19533
+ const { result, agentChain } = await doRunAgent(parallelAgents[i], i);
19534
+ context.chain.push(agentChain);
19535
+ agent_results.push(result);
19536
+ }
19537
+ }
19538
+ results.push(agent_results.join("\n\n"));
19539
+ }
19540
+ context.conversation.splice(0, context.conversation.length);
19541
+ if (!agentTree.nextAgent) {
19188
19542
  break;
19189
19543
  }
19544
+ agentTree = agentTree.nextAgent;
19190
19545
  }
19191
19546
  return {
19192
19547
  success: true,
@@ -19222,7 +19577,7 @@ class Eko {
19222
19577
  }
19223
19578
  }
19224
19579
  pauseTask(taskId, pause, abortCurrentStep, reason) {
19225
- let context = this.taskMap.get(taskId);
19580
+ const context = this.taskMap.get(taskId);
19226
19581
  if (context) {
19227
19582
  this.onTaskStatus(context, pause ? "pause" : "resume-pause", reason);
19228
19583
  context.setPause(pause, abortCurrentStep);
@@ -19233,7 +19588,7 @@ class Eko {
19233
19588
  }
19234
19589
  }
19235
19590
  chatTask(taskId, userPrompt) {
19236
- let context = this.taskMap.get(taskId);
19591
+ const context = this.taskMap.get(taskId);
19237
19592
  if (context) {
19238
19593
  context.conversation.push(userPrompt);
19239
19594
  return context.conversation;
@@ -19476,7 +19831,7 @@ function parseChunk(chunk) {
19476
19831
  return chunk_obj;
19477
19832
  }
19478
19833
 
19479
- const AGENT_NAME$4 = "File";
19834
+ const AGENT_NAME$3 = "File";
19480
19835
  class BaseFileAgent extends Agent {
19481
19836
  constructor(work_path, llms, ext_tools, mcpClient, planDescription) {
19482
19837
  const _tools_ = [];
@@ -19484,7 +19839,7 @@ class BaseFileAgent extends Agent {
19484
19839
  ? `Your default working path is: ${work_path}`
19485
19840
  : "";
19486
19841
  super({
19487
- name: AGENT_NAME$4,
19842
+ name: AGENT_NAME$3,
19488
19843
  description: `You are a file agent, handling file-related tasks such as creating, finding, reading, modifying files, etc.${prompt}`,
19489
19844
  tools: _tools_,
19490
19845
  llms: llms,
@@ -19636,7 +19991,7 @@ class BaseFileAgent extends Agent {
19636
19991
  },
19637
19992
  glob: {
19638
19993
  type: "string",
19639
- description: "Filename pattern using glob syntax wildcards",
19994
+ description: "Filename pattern using glob syntax wildcards, Example: **/*.txt",
19640
19995
  },
19641
19996
  },
19642
19997
  required: ["path", "glob"],
@@ -19649,12 +20004,12 @@ class BaseFileAgent extends Agent {
19649
20004
  }
19650
20005
  }
19651
20006
 
19652
- const AGENT_NAME$3 = "Shell";
20007
+ const AGENT_NAME$2 = "Shell";
19653
20008
  class BaseShellAgent extends Agent {
19654
20009
  constructor(llms, ext_tools, mcpClient, planDescription) {
19655
20010
  const _tools_ = [];
19656
20011
  super({
19657
- name: AGENT_NAME$3,
20012
+ name: AGENT_NAME$2,
19658
20013
  description: `Run commands in a bash shell,
19659
20014
  * You must first call create_session to create a new session when using it for the first time.
19660
20015
  * Please execute delete commands with caution, and never perform dangerous operations like \`rm -rf /\`.
@@ -19731,47 +20086,6 @@ class BaseShellAgent extends Agent {
19731
20086
  }
19732
20087
  }
19733
20088
 
19734
- const AGENT_NAME$2 = "Timer";
19735
- class BaseTimerAgent extends Agent {
19736
- constructor(llms, ext_tools, mcpClient) {
19737
- super({
19738
- name: AGENT_NAME$2,
19739
- description: "You are a scheduled task scheduling agent.",
19740
- tools: ext_tools || [],
19741
- llms: llms,
19742
- mcpClient: mcpClient,
19743
- });
19744
- this.addTool(this.schedule_tool());
19745
- }
19746
- schedule_tool() {
19747
- return {
19748
- name: "task_schedule",
19749
- description: "Task scheduled trigger, the task is triggered at a scheduled time and will automatically create a scheduled task for execution.",
19750
- parameters: {
19751
- type: "object",
19752
- properties: {
19753
- trigger_description: {
19754
- type: "string",
19755
- description: "Trigger time description.",
19756
- },
19757
- task_description: {
19758
- type: "string",
19759
- description: "Main task description, excluding trigger time.",
19760
- },
19761
- cron: {
19762
- type: "string",
19763
- description: "The cron expression of the trigger, for example, '0 9 * * *' indicates that it triggers at 9 a.m. every day.",
19764
- },
19765
- },
19766
- required: ["cron"],
19767
- },
19768
- execute: async (args, agentContext) => {
19769
- return await this.callInnerTool(() => this.task_schedule(agentContext, args.trigger_description, args.task_description, args.cron));
19770
- },
19771
- };
19772
- }
19773
- }
19774
-
19775
20089
  const AGENT_NAME$1 = "Computer";
19776
20090
  class BaseComputerAgent extends Agent {
19777
20091
  constructor(llms, ext_tools, mcpClient, keyboardKeys) {
@@ -21968,7 +22282,6 @@ exports.BaseChatAgent = BaseChatAgent;
21968
22282
  exports.BaseComputerAgent = BaseComputerAgent;
21969
22283
  exports.BaseFileAgent = BaseFileAgent;
21970
22284
  exports.BaseShellAgent = BaseShellAgent;
21971
- exports.BaseTimerAgent = BaseTimerAgent;
21972
22285
  exports.Chain = Chain;
21973
22286
  exports.Context = Context;
21974
22287
  exports.Eko = Eko;
@@ -21981,6 +22294,7 @@ exports.SimpleSseMcpClient = SimpleSseMcpClient;
21981
22294
  exports.TaskNodeStatusTool = TaskNodeStatusTool;
21982
22295
  exports.VariableStorageTool = VariableStorageTool;
21983
22296
  exports.WatchTriggerTool = WatchTriggerTool;
22297
+ exports.buildAgentTree = buildAgentTree;
21984
22298
  exports.buildSimpleAgentWorkflow = buildSimpleAgentWorkflow;
21985
22299
  exports.call_timeout = call_timeout;
21986
22300
  exports.config = config;