@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.esm.js CHANGED
@@ -3,6 +3,8 @@ const config = {
3
3
  platform: "mac",
4
4
  maxReactNum: 500,
5
5
  maxTokens: 16000,
6
+ maxRetryNum: 3,
7
+ agentParallel: false,
6
8
  compressThreshold: 80,
7
9
  largeTextLength: 5000,
8
10
  fileTextMaxLength: 20000,
@@ -317,6 +319,8 @@ function fixXmlTag(code) {
317
319
  code += '""';
318
320
  }
319
321
  else if (endStr == "name" ||
322
+ endStr == "id" ||
323
+ endStr == "dependsOn" ||
320
324
  endStr == "input" ||
321
325
  endStr == "output" ||
322
326
  endStr == "items" ||
@@ -382,13 +386,13 @@ class Context {
382
386
  this.variables = new Map();
383
387
  this.controller = new AbortController();
384
388
  }
385
- async checkAborted() {
389
+ async checkAborted(noCheckPause) {
386
390
  if (this.controller.signal.aborted) {
387
391
  const error = new Error("Operation was interrupted");
388
392
  error.name = "AbortError";
389
393
  throw error;
390
394
  }
391
- while (this.pauseStatus > 0) {
395
+ while (this.pauseStatus > 0 && !noCheckPause) {
392
396
  await sleep(500);
393
397
  if (this.pauseStatus == 2) {
394
398
  this.currentStepControllers.forEach((c) => {
@@ -14122,10 +14126,11 @@ createOpenRouter({
14122
14126
  });
14123
14127
 
14124
14128
  class RetryLanguageModel {
14125
- constructor(llms, names, stream_first_timeout) {
14129
+ constructor(llms, names, stream_first_timeout, stream_token_timeout) {
14126
14130
  this.llms = llms;
14127
14131
  this.names = names || [];
14128
14132
  this.stream_first_timeout = stream_first_timeout || 30000;
14133
+ this.stream_token_timeout = stream_token_timeout || 180000;
14129
14134
  if (this.names.indexOf("default") == -1) {
14130
14135
  this.names.push("default");
14131
14136
  }
@@ -14143,6 +14148,7 @@ class RetryLanguageModel {
14143
14148
  temperature: request.temperature,
14144
14149
  topP: request.topP,
14145
14150
  topK: request.topK,
14151
+ stopSequences: request.stopSequences,
14146
14152
  abortSignal: request.abortSignal,
14147
14153
  });
14148
14154
  }
@@ -14153,25 +14159,29 @@ class RetryLanguageModel {
14153
14159
  let lastError;
14154
14160
  for (let i = 0; i < names.length; i++) {
14155
14161
  const name = names[i];
14162
+ const llmConfig = this.llms[name];
14156
14163
  const llm = await this.getLLM(name);
14157
14164
  if (!llm) {
14158
14165
  continue;
14159
14166
  }
14160
14167
  if (!maxTokens) {
14161
- options.maxTokens =
14162
- this.llms[name].config?.maxTokens || config.maxTokens;
14168
+ options.maxTokens = llmConfig.config?.maxTokens || config.maxTokens;
14163
14169
  }
14164
14170
  if (!providerMetadata) {
14165
14171
  options.providerMetadata = {};
14166
- options.providerMetadata[llm.provider] = this.llms[name].options || {};
14172
+ options.providerMetadata[llm.provider] = llmConfig.options || {};
14173
+ }
14174
+ let _options = options;
14175
+ if (llmConfig.handler) {
14176
+ _options = await llmConfig.handler(_options);
14167
14177
  }
14168
14178
  try {
14169
- let result = (await llm.doGenerate(options));
14179
+ let result = (await llm.doGenerate(_options));
14170
14180
  if (Log.isEnableDebug()) {
14171
14181
  Log.debug(`LLM nonstream body, name: ${name} => `, result.request?.body);
14172
14182
  }
14173
14183
  result.llm = name;
14174
- result.llmConfig = this.llms[name];
14184
+ result.llmConfig = llmConfig;
14175
14185
  return result;
14176
14186
  }
14177
14187
  catch (e) {
@@ -14181,8 +14191,8 @@ class RetryLanguageModel {
14181
14191
  lastError = e;
14182
14192
  if (Log.isEnableInfo()) {
14183
14193
  Log.info(`LLM nonstream request, name: ${name} => `, {
14184
- tools: options.mode?.tools,
14185
- messages: options.prompt,
14194
+ tools: _options.mode?.tools,
14195
+ messages: _options.prompt,
14186
14196
  });
14187
14197
  }
14188
14198
  Log.error(`LLM error, name: ${name} => `, e);
@@ -14203,6 +14213,7 @@ class RetryLanguageModel {
14203
14213
  temperature: request.temperature,
14204
14214
  topP: request.topP,
14205
14215
  topK: request.topK,
14216
+ stopSequences: request.stopSequences,
14206
14217
  abortSignal: request.abortSignal,
14207
14218
  });
14208
14219
  }
@@ -14213,24 +14224,28 @@ class RetryLanguageModel {
14213
14224
  let lastError;
14214
14225
  for (let i = 0; i < names.length; i++) {
14215
14226
  const name = names[i];
14227
+ const llmConfig = this.llms[name];
14216
14228
  const llm = await this.getLLM(name);
14217
14229
  if (!llm) {
14218
14230
  continue;
14219
14231
  }
14220
14232
  if (!maxTokens) {
14221
- options.maxTokens =
14222
- this.llms[name].config?.maxTokens || config.maxTokens;
14233
+ options.maxTokens = llmConfig.config?.maxTokens || config.maxTokens;
14223
14234
  }
14224
14235
  if (!providerMetadata) {
14225
14236
  options.providerMetadata = {};
14226
- options.providerMetadata[llm.provider] = this.llms[name].options || {};
14237
+ options.providerMetadata[llm.provider] = llmConfig.options || {};
14238
+ }
14239
+ let _options = options;
14240
+ if (llmConfig.handler) {
14241
+ _options = await llmConfig.handler(_options);
14227
14242
  }
14228
14243
  try {
14229
14244
  const controller = new AbortController();
14230
- const signal = options.abortSignal
14231
- ? AbortSignal.any([options.abortSignal, controller.signal])
14245
+ const signal = _options.abortSignal
14246
+ ? AbortSignal.any([_options.abortSignal, controller.signal])
14232
14247
  : controller.signal;
14233
- const result = (await call_timeout(async () => await llm.doStream({ ...options, abortSignal: signal }), this.stream_first_timeout, (e) => {
14248
+ const result = (await call_timeout(async () => await llm.doStream({ ..._options, abortSignal: signal }), this.stream_first_timeout, (e) => {
14234
14249
  controller.abort();
14235
14250
  }));
14236
14251
  const stream = result.stream;
@@ -14255,8 +14270,8 @@ class RetryLanguageModel {
14255
14270
  continue;
14256
14271
  }
14257
14272
  result.llm = name;
14258
- result.llmConfig = this.llms[name];
14259
- result.stream = this.streamWrapper([chunk], reader);
14273
+ result.llmConfig = llmConfig;
14274
+ result.stream = this.streamWrapper([chunk], reader, controller);
14260
14275
  return result;
14261
14276
  }
14262
14277
  catch (e) {
@@ -14266,8 +14281,8 @@ class RetryLanguageModel {
14266
14281
  lastError = e;
14267
14282
  if (Log.isEnableInfo()) {
14268
14283
  Log.info(`LLM stream request, name: ${name} => `, {
14269
- tools: options.mode?.tools,
14270
- messages: options.prompt,
14284
+ tools: _options.mode?.tools,
14285
+ messages: _options.prompt,
14271
14286
  });
14272
14287
  }
14273
14288
  Log.error(`LLM error, name: ${name} => `, e);
@@ -14348,7 +14363,8 @@ class RetryLanguageModel {
14348
14363
  return llm.provider.languageModel(llm.model);
14349
14364
  }
14350
14365
  }
14351
- streamWrapper(parts, reader) {
14366
+ streamWrapper(parts, reader, abortController) {
14367
+ let timer = null;
14352
14368
  return new ReadableStream({
14353
14369
  start: (controller) => {
14354
14370
  if (parts != null && parts.length > 0) {
@@ -14358,7 +14374,11 @@ class RetryLanguageModel {
14358
14374
  }
14359
14375
  },
14360
14376
  pull: async (controller) => {
14377
+ timer = setTimeout(() => {
14378
+ abortController.abort("Streaming request timeout");
14379
+ }, this.stream_token_timeout);
14361
14380
  const { done, value } = await reader.read();
14381
+ clearTimeout(timer);
14362
14382
  if (done) {
14363
14383
  controller.close();
14364
14384
  reader.releaseLock();
@@ -14367,6 +14387,7 @@ class RetryLanguageModel {
14367
14387
  controller.enqueue(value);
14368
14388
  },
14369
14389
  cancel: (reason) => {
14390
+ timer && clearTimeout(timer);
14370
14391
  reader.cancel(reason);
14371
14392
  },
14372
14393
  });
@@ -16824,6 +16845,159 @@ function requireDomParser () {
16824
16845
 
16825
16846
  var domParserExports = requireDomParser();
16826
16847
 
16848
+ function buildAgentTree(agents) {
16849
+ // Detect and handle circular dependencies
16850
+ const safeAgents = detectAndBreakCycles(agents);
16851
+ if (safeAgents.length === 0) {
16852
+ throw new Error("No executable agent");
16853
+ }
16854
+ // Establish dependency relationship mapping
16855
+ const agentMap = new Map();
16856
+ const dependents = new Map();
16857
+ for (const agent of safeAgents) {
16858
+ agentMap.set(agent.id, agent);
16859
+ dependents.set(agent.id, []);
16860
+ }
16861
+ for (const agent of safeAgents) {
16862
+ for (const depId of agent.dependsOn) {
16863
+ if (dependents.has(depId)) {
16864
+ dependents.get(depId).push(agent);
16865
+ }
16866
+ }
16867
+ }
16868
+ let entryAgents = safeAgents.filter((agent) => agent.dependsOn.length === 0);
16869
+ if (entryAgents.length === 0) {
16870
+ entryAgents = safeAgents.filter((agent) => agent.dependsOn.length == 1 && agent.dependsOn[0].endsWith("00"));
16871
+ }
16872
+ const processedAgents = new Set();
16873
+ function buildNodeRecursive(currentAgents) {
16874
+ if (currentAgents.length === 0) {
16875
+ return undefined;
16876
+ }
16877
+ for (const agent of currentAgents) {
16878
+ processedAgents.add(agent.id);
16879
+ }
16880
+ const nextLevelAgents = [];
16881
+ const nextLevelSet = new Set();
16882
+ for (const agent of currentAgents) {
16883
+ const dependentAgents = dependents.get(agent.id) || [];
16884
+ for (const dependentAgent of dependentAgents) {
16885
+ const allDependenciesProcessed = dependentAgent.dependsOn.every((depId) => processedAgents.has(depId));
16886
+ if (allDependenciesProcessed && !nextLevelSet.has(dependentAgent.id)) {
16887
+ nextLevelAgents.push(dependentAgent);
16888
+ nextLevelSet.add(dependentAgent.id);
16889
+ }
16890
+ }
16891
+ }
16892
+ const nextNode = buildNodeRecursive(nextLevelAgents);
16893
+ if (currentAgents.length === 1) {
16894
+ return {
16895
+ type: "normal",
16896
+ agent: currentAgents[0],
16897
+ nextAgent: nextNode,
16898
+ };
16899
+ }
16900
+ else {
16901
+ const parallelNodes = currentAgents.map((agent) => ({
16902
+ type: "normal",
16903
+ agent: agent,
16904
+ nextAgent: undefined,
16905
+ }));
16906
+ return {
16907
+ type: "parallel",
16908
+ agents: parallelNodes,
16909
+ nextAgent: nextNode,
16910
+ };
16911
+ }
16912
+ }
16913
+ const rootNode = buildNodeRecursive(entryAgents);
16914
+ if (!rootNode) {
16915
+ throw new Error("Unable to build execution tree");
16916
+ }
16917
+ return rootNode;
16918
+ }
16919
+ function detectAndBreakCycles(agents) {
16920
+ // Detect cyclic dependencies and return a safe dependency relationship
16921
+ // Use topological sorting algorithm to detect cycles, if a cycle is found, break some dependencies.
16922
+ const agentMap = new Map();
16923
+ const inDegree = new Map();
16924
+ const adjList = new Map();
16925
+ for (const agent of agents) {
16926
+ agentMap.set(agent.id, agent);
16927
+ inDegree.set(agent.id, 0);
16928
+ adjList.set(agent.id, []);
16929
+ }
16930
+ for (const agent of agents) {
16931
+ for (const depId of agent.dependsOn) {
16932
+ if (agentMap.has(depId)) {
16933
+ // depId -> agent.id indicates that the agent depends on depId.
16934
+ adjList.get(depId).push(agent.id);
16935
+ inDegree.set(agent.id, inDegree.get(agent.id) + 1);
16936
+ }
16937
+ }
16938
+ }
16939
+ // Topological Sorting Detects Cycles
16940
+ const queue = [];
16941
+ const processedCount = new Map();
16942
+ for (const [agentId, degree] of inDegree.entries()) {
16943
+ if (degree === 0) {
16944
+ queue.push(agentId);
16945
+ }
16946
+ processedCount.set(agentId, 0);
16947
+ }
16948
+ let processedNodes = 0;
16949
+ while (queue.length > 0) {
16950
+ const currentId = queue.shift();
16951
+ processedNodes++;
16952
+ for (const neighborId of adjList.get(currentId)) {
16953
+ const newInDegree = inDegree.get(neighborId) - 1;
16954
+ inDegree.set(neighborId, newInDegree);
16955
+ if (newInDegree === 0) {
16956
+ queue.push(neighborId);
16957
+ }
16958
+ }
16959
+ }
16960
+ if (processedNodes < agents.length) {
16961
+ console.warn("Detected a circular dependency, automatically disconnecting the circular link...");
16962
+ const cyclicNodes = new Set();
16963
+ for (const [agentId, degree] of inDegree.entries()) {
16964
+ if (degree > 0) {
16965
+ cyclicNodes.add(agentId);
16966
+ }
16967
+ }
16968
+ const fixedAgents = [];
16969
+ for (const agent of agents) {
16970
+ if (cyclicNodes.has(agent.id)) {
16971
+ const filteredDependsOn = agent.dependsOn.filter((depId) => !cyclicNodes.has(depId) || !agentMap.has(depId));
16972
+ // Preserve the shortest path dependency
16973
+ if (filteredDependsOn.length === 0 && agent.dependsOn.length > 0) {
16974
+ const firstValidDep = agent.dependsOn.find((depId) => agentMap.has(depId));
16975
+ if (firstValidDep && !cyclicNodes.has(firstValidDep)) {
16976
+ filteredDependsOn.push(firstValidDep);
16977
+ }
16978
+ }
16979
+ agent.dependsOn = filteredDependsOn;
16980
+ fixedAgents.push(agent);
16981
+ if (filteredDependsOn.length !== agent.dependsOn.length) {
16982
+ console.warn(`The partial cyclic dependency of agent ${agent.id} has been disconnected.`);
16983
+ }
16984
+ }
16985
+ else {
16986
+ // Non-cyclic node, filter out non-existent dependencies
16987
+ const validDependsOn = agent.dependsOn.filter((depId) => agentMap.has(depId));
16988
+ agent.dependsOn = validDependsOn;
16989
+ fixedAgents.push(agent);
16990
+ }
16991
+ }
16992
+ return fixedAgents;
16993
+ }
16994
+ // No loops, just need to filter out non-existent dependencies
16995
+ return agents.map((agent) => {
16996
+ agent.dependsOn = agent.dependsOn.filter((depId) => agentMap.has(depId));
16997
+ return agent;
16998
+ });
16999
+ }
17000
+
16827
17001
  function parseWorkflow(taskId, xml, done, thinking) {
16828
17002
  let _workflow = null;
16829
17003
  try {
@@ -16871,12 +17045,17 @@ function parseWorkflow(taskId, xml, done, thinking) {
16871
17045
  if (!name) {
16872
17046
  break;
16873
17047
  }
17048
+ let index = agentNode.getAttribute("id") || i;
17049
+ let dependsOn = agentNode.getAttribute("dependsOn") || "";
16874
17050
  let nodes = [];
16875
17051
  let agent = {
16876
17052
  name: name,
16877
- id: taskId + "-" + (i < 10 ? "0" + i : i),
17053
+ id: getAgentId(taskId, index),
17054
+ dependsOn: dependsOn.split(",").filter(idx => idx.trim() != "").map(idx => getAgentId(taskId, idx)),
16878
17055
  task: agentNode.getElementsByTagName("task")[0]?.textContent || "",
16879
17056
  nodes: nodes,
17057
+ status: "init",
17058
+ parallel: undefined,
16880
17059
  xml: agentNode.toString(),
16881
17060
  };
16882
17061
  let xmlNodes = agentNode.getElementsByTagName("nodes");
@@ -16885,6 +17064,25 @@ function parseWorkflow(taskId, xml, done, thinking) {
16885
17064
  }
16886
17065
  agents.push(agent);
16887
17066
  }
17067
+ if (done) {
17068
+ let agentTree = buildAgentTree(workflow.agents);
17069
+ while (true) {
17070
+ if (agentTree.type === "normal") {
17071
+ agentTree.agent.parallel = false;
17072
+ }
17073
+ else {
17074
+ const parallelAgents = agentTree.agents;
17075
+ for (let i = 0; i < parallelAgents.length; i++) {
17076
+ const agentNode = parallelAgents[i];
17077
+ agentNode.agent.parallel = true;
17078
+ }
17079
+ }
17080
+ if (!agentTree.nextAgent) {
17081
+ break;
17082
+ }
17083
+ agentTree = agentTree.nextAgent;
17084
+ }
17085
+ }
16888
17086
  return workflow;
16889
17087
  }
16890
17088
  catch (e) {
@@ -16896,6 +17094,9 @@ function parseWorkflow(taskId, xml, done, thinking) {
16896
17094
  }
16897
17095
  }
16898
17096
  }
17097
+ function getAgentId(taskId, index) {
17098
+ return taskId + "-" + (+index < 10 ? "0" + index : index);
17099
+ }
16899
17100
  function parseWorkflowNodes(nodes, xmlNodes) {
16900
17101
  for (let i = 0; i < xmlNodes.length; i++) {
16901
17102
  if (xmlNodes[i].nodeType !== 1) {
@@ -17013,6 +17214,7 @@ function buildSimpleAgentWorkflow({ taskId, name, agentName, task, taskNodes, })
17013
17214
  agents: [
17014
17215
  {
17015
17216
  id: taskId + "-00",
17217
+ dependsOn: [],
17016
17218
  name: agentName,
17017
17219
  task: task,
17018
17220
  nodes: taskNodes.map((node) => {
@@ -17021,6 +17223,8 @@ function buildSimpleAgentWorkflow({ taskId, name, agentName, task, taskNodes, })
17021
17223
  text: node,
17022
17224
  };
17023
17225
  }),
17226
+ status: "init",
17227
+ parallel: false,
17024
17228
  xml: "",
17025
17229
  },
17026
17230
  ],
@@ -17034,6 +17238,7 @@ function resetWorkflowXml(workflow) {
17034
17238
  const agents = [];
17035
17239
  for (let i = 0; i < workflow.agents.length; i++) {
17036
17240
  const agent = workflow.agents[i];
17241
+ const agentDependsAttr = ` id="${i}" dependsOn="${(agent.dependsOn || []).filter(s => parseInt(s.split("-")[s.split("-").length - 1])).join(",")}"`;
17037
17242
  const nodes = agent.nodes
17038
17243
  .map((node) => {
17039
17244
  if (node.type == "forEach") {
@@ -17070,7 +17275,7 @@ ${watchNodes.join("\n")}
17070
17275
  }
17071
17276
  })
17072
17277
  .join("\n");
17073
- const agentXml = ` <agent name="${agent.name}">
17278
+ const agentXml = ` <agent name="${agent.name}"${agentDependsAttr}>
17074
17279
  <task>${agent.task}</task>
17075
17280
  <nodes>
17076
17281
  ${nodes}
@@ -17137,7 +17342,7 @@ class TaskSnapshotTool {
17137
17342
  }
17138
17343
  }
17139
17344
 
17140
- async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, retry, callback) {
17345
+ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, retryNum = 0, callback, requestHandler) {
17141
17346
  await agentContext.context.checkAborted();
17142
17347
  if (messages.length >= config.compressThreshold && !noCompress) {
17143
17348
  await compressAgentMessages(agentContext, rlm, messages, tools);
@@ -17164,6 +17369,7 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
17164
17369
  messages: messages,
17165
17370
  abortSignal: signal,
17166
17371
  };
17372
+ requestHandler && requestHandler(request);
17167
17373
  agentChain.agentRequest = request;
17168
17374
  let result;
17169
17375
  try {
@@ -17174,13 +17380,13 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
17174
17380
  context.currentStepControllers.delete(stepController);
17175
17381
  await context.checkAborted();
17176
17382
  if (!noCompress &&
17177
- messages.length > 10 &&
17383
+ messages.length >= 5 &&
17178
17384
  ((e + "").indexOf("tokens") > -1 || (e + "").indexOf("too long") > -1)) {
17179
17385
  await compressAgentMessages(agentContext, rlm, messages, tools);
17180
17386
  }
17181
- if (!retry) {
17182
- await sleep(200);
17183
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
17387
+ if (retryNum < config.maxRetryNum) {
17388
+ await sleep(200 * (retryNum + 1) * (retryNum + 1));
17389
+ return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
17184
17390
  }
17185
17391
  throw e;
17186
17392
  }
@@ -17359,11 +17565,11 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
17359
17565
  usage: chunk.usage,
17360
17566
  }, agentContext);
17361
17567
  if (chunk.finishReason === "length" &&
17362
- messages.length >= 10 &&
17568
+ messages.length >= 5 &&
17363
17569
  !noCompress &&
17364
- !retry) {
17570
+ retryNum < config.maxRetryNum) {
17365
17571
  await compressAgentMessages(agentContext, rlm, messages, tools);
17366
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
17572
+ return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
17367
17573
  }
17368
17574
  break;
17369
17575
  }
@@ -17372,8 +17578,9 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
17372
17578
  }
17373
17579
  catch (e) {
17374
17580
  await context.checkAborted();
17375
- if (!retry) {
17376
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
17581
+ if (retryNum < config.maxRetryNum) {
17582
+ await sleep(200 * (retryNum + 1) * (retryNum + 1));
17583
+ return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
17377
17584
  }
17378
17585
  throw e;
17379
17586
  }
@@ -17394,7 +17601,8 @@ function appendUserConversation(agentContext, messages) {
17394
17601
  .splice(0, agentContext.context.conversation.length)
17395
17602
  .filter((s) => !!s);
17396
17603
  if (userPrompts.length > 0) {
17397
- 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");
17604
+ const prompt = "The user is intervening in the current task, please replan and execute according to the following instructions:\n" +
17605
+ userPrompts.map((s) => `- ${s.trim()}`).join("\n");
17398
17606
  messages.push({
17399
17607
  role: "user",
17400
17608
  content: [{ type: "text", text: prompt }],
@@ -17446,9 +17654,17 @@ function removeDuplicateToolUse(results) {
17446
17654
  return _results;
17447
17655
  }
17448
17656
  async function compressAgentMessages(agentContext, rlm, messages, tools) {
17449
- if (messages.length < 10) {
17657
+ if (messages.length < 5) {
17450
17658
  return;
17451
17659
  }
17660
+ try {
17661
+ doCompressAgentMessages(agentContext, rlm, messages, tools);
17662
+ }
17663
+ catch (e) {
17664
+ Log.error("Error compressing agent messages:", e);
17665
+ }
17666
+ }
17667
+ async function doCompressAgentMessages(agentContext, rlm, messages, tools) {
17452
17668
  // extract used tool
17453
17669
  let usedTools = extractUsedTool(messages, tools);
17454
17670
  let snapshotTool = new TaskSnapshotTool();
@@ -17570,7 +17786,8 @@ function handleLargeContextMessages(messages) {
17570
17786
  }
17571
17787
  for (let r = 0; r < toolContent.length; r++) {
17572
17788
  let _content = toolContent[r];
17573
- if (_content.type == "text" && _content.text?.length > config.largeTextLength) {
17789
+ if (_content.type == "text" &&
17790
+ _content.text?.length > config.largeTextLength) {
17574
17791
  if (!longTextTools[toolResult.toolName]) {
17575
17792
  longTextTools[toolResult.toolName] = 1;
17576
17793
  break;
@@ -18343,6 +18560,7 @@ class Agent {
18343
18560
  this.llms = params.llms;
18344
18561
  this.mcpClient = params.mcpClient;
18345
18562
  this.planDescription = params.planDescription;
18563
+ this.requestHandler = params.requestHandler;
18346
18564
  }
18347
18565
  async run(context, agentChain) {
18348
18566
  let mcpClient = this.mcpClient || context.config.defaultMcpClient;
@@ -18388,7 +18606,7 @@ class Agent {
18388
18606
  }
18389
18607
  }
18390
18608
  await this.handleMessages(agentContext, messages, tools);
18391
- let results = await callAgentLLM(agentContext, rlm, messages, this.convertTools(agentTools), false, undefined, false, this.callback);
18609
+ let results = await callAgentLLM(agentContext, rlm, messages, this.convertTools(agentTools), false, undefined, 0, this.callback, this.requestHandler);
18392
18610
  let finalResult = await this.handleCallResult(agentContext, messages, agentTools, results);
18393
18611
  if (finalResult) {
18394
18612
  return finalResult;
@@ -18398,6 +18616,10 @@ class Agent {
18398
18616
  return "Unfinished";
18399
18617
  }
18400
18618
  async handleCallResult(agentContext, messages, agentTools, results) {
18619
+ const forceStop = agentContext.variables.get("forceStop");
18620
+ if (forceStop) {
18621
+ return forceStop;
18622
+ }
18401
18623
  let text = null;
18402
18624
  let context = agentContext.context;
18403
18625
  let user_messages = [];
@@ -18686,11 +18908,11 @@ class Agent {
18686
18908
  }
18687
18909
  }
18688
18910
 
18689
- const AGENT_NAME$5 = "Chat";
18911
+ const AGENT_NAME$4 = "Chat";
18690
18912
  class BaseChatAgent extends Agent {
18691
18913
  constructor(llms, ext_tools, mcpClient) {
18692
18914
  super({
18693
- name: AGENT_NAME$5,
18915
+ name: AGENT_NAME$4,
18694
18916
  description: "You are a helpful assistant.",
18695
18917
  tools: ext_tools || [],
18696
18918
  llms: llms,
@@ -18724,8 +18946,13 @@ Your task is to understand the user's requirements, dynamically plan the user's
18724
18946
  <thought>Your thought process on user demand planning</thought>
18725
18947
  <!-- Multiple Agents work together to complete the task -->
18726
18948
  <agents>
18727
- <!-- The required Agent, where the name can only be an available name in the Agent list -->
18728
- <agent name="Agent name">
18949
+ <!--
18950
+ Multi-Agent supports parallelism, coordinating parallel tasks through dependencies, and passing dependent context information through node variables.
18951
+ name: The name of the Agent, where the name can only be an available name in the Agent list.
18952
+ id: Use subscript order as ID for dependency relationships between multiple agents.
18953
+ dependsOn: The IDs of agents that the current agent depends on, separated by commas when there are multiple dependencies.
18954
+ -->
18955
+ <agent name="Agent name" id="0" dependsOn="">
18729
18956
  <!-- The current Agent needs to complete the task -->
18730
18957
  <task>current agent task</task>
18731
18958
  <nodes>
@@ -18747,6 +18974,22 @@ Your task is to understand the user's requirements, dynamically plan the user's
18747
18974
  </watch>
18748
18975
  </nodes>
18749
18976
  </agent>
18977
+ <!--
18978
+ Multi-agent Collaboration Dependency Example:
18979
+
18980
+ Execution Flow:
18981
+ 1. Agent 0: Initial agent with no dependencies (executes first)
18982
+ 2. Agent 1: Depends on Agent 0 completion (executes after Agent 0)
18983
+ 3. Agent 2 & 3: Both depend on Agent 1 completion (execute in parallel after Agent 1)
18984
+ 4. Agent 4: Depends on both Agent 2 and Agent 3 completion (executes last)
18985
+
18986
+ Dependency Chain: Agent 0 → Agent 1 → (Agent 2 ∥ Agent 3) → Agent 4
18987
+ -->
18988
+ <agent name="Agent name" id="0" dependsOn="">...</agent>
18989
+ <agent name="Agent name" id="1" dependsOn="0">...</agent>
18990
+ <agent name="Agent name" id="2" dependsOn="1">...</agent>
18991
+ <agent name="Agent name" id="3" dependsOn="1">...</agent>
18992
+ <agent name="Agent name" id="4" dependsOn="2,3">...</agent>
18750
18993
  </agents>
18751
18994
  </root>
18752
18995
 
@@ -18759,7 +19002,7 @@ Output result:
18759
19002
  <thought>Alright, the user wrote "hello". That's pretty straightforward. I need to respond in a friendly and welcoming manner.</thought>
18760
19003
  <agents>
18761
19004
  <!-- Chat agents can exist without the <task> and <nodes> nodes. -->
18762
- <agent name="Chat"></agent>
19005
+ <agent name="Chat" id="0" dependsOn=""></agent>
18763
19006
  </agents>
18764
19007
  </root>`;
18765
19008
  const PLAN_EXAMPLE_LIST = [
@@ -18769,7 +19012,7 @@ Output result:
18769
19012
  <name>Submit resume</name>
18770
19013
  <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>
18771
19014
  <agents>
18772
- <agent name="Browser">
19015
+ <agent name="Browser" id="0" dependsOn="">
18773
19016
  <task>Open Boss Zhipin, find 10 operation positions in Chengdu, and send a personal introduction to the recruiters based on the page information.</task>
18774
19017
  <nodes>
18775
19018
  <node>Open Boss Zhipin, enter the job search page</node>
@@ -18789,7 +19032,7 @@ Output result:
18789
19032
  <name>Latest AI News</name>
18790
19033
  <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>
18791
19034
  <agents>
18792
- <agent name="Browser">
19035
+ <agent name="Browser" id="0" dependsOn="">
18793
19036
  <task>Search for the latest updates on AI</task>
18794
19037
  <nodes>
18795
19038
  <node>Open Google</node>
@@ -18800,7 +19043,7 @@ Output result:
18800
19043
  <node output="summaryInfo">Summarize search information</node>
18801
19044
  </nodes>
18802
19045
  </agent>
18803
- <agent name="Computer">
19046
+ <agent name="Computer" id="1" dependsOn="0">
18804
19047
  <task>Send a message to the WeChat group chat "AI news information"</task>
18805
19048
  <nodes>
18806
19049
  <node>Open WeChat</node>
@@ -18816,7 +19059,7 @@ Output result:
18816
19059
  <name>Statistics of Google Team Developers' Geographic Distribution</name>
18817
19060
  <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>
18818
19061
  <agents>
18819
- <agent name="Browser">
19062
+ <agent name="Browser" id="0" dependsOn="">
18820
19063
  <task>Visit Google GitHub Organization Page and Analyze Developer Geographic Distribution</task>
18821
19064
  <nodes>
18822
19065
  <node>Visit https://github.com/google</node>
@@ -18838,7 +19081,7 @@ Output result:
18838
19081
  <name>Automatic reply to Discord messages</name>
18839
19082
  <thought>OK, monitor the chat messages in Discord group A and automatically reply.</thought>
18840
19083
  <agents>
18841
- <agent name="Browser">
19084
+ <agent name="Browser" id="0" dependsOn="">
18842
19085
  <task>Open Group A in Discord</task>
18843
19086
  <nodes>
18844
19087
  <node>Open Discord page</node>
@@ -18853,6 +19096,59 @@ Output result:
18853
19096
  </nodes>
18854
19097
  </agent>
18855
19098
  </agents>
19099
+ </root>`,
19100
+ `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.
19101
+ Output result:
19102
+ <root>
19103
+ <name>Fellou Research and Social Media Campaign</name>
19104
+ <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>
19105
+ <agents>
19106
+ <agent name="Browser" id="0" dependsOn="">
19107
+ <task>Research comprehensive information about 'Fellou'</task>
19108
+ <nodes>
19109
+ <node>Search for the latest information about 'Fellou' - its identity, purpose, and core features</node>
19110
+ <node>Search for Fellou's functionalities, capabilities, and technical specifications</node>
19111
+ <node>Search for recent news, updates, announcements, and developments related to Fellou</node>
19112
+ <node>Search for user reviews, feedback, and community discussions about Fellou</node>
19113
+ <node>Search for Fellou's market position, competitors, and industry context</node>
19114
+ <node output="researchData">Compile all research findings into a comprehensive summary profile</node>
19115
+ </nodes>
19116
+ </agent>
19117
+ <agent name="Browser" id="1" dependsOn="0">
19118
+ <task>Share Fellou's summary and collected interaction data on Twitter/X</task>
19119
+ <nodes>
19120
+ <node>Navigate to Twitter/X platform</node>
19121
+ <node input="researchData">Create and post Twitter-optimized content about Fellou (within character limits, using hashtags)</node>
19122
+ <node output="twitterResults">Capture Twitter post URL and initial engagement metrics</node>
19123
+ </nodes>
19124
+ </agent>
19125
+ <agent name="Browser" id="2" dependsOn="0">
19126
+ <task>Share Fellou's summary and collected interaction data on Facebook</task>
19127
+ <nodes>
19128
+ <node>Navigate to Facebook platform</node>
19129
+ <node input="researchData">Create and post Facebook-optimized content about Fellou (longer format, engaging description)</node>
19130
+ <node output="facebookResults">Capture Facebook post URL and initial engagement metrics</node>
19131
+ </nodes>
19132
+ </agent>
19133
+ <agent name="Browser" id="3" dependsOn="0">
19134
+ <task>Share Fellou's summary and collected interaction data on Reddit</task>
19135
+ <nodes>
19136
+ <node>Navigate to Reddit platform</node>
19137
+ <node input="researchData">Find appropriate subreddit and create Reddit-optimized post about Fellou (community-focused, informative)</node>
19138
+ <node output="redditResults">Capture Reddit post URL and initial engagement metrics</node>
19139
+ </nodes>
19140
+ </agent>
19141
+ <agent name="File" id="4" dependsOn="1,2,3">
19142
+ <task>Compile social media results into Excel file</task>
19143
+ <nodes>
19144
+ <node input="twitterResults,facebookResults,redditResults">Create Excel file with social media campaign results</node>
19145
+ <node>Include columns for Platform, Post URL, Content Summary, Timestamp, Initial Likes/Shares/Comments</node>
19146
+ <node>Format the Excel file with proper headers and styling</node>
19147
+ <node>Save the file as 'Fellou_Social_Media_Campaign_Results.xlsx'</node>
19148
+ </nodes>
19149
+ </agent>
19150
+ </agents>
19151
+ </agents>
18856
19152
  </root>`,
18857
19153
  ];
18858
19154
  const PLAN_USER_TEMPLATE = `
@@ -18883,7 +19179,7 @@ async function getPlanSystemPrompt(context) {
18883
19179
  "\n</agent>\n\n";
18884
19180
  }
18885
19181
  let plan_example_list = context.variables.get("plan_example_list") || PLAN_EXAMPLE_LIST;
18886
- let hasChatAgent = context.agents.filter((a) => a.Name == AGENT_NAME$5).length > 0;
19182
+ let hasChatAgent = context.agents.filter((a) => a.Name == AGENT_NAME$4).length > 0;
18887
19183
  let example_prompt = "";
18888
19184
  const example_list = hasChatAgent
18889
19185
  ? [PLAN_CHAT_EXAMPLE, ...plan_example_list]
@@ -18916,9 +19212,10 @@ function getPlanUserPrompt(task_prompt, task_website, ext_prompt) {
18916
19212
  }
18917
19213
 
18918
19214
  class Planner {
18919
- constructor(context, taskId) {
19215
+ constructor(context, callback) {
18920
19216
  this.context = context;
18921
- this.taskId = taskId || context.taskId;
19217
+ this.taskId = context.taskId;
19218
+ this.callback = callback || context.config.callback;
18922
19219
  }
18923
19220
  async plan(taskPrompt, saveHistory = true) {
18924
19221
  let taskPromptStr;
@@ -18982,7 +19279,7 @@ class Planner {
18982
19279
  let thinkingText = "";
18983
19280
  try {
18984
19281
  while (true) {
18985
- await this.context.checkAborted();
19282
+ await this.context.checkAborted(true);
18986
19283
  const { done, value } = await reader.read();
18987
19284
  if (done) {
18988
19285
  break;
@@ -18998,10 +19295,10 @@ class Planner {
18998
19295
  if (chunk.type == "text-delta") {
18999
19296
  streamText += chunk.textDelta || "";
19000
19297
  }
19001
- if (config.callback) {
19298
+ if (this.callback) {
19002
19299
  let workflow = parseWorkflow(this.taskId, streamText, false, thinkingText);
19003
19300
  if (workflow) {
19004
- await config.callback.onMessage({
19301
+ await this.callback.onMessage({
19005
19302
  taskId: this.taskId,
19006
19303
  agentName: "Planer",
19007
19304
  type: "workflow",
@@ -19024,8 +19321,8 @@ class Planner {
19024
19321
  chain.planResult = streamText;
19025
19322
  }
19026
19323
  let workflow = parseWorkflow(this.taskId, streamText, true, thinkingText);
19027
- if (config.callback) {
19028
- await config.callback.onMessage({
19324
+ if (this.callback) {
19325
+ await this.callback.onMessage({
19029
19326
  taskId: this.taskId,
19030
19327
  agentName: "Planer",
19031
19328
  type: "workflow",
@@ -19050,18 +19347,18 @@ class Eko {
19050
19347
  }
19051
19348
  async generate(taskPrompt, taskId = uuidv4(), contextParams) {
19052
19349
  const agents = [...(this.config.agents || [])];
19053
- let chain = new Chain(taskPrompt);
19054
- let context = new Context(taskId, this.config, agents, chain);
19350
+ const chain = new Chain(taskPrompt);
19351
+ const context = new Context(taskId, this.config, agents, chain);
19055
19352
  if (contextParams) {
19056
19353
  Object.keys(contextParams).forEach((key) => context.variables.set(key, contextParams[key]));
19057
19354
  }
19058
19355
  try {
19059
19356
  this.taskMap.set(taskId, context);
19060
19357
  if (this.config.a2aClient) {
19061
- let a2aList = await this.config.a2aClient.listAgents(taskPrompt);
19358
+ const a2aList = await this.config.a2aClient.listAgents(taskPrompt);
19062
19359
  context.agents = mergeAgents(context.agents, a2aList);
19063
19360
  }
19064
- let planner = new Planner(context, taskId);
19361
+ const planner = new Planner(context);
19065
19362
  context.workflow = await planner.plan(taskPrompt);
19066
19363
  return context.workflow;
19067
19364
  }
@@ -19071,20 +19368,20 @@ class Eko {
19071
19368
  }
19072
19369
  }
19073
19370
  async modify(taskId, modifyTaskPrompt) {
19074
- let context = this.taskMap.get(taskId);
19371
+ const context = this.taskMap.get(taskId);
19075
19372
  if (!context) {
19076
19373
  return await this.generate(modifyTaskPrompt, taskId);
19077
19374
  }
19078
19375
  if (this.config.a2aClient) {
19079
- let a2aList = await this.config.a2aClient.listAgents(modifyTaskPrompt);
19376
+ const a2aList = await this.config.a2aClient.listAgents(modifyTaskPrompt);
19080
19377
  context.agents = mergeAgents(context.agents, a2aList);
19081
19378
  }
19082
- let planner = new Planner(context, taskId);
19379
+ const planner = new Planner(context);
19083
19380
  context.workflow = await planner.replan(modifyTaskPrompt);
19084
19381
  return context.workflow;
19085
19382
  }
19086
19383
  async execute(taskId) {
19087
- let context = this.getTask(taskId);
19384
+ const context = this.getTask(taskId);
19088
19385
  if (!context) {
19089
19386
  throw new Error("The task does not exist");
19090
19387
  }
@@ -19114,10 +19411,10 @@ class Eko {
19114
19411
  }
19115
19412
  async initContext(workflow, contextParams) {
19116
19413
  const agents = this.config.agents || [];
19117
- let chain = new Chain(workflow.taskPrompt || workflow.name);
19118
- let context = new Context(workflow.taskId, this.config, agents, chain);
19414
+ const chain = new Chain(workflow.taskPrompt || workflow.name);
19415
+ const context = new Context(workflow.taskId, this.config, agents, chain);
19119
19416
  if (this.config.a2aClient) {
19120
- let a2aList = await this.config.a2aClient.listAgents(workflow.taskPrompt || workflow.name);
19417
+ const a2aList = await this.config.a2aClient.listAgents(workflow.taskPrompt || workflow.name);
19121
19418
  context.agents = mergeAgents(context.agents, a2aList);
19122
19419
  }
19123
19420
  if (contextParams) {
@@ -19128,30 +19425,88 @@ class Eko {
19128
19425
  return context;
19129
19426
  }
19130
19427
  async doRunWorkflow(context) {
19131
- let agents = context.agents;
19132
- let workflow = context.workflow;
19428
+ const agents = context.agents;
19429
+ const workflow = context.workflow;
19133
19430
  if (!workflow || workflow.agents.length == 0) {
19134
19431
  throw new Error("Workflow error");
19135
19432
  }
19136
- let agentMap = agents.reduce((map, item) => {
19433
+ const agentNameMap = agents.reduce((map, item) => {
19137
19434
  map[item.Name] = item;
19138
19435
  return map;
19139
19436
  }, {});
19140
- let results = [];
19141
- for (let i = 0; i < workflow.agents.length; i++) {
19437
+ let agentTree = buildAgentTree(workflow.agents);
19438
+ const results = [];
19439
+ while (true) {
19142
19440
  await context.checkAborted();
19143
- let agentNode = workflow.agents[i];
19144
- let agent = agentMap[agentNode.name];
19145
- if (!agent) {
19146
- throw new Error("Unknown Agent: " + agentNode.name);
19147
- }
19148
- let agentChain = new AgentChain(agentNode);
19149
- context.chain.push(agentChain);
19150
- agent.result = await agent.run(context, agentChain);
19151
- results.push(agent.result);
19152
- if (agentNode.name === "Timer") {
19441
+ if (agentTree.type === "normal") {
19442
+ // normal agent
19443
+ const agent = agentNameMap[agentTree.agent.name];
19444
+ if (!agent) {
19445
+ throw new Error("Unknown Agent: " + agentTree.agent.name);
19446
+ }
19447
+ const agentNode = agentTree.agent;
19448
+ const agentChain = new AgentChain(agentNode);
19449
+ context.chain.push(agentChain);
19450
+ try {
19451
+ agentNode.status = "running";
19452
+ agentTree.result = await agent.run(context, agentChain);
19453
+ agentNode.status = "done";
19454
+ results.push(agentTree.result);
19455
+ }
19456
+ catch (e) {
19457
+ agentNode.status = "error";
19458
+ throw e;
19459
+ }
19460
+ }
19461
+ else {
19462
+ // parallel agent
19463
+ const parallelAgents = agentTree.agents;
19464
+ const doRunAgent = async (agentNode, index) => {
19465
+ const agent = agentNameMap[agentNode.agent.name];
19466
+ if (!agent) {
19467
+ throw new Error("Unknown Agent: " + agentNode.agent.name);
19468
+ }
19469
+ const agentChain = new AgentChain(agentNode.agent);
19470
+ try {
19471
+ agentNode.agent.status = "running";
19472
+ agentNode.result = await agent.run(context, agentChain);
19473
+ agentNode.agent.status = "done";
19474
+ }
19475
+ catch (e) {
19476
+ agentNode.agent.status = "error";
19477
+ throw e;
19478
+ }
19479
+ return { result: agentNode.result, agentChain, index };
19480
+ };
19481
+ let agent_results = [];
19482
+ let agentParallel = context.variables.get("agentParallel");
19483
+ if (agentParallel === undefined) {
19484
+ agentParallel = config.agentParallel;
19485
+ }
19486
+ if (agentParallel) {
19487
+ // parallel execution
19488
+ const parallelResults = await Promise.all(parallelAgents.map((agent, index) => doRunAgent(agent, index)));
19489
+ parallelResults.sort((a, b) => a.index - b.index);
19490
+ parallelResults.forEach(({ agentChain }) => {
19491
+ context.chain.push(agentChain);
19492
+ });
19493
+ agent_results = parallelResults.map(({ result }) => result);
19494
+ }
19495
+ else {
19496
+ // serial execution
19497
+ for (let i = 0; i < parallelAgents.length; i++) {
19498
+ const { result, agentChain } = await doRunAgent(parallelAgents[i], i);
19499
+ context.chain.push(agentChain);
19500
+ agent_results.push(result);
19501
+ }
19502
+ }
19503
+ results.push(agent_results.join("\n\n"));
19504
+ }
19505
+ context.conversation.splice(0, context.conversation.length);
19506
+ if (!agentTree.nextAgent) {
19153
19507
  break;
19154
19508
  }
19509
+ agentTree = agentTree.nextAgent;
19155
19510
  }
19156
19511
  return {
19157
19512
  success: true,
@@ -19187,7 +19542,7 @@ class Eko {
19187
19542
  }
19188
19543
  }
19189
19544
  pauseTask(taskId, pause, abortCurrentStep, reason) {
19190
- let context = this.taskMap.get(taskId);
19545
+ const context = this.taskMap.get(taskId);
19191
19546
  if (context) {
19192
19547
  this.onTaskStatus(context, pause ? "pause" : "resume-pause", reason);
19193
19548
  context.setPause(pause, abortCurrentStep);
@@ -19198,7 +19553,7 @@ class Eko {
19198
19553
  }
19199
19554
  }
19200
19555
  chatTask(taskId, userPrompt) {
19201
- let context = this.taskMap.get(taskId);
19556
+ const context = this.taskMap.get(taskId);
19202
19557
  if (context) {
19203
19558
  context.conversation.push(userPrompt);
19204
19559
  return context.conversation;
@@ -19441,7 +19796,7 @@ function parseChunk(chunk) {
19441
19796
  return chunk_obj;
19442
19797
  }
19443
19798
 
19444
- const AGENT_NAME$4 = "File";
19799
+ const AGENT_NAME$3 = "File";
19445
19800
  class BaseFileAgent extends Agent {
19446
19801
  constructor(work_path, llms, ext_tools, mcpClient, planDescription) {
19447
19802
  const _tools_ = [];
@@ -19449,7 +19804,7 @@ class BaseFileAgent extends Agent {
19449
19804
  ? `Your default working path is: ${work_path}`
19450
19805
  : "";
19451
19806
  super({
19452
- name: AGENT_NAME$4,
19807
+ name: AGENT_NAME$3,
19453
19808
  description: `You are a file agent, handling file-related tasks such as creating, finding, reading, modifying files, etc.${prompt}`,
19454
19809
  tools: _tools_,
19455
19810
  llms: llms,
@@ -19601,7 +19956,7 @@ class BaseFileAgent extends Agent {
19601
19956
  },
19602
19957
  glob: {
19603
19958
  type: "string",
19604
- description: "Filename pattern using glob syntax wildcards",
19959
+ description: "Filename pattern using glob syntax wildcards, Example: **/*.txt",
19605
19960
  },
19606
19961
  },
19607
19962
  required: ["path", "glob"],
@@ -19614,12 +19969,12 @@ class BaseFileAgent extends Agent {
19614
19969
  }
19615
19970
  }
19616
19971
 
19617
- const AGENT_NAME$3 = "Shell";
19972
+ const AGENT_NAME$2 = "Shell";
19618
19973
  class BaseShellAgent extends Agent {
19619
19974
  constructor(llms, ext_tools, mcpClient, planDescription) {
19620
19975
  const _tools_ = [];
19621
19976
  super({
19622
- name: AGENT_NAME$3,
19977
+ name: AGENT_NAME$2,
19623
19978
  description: `Run commands in a bash shell,
19624
19979
  * You must first call create_session to create a new session when using it for the first time.
19625
19980
  * Please execute delete commands with caution, and never perform dangerous operations like \`rm -rf /\`.
@@ -19696,47 +20051,6 @@ class BaseShellAgent extends Agent {
19696
20051
  }
19697
20052
  }
19698
20053
 
19699
- const AGENT_NAME$2 = "Timer";
19700
- class BaseTimerAgent extends Agent {
19701
- constructor(llms, ext_tools, mcpClient) {
19702
- super({
19703
- name: AGENT_NAME$2,
19704
- description: "You are a scheduled task scheduling agent.",
19705
- tools: ext_tools || [],
19706
- llms: llms,
19707
- mcpClient: mcpClient,
19708
- });
19709
- this.addTool(this.schedule_tool());
19710
- }
19711
- schedule_tool() {
19712
- return {
19713
- name: "task_schedule",
19714
- description: "Task scheduled trigger, the task is triggered at a scheduled time and will automatically create a scheduled task for execution.",
19715
- parameters: {
19716
- type: "object",
19717
- properties: {
19718
- trigger_description: {
19719
- type: "string",
19720
- description: "Trigger time description.",
19721
- },
19722
- task_description: {
19723
- type: "string",
19724
- description: "Main task description, excluding trigger time.",
19725
- },
19726
- cron: {
19727
- type: "string",
19728
- description: "The cron expression of the trigger, for example, '0 9 * * *' indicates that it triggers at 9 a.m. every day.",
19729
- },
19730
- },
19731
- required: ["cron"],
19732
- },
19733
- execute: async (args, agentContext) => {
19734
- return await this.callInnerTool(() => this.task_schedule(agentContext, args.trigger_description, args.task_description, args.cron));
19735
- },
19736
- };
19737
- }
19738
- }
19739
-
19740
20054
  const AGENT_NAME$1 = "Computer";
19741
20055
  class BaseComputerAgent extends Agent {
19742
20056
  constructor(llms, ext_tools, mcpClient, keyboardKeys) {
@@ -21923,5 +22237,5 @@ class BaseBrowserScreenAgent extends BaseBrowserAgent {
21923
22237
  }
21924
22238
  }
21925
22239
 
21926
- export { Agent, AgentChain, AgentContext, BaseBrowserAgent, BaseBrowserLabelsAgent, BaseBrowserScreenAgent, BaseChatAgent, BaseComputerAgent, BaseFileAgent, BaseShellAgent, BaseTimerAgent, Chain, Context, Eko, ForeachTaskTool, HumanInteractTool, Log, Planner, RetryLanguageModel, SimpleSseMcpClient, TaskNodeStatusTool, VariableStorageTool, WatchTriggerTool, buildSimpleAgentWorkflow, call_timeout, config, convertToolSchema, Eko as default, extract_page_content, mergeTools, parseWorkflow, resetWorkflowXml, toImage, uuidv4 };
22240
+ export { Agent, AgentChain, AgentContext, BaseBrowserAgent, BaseBrowserLabelsAgent, BaseBrowserScreenAgent, BaseChatAgent, BaseComputerAgent, BaseFileAgent, BaseShellAgent, Chain, Context, Eko, ForeachTaskTool, HumanInteractTool, Log, Planner, RetryLanguageModel, SimpleSseMcpClient, TaskNodeStatusTool, VariableStorageTool, WatchTriggerTool, buildAgentTree, buildSimpleAgentWorkflow, call_timeout, config, convertToolSchema, Eko as default, extract_page_content, mergeTools, parseWorkflow, resetWorkflowXml, toImage, uuidv4 };
21927
22241
  //# sourceMappingURL=index.esm.js.map