@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/agent/base.d.ts +3 -1
- package/dist/agent/base.d.ts.map +1 -1
- package/dist/agent/browser/browser_labels.d.ts +2 -2
- package/dist/agent/browser/browser_labels.d.ts.map +1 -1
- package/dist/agent/index.d.ts +1 -2
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/llm.d.ts +2 -2
- package/dist/agent/llm.d.ts.map +1 -1
- package/dist/common/tree.d.ts +3 -0
- package/dist/common/tree.d.ts.map +1 -0
- package/dist/common/utils.d.ts +2 -2
- package/dist/common/utils.d.ts.map +1 -1
- package/dist/common/xml.d.ts.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/core/context.d.ts +1 -1
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/plan.d.ts +5 -4
- package/dist/core/plan.d.ts.map +1 -1
- package/dist/index.cjs.js +444 -130
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +444 -130
- package/dist/index.esm.js.map +1 -1
- package/dist/llm/index.d.ts +2 -1
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/prompt/plan.d.ts.map +1 -1
- package/dist/types/core.types.d.ts +16 -0
- package/dist/types/core.types.d.ts.map +1 -1
- package/dist/types/llm.types.d.ts +3 -1
- package/dist/types/llm.types.d.ts.map +1 -1
- package/package.json +1 -1
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] =
|
|
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(
|
|
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 =
|
|
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:
|
|
14185
|
-
messages:
|
|
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] =
|
|
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 =
|
|
14231
|
-
? AbortSignal.any([
|
|
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({ ...
|
|
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 =
|
|
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:
|
|
14270
|
-
messages:
|
|
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
|
|
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,
|
|
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
|
|
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 (
|
|
17182
|
-
await sleep(200);
|
|
17183
|
-
return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice,
|
|
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 >=
|
|
17568
|
+
messages.length >= 5 &&
|
|
17363
17569
|
!noCompress &&
|
|
17364
|
-
|
|
17570
|
+
retryNum < config.maxRetryNum) {
|
|
17365
17571
|
await compressAgentMessages(agentContext, rlm, messages, tools);
|
|
17366
|
-
return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice,
|
|
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 (
|
|
17376
|
-
|
|
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
|
|
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 <
|
|
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" &&
|
|
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,
|
|
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$
|
|
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$
|
|
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
|
-
<!--
|
|
18728
|
-
|
|
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$
|
|
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,
|
|
19215
|
+
constructor(context, callback) {
|
|
18920
19216
|
this.context = context;
|
|
18921
|
-
this.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 (
|
|
19298
|
+
if (this.callback) {
|
|
19002
19299
|
let workflow = parseWorkflow(this.taskId, streamText, false, thinkingText);
|
|
19003
19300
|
if (workflow) {
|
|
19004
|
-
await
|
|
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 (
|
|
19028
|
-
await
|
|
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
|
-
|
|
19054
|
-
|
|
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
|
-
|
|
19358
|
+
const a2aList = await this.config.a2aClient.listAgents(taskPrompt);
|
|
19062
19359
|
context.agents = mergeAgents(context.agents, a2aList);
|
|
19063
19360
|
}
|
|
19064
|
-
|
|
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
|
-
|
|
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
|
-
|
|
19376
|
+
const a2aList = await this.config.a2aClient.listAgents(modifyTaskPrompt);
|
|
19080
19377
|
context.agents = mergeAgents(context.agents, a2aList);
|
|
19081
19378
|
}
|
|
19082
|
-
|
|
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
|
-
|
|
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
|
-
|
|
19118
|
-
|
|
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
|
-
|
|
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
|
-
|
|
19132
|
-
|
|
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
|
-
|
|
19433
|
+
const agentNameMap = agents.reduce((map, item) => {
|
|
19137
19434
|
map[item.Name] = item;
|
|
19138
19435
|
return map;
|
|
19139
19436
|
}, {});
|
|
19140
|
-
let
|
|
19141
|
-
|
|
19437
|
+
let agentTree = buildAgentTree(workflow.agents);
|
|
19438
|
+
const results = [];
|
|
19439
|
+
while (true) {
|
|
19142
19440
|
await context.checkAborted();
|
|
19143
|
-
|
|
19144
|
-
|
|
19145
|
-
|
|
19146
|
-
|
|
19147
|
-
|
|
19148
|
-
|
|
19149
|
-
|
|
19150
|
-
|
|
19151
|
-
|
|
19152
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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,
|
|
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
|