@eko-ai/eko 2.1.7-alpha.7 → 2.1.7
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/README.md +1 -2
- package/dist/agent/base.d.ts +4 -3
- package/dist/agent/base.d.ts.map +1 -1
- package/dist/common/utils.d.ts.map +1 -1
- package/dist/common/xml.d.ts +1 -9
- package/dist/common/xml.d.ts.map +1 -1
- package/dist/core/context.d.ts +2 -6
- 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 +3 -4
- package/dist/core/plan.d.ts.map +1 -1
- package/dist/index.cjs.js +445 -638
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +446 -635
- package/dist/index.esm.js.map +1 -1
- package/dist/llm/index.d.ts +0 -2
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/prompt/plan.d.ts.map +1 -1
- package/dist/types/llm.types.d.ts +0 -4
- package/dist/types/llm.types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/agent/llm.d.ts +0 -6
- package/dist/agent/llm.d.ts.map +0 -1
package/dist/index.cjs.js
CHANGED
|
@@ -363,10 +363,8 @@ function fixXmlTag(code) {
|
|
|
363
363
|
const top = stack.pop();
|
|
364
364
|
if (top.startsWith("<")) {
|
|
365
365
|
let arr = top.match(/<(\w+)/);
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
missingParts.push(`</${tagName}>`);
|
|
369
|
-
}
|
|
366
|
+
const tagName = arr[1];
|
|
367
|
+
missingParts.push(`</${tagName}>`);
|
|
370
368
|
}
|
|
371
369
|
else {
|
|
372
370
|
missingParts.push(top);
|
|
@@ -378,9 +376,8 @@ function fixXmlTag(code) {
|
|
|
378
376
|
|
|
379
377
|
class Context {
|
|
380
378
|
constructor(taskId, config, agents, chain) {
|
|
379
|
+
this.paused = false;
|
|
381
380
|
this.conversation = [];
|
|
382
|
-
this.pauseStatus = 0;
|
|
383
|
-
this.currentStepControllers = new Set();
|
|
384
381
|
this.taskId = taskId;
|
|
385
382
|
this.config = config;
|
|
386
383
|
this.agents = agents;
|
|
@@ -389,19 +386,14 @@ class Context {
|
|
|
389
386
|
this.controller = new AbortController();
|
|
390
387
|
}
|
|
391
388
|
async checkAborted() {
|
|
389
|
+
// this.controller.signal.throwIfAborted();
|
|
392
390
|
if (this.controller.signal.aborted) {
|
|
393
391
|
const error = new Error("Operation was interrupted");
|
|
394
392
|
error.name = "AbortError";
|
|
395
393
|
throw error;
|
|
396
394
|
}
|
|
397
|
-
while (this.
|
|
395
|
+
while (this.paused) {
|
|
398
396
|
await sleep(500);
|
|
399
|
-
if (this.pauseStatus == 2) {
|
|
400
|
-
this.currentStepControllers.forEach((c) => {
|
|
401
|
-
c.abort("Pause");
|
|
402
|
-
});
|
|
403
|
-
this.currentStepControllers.clear();
|
|
404
|
-
}
|
|
405
397
|
if (this.controller.signal.aborted) {
|
|
406
398
|
const error = new Error("Operation was interrupted");
|
|
407
399
|
error.name = "AbortError";
|
|
@@ -418,21 +410,9 @@ class Context {
|
|
|
418
410
|
if (!agent) {
|
|
419
411
|
return null;
|
|
420
412
|
}
|
|
421
|
-
const agentContext = agent
|
|
413
|
+
const agentContext = agent["agentContext"];
|
|
422
414
|
return [agent, agentNode.agent, agentContext];
|
|
423
415
|
}
|
|
424
|
-
get pause() {
|
|
425
|
-
return this.pauseStatus > 0;
|
|
426
|
-
}
|
|
427
|
-
setPause(pause, abortCurrentStep) {
|
|
428
|
-
this.pauseStatus = pause ? (abortCurrentStep ? 2 : 1) : 0;
|
|
429
|
-
if (this.pauseStatus == 2) {
|
|
430
|
-
this.currentStepControllers.forEach((c) => {
|
|
431
|
-
c.abort("Pause");
|
|
432
|
-
});
|
|
433
|
-
this.currentStepControllers.clear();
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
416
|
}
|
|
437
417
|
class AgentContext {
|
|
438
418
|
constructor(context, agent, agentChain) {
|
|
@@ -14185,7 +14165,6 @@ class RetryLanguageModel {
|
|
|
14185
14165
|
const maxTokens = options.maxTokens;
|
|
14186
14166
|
const providerMetadata = options.providerMetadata;
|
|
14187
14167
|
const names = [...this.names, ...this.names];
|
|
14188
|
-
let lastError;
|
|
14189
14168
|
for (let i = 0; i < names.length; i++) {
|
|
14190
14169
|
const name = names[i];
|
|
14191
14170
|
const llm = await this.getLLM(name);
|
|
@@ -14201,19 +14180,16 @@ class RetryLanguageModel {
|
|
|
14201
14180
|
options.providerMetadata[llm.provider] = this.llms[name].options || {};
|
|
14202
14181
|
}
|
|
14203
14182
|
try {
|
|
14204
|
-
let result =
|
|
14183
|
+
let result = await llm.doGenerate(options);
|
|
14205
14184
|
if (Log.isEnableDebug()) {
|
|
14206
14185
|
Log.debug(`LLM nonstream body, name: ${name} => `, result.request?.body);
|
|
14207
14186
|
}
|
|
14208
|
-
result.llm = name;
|
|
14209
|
-
result.llmConfig = this.llms[name];
|
|
14210
14187
|
return result;
|
|
14211
14188
|
}
|
|
14212
14189
|
catch (e) {
|
|
14213
14190
|
if (e?.name === "AbortError") {
|
|
14214
14191
|
throw e;
|
|
14215
14192
|
}
|
|
14216
|
-
lastError = e;
|
|
14217
14193
|
if (Log.isEnableInfo()) {
|
|
14218
14194
|
Log.info(`LLM nonstream request, name: ${name} => `, {
|
|
14219
14195
|
tools: options.mode?.tools,
|
|
@@ -14223,7 +14199,7 @@ class RetryLanguageModel {
|
|
|
14223
14199
|
Log.error(`LLM error, name: ${name} => `, e);
|
|
14224
14200
|
}
|
|
14225
14201
|
}
|
|
14226
|
-
return Promise.reject(
|
|
14202
|
+
return Promise.reject(new Error("No LLM available"));
|
|
14227
14203
|
}
|
|
14228
14204
|
async callStream(request) {
|
|
14229
14205
|
return await this.doStream({
|
|
@@ -14245,7 +14221,6 @@ class RetryLanguageModel {
|
|
|
14245
14221
|
const maxTokens = options.maxTokens;
|
|
14246
14222
|
const providerMetadata = options.providerMetadata;
|
|
14247
14223
|
const names = [...this.names, ...this.names];
|
|
14248
|
-
let lastError;
|
|
14249
14224
|
for (let i = 0; i < names.length; i++) {
|
|
14250
14225
|
const name = names[i];
|
|
14251
14226
|
const llm = await this.getLLM(name);
|
|
@@ -14265,9 +14240,9 @@ class RetryLanguageModel {
|
|
|
14265
14240
|
const signal = options.abortSignal
|
|
14266
14241
|
? AbortSignal.any([options.abortSignal, controller.signal])
|
|
14267
14242
|
: controller.signal;
|
|
14268
|
-
const result =
|
|
14243
|
+
const result = await call_timeout(async () => await llm.doStream({ ...options, abortSignal: signal }), this.stream_first_timeout, (e) => {
|
|
14269
14244
|
controller.abort();
|
|
14270
|
-
})
|
|
14245
|
+
});
|
|
14271
14246
|
const stream = result.stream;
|
|
14272
14247
|
const reader = stream.getReader();
|
|
14273
14248
|
const { done, value } = await call_timeout(async () => await reader.read(), this.stream_first_timeout, (e) => {
|
|
@@ -14289,8 +14264,6 @@ class RetryLanguageModel {
|
|
|
14289
14264
|
reader.releaseLock();
|
|
14290
14265
|
continue;
|
|
14291
14266
|
}
|
|
14292
|
-
result.llm = name;
|
|
14293
|
-
result.llmConfig = this.llms[name];
|
|
14294
14267
|
result.stream = this.streamWrapper([chunk], reader);
|
|
14295
14268
|
return result;
|
|
14296
14269
|
}
|
|
@@ -14298,7 +14271,6 @@ class RetryLanguageModel {
|
|
|
14298
14271
|
if (e?.name === "AbortError") {
|
|
14299
14272
|
throw e;
|
|
14300
14273
|
}
|
|
14301
|
-
lastError = e;
|
|
14302
14274
|
if (Log.isEnableInfo()) {
|
|
14303
14275
|
Log.info(`LLM stream request, name: ${name} => `, {
|
|
14304
14276
|
tools: options.mode?.tools,
|
|
@@ -14308,7 +14280,7 @@ class RetryLanguageModel {
|
|
|
14308
14280
|
Log.error(`LLM error, name: ${name} => `, e);
|
|
14309
14281
|
}
|
|
14310
14282
|
}
|
|
14311
|
-
return Promise.reject(
|
|
14283
|
+
return Promise.reject(new Error("No LLM available"));
|
|
14312
14284
|
}
|
|
14313
14285
|
async getLLM(name) {
|
|
14314
14286
|
const llm = this.llms[name];
|
|
@@ -14406,12 +14378,6 @@ class RetryLanguageModel {
|
|
|
14406
14378
|
},
|
|
14407
14379
|
});
|
|
14408
14380
|
}
|
|
14409
|
-
get Llms() {
|
|
14410
|
-
return this.llms;
|
|
14411
|
-
}
|
|
14412
|
-
get Names() {
|
|
14413
|
-
return this.names;
|
|
14414
|
-
}
|
|
14415
14381
|
}
|
|
14416
14382
|
|
|
14417
14383
|
var domParser = {};
|
|
@@ -16859,21 +16825,11 @@ function requireDomParser () {
|
|
|
16859
16825
|
|
|
16860
16826
|
var domParserExports = requireDomParser();
|
|
16861
16827
|
|
|
16862
|
-
function parseWorkflow(taskId, xml, done
|
|
16863
|
-
let _workflow = null;
|
|
16828
|
+
function parseWorkflow(taskId, xml, done) {
|
|
16864
16829
|
try {
|
|
16865
|
-
if (thinking) {
|
|
16866
|
-
_workflow = {
|
|
16867
|
-
taskId: taskId,
|
|
16868
|
-
name: "",
|
|
16869
|
-
thought: thinking,
|
|
16870
|
-
agents: [],
|
|
16871
|
-
xml: xml,
|
|
16872
|
-
};
|
|
16873
|
-
}
|
|
16874
16830
|
let sIdx = xml.indexOf("<root>");
|
|
16875
16831
|
if (sIdx == -1) {
|
|
16876
|
-
return
|
|
16832
|
+
return null;
|
|
16877
16833
|
}
|
|
16878
16834
|
xml = xml.substring(sIdx);
|
|
16879
16835
|
let eIdx = xml.indexOf("</root>");
|
|
@@ -16887,14 +16843,13 @@ function parseWorkflow(taskId, xml, done, thinking) {
|
|
|
16887
16843
|
const doc = parser.parseFromString(xml, "text/xml");
|
|
16888
16844
|
let root = doc.documentElement;
|
|
16889
16845
|
if (root.tagName !== "root") {
|
|
16890
|
-
return
|
|
16846
|
+
return null;
|
|
16891
16847
|
}
|
|
16892
|
-
|
|
16893
|
-
const thought = root.getElementsByTagName("thought")[0]?.textContent || "";
|
|
16848
|
+
let agents = [];
|
|
16894
16849
|
const workflow = {
|
|
16895
16850
|
taskId: taskId,
|
|
16896
16851
|
name: root.getElementsByTagName("name")[0]?.textContent || "",
|
|
16897
|
-
thought:
|
|
16852
|
+
thought: root.getElementsByTagName("thought")[0]?.textContent || "",
|
|
16898
16853
|
agents: agents,
|
|
16899
16854
|
xml: xml,
|
|
16900
16855
|
};
|
|
@@ -16927,7 +16882,7 @@ function parseWorkflow(taskId, xml, done, thinking) {
|
|
|
16927
16882
|
throw e;
|
|
16928
16883
|
}
|
|
16929
16884
|
else {
|
|
16930
|
-
return
|
|
16885
|
+
return null;
|
|
16931
16886
|
}
|
|
16932
16887
|
}
|
|
16933
16888
|
}
|
|
@@ -17005,7 +16960,7 @@ function buildAgentRootXml(agentXml, mainTaskPrompt, nodeCallback) {
|
|
|
17005
16960
|
.replace("<task>", "<currentTask>")
|
|
17006
16961
|
.replace("</task>", "</currentTask>");
|
|
17007
16962
|
const xmlPrompt = `<root>${prefix}<mainTask>${mainTaskPrompt}</mainTask>${agentInnerHTML}</root>`;
|
|
17008
|
-
return xmlPrompt.replace(/ /g, " ").replace(
|
|
16963
|
+
return xmlPrompt.replace(/ /g, " ").replace(' </root>', '</root>');
|
|
17009
16964
|
}
|
|
17010
16965
|
function extractAgentXmlNode(agentXml, nodeId) {
|
|
17011
16966
|
const parser = new domParserExports.DOMParser();
|
|
@@ -17037,92 +16992,6 @@ function getInnerXML(node) {
|
|
|
17037
16992
|
}
|
|
17038
16993
|
return result;
|
|
17039
16994
|
}
|
|
17040
|
-
function buildSimpleAgentWorkflow({ taskId, name, agentName, task, taskNodes, }) {
|
|
17041
|
-
if (!taskNodes || taskNodes.length == 0) {
|
|
17042
|
-
taskNodes = [task];
|
|
17043
|
-
}
|
|
17044
|
-
const workflow = {
|
|
17045
|
-
taskId: taskId,
|
|
17046
|
-
name: name,
|
|
17047
|
-
thought: "",
|
|
17048
|
-
agents: [
|
|
17049
|
-
{
|
|
17050
|
-
id: taskId + "-00",
|
|
17051
|
-
name: agentName,
|
|
17052
|
-
task: task,
|
|
17053
|
-
nodes: taskNodes.map((node) => {
|
|
17054
|
-
return {
|
|
17055
|
-
type: "normal",
|
|
17056
|
-
text: node,
|
|
17057
|
-
};
|
|
17058
|
-
}),
|
|
17059
|
-
xml: "",
|
|
17060
|
-
},
|
|
17061
|
-
],
|
|
17062
|
-
xml: "",
|
|
17063
|
-
};
|
|
17064
|
-
workflow.taskPrompt = task;
|
|
17065
|
-
resetWorkflowXml(workflow);
|
|
17066
|
-
return workflow;
|
|
17067
|
-
}
|
|
17068
|
-
function resetWorkflowXml(workflow) {
|
|
17069
|
-
const agents = [];
|
|
17070
|
-
for (let i = 0; i < workflow.agents.length; i++) {
|
|
17071
|
-
const agent = workflow.agents[i];
|
|
17072
|
-
const nodes = agent.nodes
|
|
17073
|
-
.map((node) => {
|
|
17074
|
-
if (node.type == "forEach") {
|
|
17075
|
-
const forEachNodes = [];
|
|
17076
|
-
for (let j = 0; j < node.nodes.length; j++) {
|
|
17077
|
-
const _node = node.nodes[j];
|
|
17078
|
-
const input = _node.input ? ` input="${_node.input}"` : "";
|
|
17079
|
-
const output = _node.output ? ` output="${_node.output}"` : "";
|
|
17080
|
-
forEachNodes.push(` <node${input}${output}>${_node.text}</node>`);
|
|
17081
|
-
}
|
|
17082
|
-
return ` <forEach items="${node.items || ""}">
|
|
17083
|
-
${forEachNodes.join("\n")}
|
|
17084
|
-
</forEach>`;
|
|
17085
|
-
}
|
|
17086
|
-
else if (node.type == "watch") {
|
|
17087
|
-
const watchNodes = [];
|
|
17088
|
-
for (let j = 0; j < node.triggerNodes.length; j++) {
|
|
17089
|
-
const _node = node.triggerNodes[j];
|
|
17090
|
-
const input = _node.input ? ` input="${_node.input}"` : "";
|
|
17091
|
-
const output = _node.output ? ` output="${_node.output}"` : "";
|
|
17092
|
-
watchNodes.push(` <node${input}${output}>${_node.text}</node>`);
|
|
17093
|
-
}
|
|
17094
|
-
return ` <watch event="${node.event || "dom"}" loop="${node.loop ? "true" : "false"}">
|
|
17095
|
-
<description>${node.description}</description>
|
|
17096
|
-
<trigger>
|
|
17097
|
-
${watchNodes.join("\n")}
|
|
17098
|
-
</trigger>
|
|
17099
|
-
</watch>`;
|
|
17100
|
-
}
|
|
17101
|
-
else {
|
|
17102
|
-
const input = node.input ? ` input="${node.input}"` : "";
|
|
17103
|
-
const output = node.output ? ` output="${node.output}"` : "";
|
|
17104
|
-
return ` <node${input}${output}>${node.text}</node>`;
|
|
17105
|
-
}
|
|
17106
|
-
})
|
|
17107
|
-
.join("\n");
|
|
17108
|
-
const agentXml = ` <agent name="${agent.name}">
|
|
17109
|
-
<task>${agent.task}</task>
|
|
17110
|
-
<nodes>
|
|
17111
|
-
${nodes}
|
|
17112
|
-
</nodes>
|
|
17113
|
-
</agent>`;
|
|
17114
|
-
agent.xml = agentXml;
|
|
17115
|
-
agents.push(agentXml);
|
|
17116
|
-
}
|
|
17117
|
-
const xml = `<root>
|
|
17118
|
-
<name>${workflow.name}</name>
|
|
17119
|
-
<thought>${workflow.thought}</thought>
|
|
17120
|
-
<agents>
|
|
17121
|
-
${agents.join("\n")}
|
|
17122
|
-
</agents>
|
|
17123
|
-
</root>`;
|
|
17124
|
-
workflow.xml = xml;
|
|
17125
|
-
}
|
|
17126
16995
|
|
|
17127
16996
|
const TOOL_NAME$5 = "task_snapshot";
|
|
17128
16997
|
class TaskSnapshotTool {
|
|
@@ -17172,425 +17041,158 @@ class TaskSnapshotTool {
|
|
|
17172
17041
|
}
|
|
17173
17042
|
}
|
|
17174
17043
|
|
|
17175
|
-
|
|
17176
|
-
|
|
17177
|
-
|
|
17178
|
-
|
|
17044
|
+
function extractUsedTool(messages, agentTools) {
|
|
17045
|
+
let tools = [];
|
|
17046
|
+
let toolNames = [];
|
|
17047
|
+
for (let i = 0; i < messages.length; i++) {
|
|
17048
|
+
let message = messages[i];
|
|
17049
|
+
if (message.role == "tool") {
|
|
17050
|
+
for (let j = 0; j < message.content.length; j++) {
|
|
17051
|
+
let toolName = message.content[j].toolName;
|
|
17052
|
+
if (toolNames.indexOf(toolName) > -1) {
|
|
17053
|
+
continue;
|
|
17054
|
+
}
|
|
17055
|
+
toolNames.push(toolName);
|
|
17056
|
+
let tool = agentTools.filter((tool) => tool.name === toolName)[0];
|
|
17057
|
+
if (tool) {
|
|
17058
|
+
tools.push(tool);
|
|
17059
|
+
}
|
|
17060
|
+
}
|
|
17061
|
+
}
|
|
17062
|
+
}
|
|
17063
|
+
return tools;
|
|
17064
|
+
}
|
|
17065
|
+
function removeDuplicateToolUse(results) {
|
|
17066
|
+
if (results.length <= 1 ||
|
|
17067
|
+
results.filter((r) => r.type == "tool-call").length <= 1) {
|
|
17068
|
+
return results;
|
|
17069
|
+
}
|
|
17070
|
+
let _results = [];
|
|
17071
|
+
let tool_uniques = [];
|
|
17072
|
+
for (let i = 0; i < results.length; i++) {
|
|
17073
|
+
if (results[i].type === "tool-call") {
|
|
17074
|
+
let tool = results[i];
|
|
17075
|
+
let key = tool.toolName + tool.args;
|
|
17076
|
+
if (tool_uniques.indexOf(key) == -1) {
|
|
17077
|
+
_results.push(results[i]);
|
|
17078
|
+
tool_uniques.push(key);
|
|
17079
|
+
}
|
|
17080
|
+
}
|
|
17081
|
+
else {
|
|
17082
|
+
_results.push(results[i]);
|
|
17083
|
+
}
|
|
17179
17084
|
}
|
|
17180
|
-
|
|
17181
|
-
|
|
17182
|
-
|
|
17085
|
+
return _results;
|
|
17086
|
+
}
|
|
17087
|
+
async function compressAgentMessages(agentContext, rlm, messages, tools) {
|
|
17088
|
+
if (messages.length < 10) {
|
|
17089
|
+
return;
|
|
17183
17090
|
}
|
|
17184
|
-
|
|
17185
|
-
let
|
|
17186
|
-
let
|
|
17187
|
-
let
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17191
|
-
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
stepController.signal,
|
|
17091
|
+
// extract used tool
|
|
17092
|
+
let usedTools = extractUsedTool(messages, tools);
|
|
17093
|
+
let snapshotTool = new TaskSnapshotTool();
|
|
17094
|
+
let newTools = mergeTools(usedTools, [
|
|
17095
|
+
{
|
|
17096
|
+
type: "function",
|
|
17097
|
+
name: snapshotTool.name,
|
|
17098
|
+
description: snapshotTool.description,
|
|
17099
|
+
parameters: snapshotTool.parameters,
|
|
17100
|
+
},
|
|
17195
17101
|
]);
|
|
17196
|
-
|
|
17197
|
-
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
|
|
17201
|
-
|
|
17202
|
-
|
|
17203
|
-
|
|
17204
|
-
|
|
17205
|
-
context.currentStepControllers.add(stepController);
|
|
17206
|
-
result = await rlm.callStream(request);
|
|
17102
|
+
// handle messages
|
|
17103
|
+
let lastToolIndex = messages.length - 1;
|
|
17104
|
+
let newMessages = messages;
|
|
17105
|
+
for (let r = newMessages.length - 1; r > 3; r--) {
|
|
17106
|
+
if (newMessages[r].role == "tool") {
|
|
17107
|
+
newMessages = newMessages.slice(0, r + 1);
|
|
17108
|
+
lastToolIndex = r;
|
|
17109
|
+
break;
|
|
17110
|
+
}
|
|
17207
17111
|
}
|
|
17208
|
-
|
|
17209
|
-
|
|
17210
|
-
|
|
17211
|
-
|
|
17212
|
-
|
|
17213
|
-
|
|
17214
|
-
|
|
17215
|
-
|
|
17216
|
-
|
|
17217
|
-
|
|
17218
|
-
|
|
17112
|
+
newMessages.push({
|
|
17113
|
+
role: "user",
|
|
17114
|
+
content: [
|
|
17115
|
+
{
|
|
17116
|
+
type: "text",
|
|
17117
|
+
text: "Please create a snapshot backup of the current task, keeping only key important information and node completion status.",
|
|
17118
|
+
},
|
|
17119
|
+
],
|
|
17120
|
+
});
|
|
17121
|
+
// compress snapshot
|
|
17122
|
+
let result = await callLLM(agentContext, rlm, newMessages, newTools, true, {
|
|
17123
|
+
type: "tool",
|
|
17124
|
+
toolName: snapshotTool.name,
|
|
17125
|
+
});
|
|
17126
|
+
let toolCall = result.filter((s) => s.type == "tool-call")[0];
|
|
17127
|
+
let args = typeof toolCall.args == "string"
|
|
17128
|
+
? JSON.parse(toolCall.args || "{}")
|
|
17129
|
+
: toolCall.args || {};
|
|
17130
|
+
let toolResult = await snapshotTool.execute(args, agentContext);
|
|
17131
|
+
let callback = agentContext.context.config.callback;
|
|
17132
|
+
if (callback) {
|
|
17133
|
+
await callback.onMessage({
|
|
17134
|
+
taskId: agentContext.context.taskId,
|
|
17135
|
+
agentName: agentContext.agent.Name,
|
|
17136
|
+
nodeId: agentContext.agentChain.agent.id,
|
|
17137
|
+
type: "tool_result",
|
|
17138
|
+
toolId: toolCall.toolCallId,
|
|
17139
|
+
toolName: toolCall.toolName,
|
|
17140
|
+
params: args,
|
|
17141
|
+
toolResult: toolResult,
|
|
17142
|
+
}, agentContext);
|
|
17143
|
+
}
|
|
17144
|
+
// handle original messages
|
|
17145
|
+
let firstToolIndex = 3;
|
|
17146
|
+
for (let i = 0; i < messages.length; i++) {
|
|
17147
|
+
if (messages[0].role == "tool") {
|
|
17148
|
+
firstToolIndex = i;
|
|
17149
|
+
break;
|
|
17219
17150
|
}
|
|
17220
|
-
throw e;
|
|
17221
17151
|
}
|
|
17222
|
-
|
|
17223
|
-
|
|
17224
|
-
|
|
17225
|
-
|
|
17226
|
-
|
|
17227
|
-
|
|
17228
|
-
|
|
17229
|
-
|
|
17230
|
-
|
|
17231
|
-
|
|
17232
|
-
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
|
|
17239
|
-
|
|
17240
|
-
|
|
17241
|
-
continue;
|
|
17152
|
+
// system, user, assistant, tool(first), [...], <user>, assistant, tool(last), ...
|
|
17153
|
+
messages.splice(firstToolIndex + 1, lastToolIndex - firstToolIndex - 2, {
|
|
17154
|
+
role: "user",
|
|
17155
|
+
content: toolResult.content.filter((s) => s.type == "text"),
|
|
17156
|
+
});
|
|
17157
|
+
}
|
|
17158
|
+
function handleLargeContextMessages(messages) {
|
|
17159
|
+
let imageNum = 0;
|
|
17160
|
+
let fileNum = 0;
|
|
17161
|
+
let maxNum = config.maxDialogueImgFileNum;
|
|
17162
|
+
let longTextTools = {};
|
|
17163
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
17164
|
+
let message = messages[i];
|
|
17165
|
+
if (message.role == "user") {
|
|
17166
|
+
for (let j = 0; j < message.content.length; j++) {
|
|
17167
|
+
let content = message.content[j];
|
|
17168
|
+
if (content.type == "image") {
|
|
17169
|
+
if (++imageNum <= maxNum) {
|
|
17170
|
+
break;
|
|
17242
17171
|
}
|
|
17243
|
-
|
|
17244
|
-
await streamCallback.onMessage({
|
|
17245
|
-
taskId: context.taskId,
|
|
17246
|
-
agentName: agentNode.name,
|
|
17247
|
-
nodeId: agentNode.id,
|
|
17172
|
+
content = {
|
|
17248
17173
|
type: "text",
|
|
17249
|
-
|
|
17250
|
-
|
|
17251
|
-
|
|
17252
|
-
|
|
17253
|
-
|
|
17254
|
-
|
|
17255
|
-
|
|
17256
|
-
agentName: agentNode.name,
|
|
17257
|
-
nodeId: agentNode.id,
|
|
17258
|
-
type: "tool_use",
|
|
17259
|
-
toolId: toolPart.toolCallId,
|
|
17260
|
-
toolName: toolPart.toolName,
|
|
17261
|
-
params: toolPart.args || {},
|
|
17262
|
-
}, agentContext);
|
|
17263
|
-
toolPart = null;
|
|
17174
|
+
text: "[image]",
|
|
17175
|
+
};
|
|
17176
|
+
message.content[j] = content;
|
|
17177
|
+
}
|
|
17178
|
+
else if (content.type == "file") {
|
|
17179
|
+
if (++fileNum <= maxNum) {
|
|
17180
|
+
break;
|
|
17264
17181
|
}
|
|
17265
|
-
|
|
17182
|
+
content = {
|
|
17183
|
+
type: "text",
|
|
17184
|
+
text: "[file]",
|
|
17185
|
+
};
|
|
17186
|
+
message.content[j] = content;
|
|
17266
17187
|
}
|
|
17267
|
-
|
|
17268
|
-
|
|
17269
|
-
|
|
17270
|
-
|
|
17271
|
-
|
|
17272
|
-
|
|
17273
|
-
|
|
17274
|
-
|
|
17275
|
-
streamDone: false,
|
|
17276
|
-
text: thinkText,
|
|
17277
|
-
}, agentContext);
|
|
17278
|
-
break;
|
|
17279
|
-
}
|
|
17280
|
-
case "tool-call-delta": {
|
|
17281
|
-
if (!textStreamDone) {
|
|
17282
|
-
textStreamDone = true;
|
|
17283
|
-
await streamCallback.onMessage({
|
|
17284
|
-
taskId: context.taskId,
|
|
17285
|
-
agentName: agentNode.name,
|
|
17286
|
-
nodeId: agentNode.id,
|
|
17287
|
-
type: "text",
|
|
17288
|
-
streamId,
|
|
17289
|
-
streamDone: true,
|
|
17290
|
-
text: streamText,
|
|
17291
|
-
}, agentContext);
|
|
17292
|
-
}
|
|
17293
|
-
toolArgsText += chunk.argsTextDelta || "";
|
|
17294
|
-
await streamCallback.onMessage({
|
|
17295
|
-
taskId: context.taskId,
|
|
17296
|
-
agentName: agentNode.name,
|
|
17297
|
-
nodeId: agentNode.id,
|
|
17298
|
-
type: "tool_streaming",
|
|
17299
|
-
toolId: chunk.toolCallId,
|
|
17300
|
-
toolName: chunk.toolName,
|
|
17301
|
-
paramsText: toolArgsText,
|
|
17302
|
-
}, agentContext);
|
|
17303
|
-
if (toolPart == null) {
|
|
17304
|
-
toolPart = {
|
|
17305
|
-
type: "tool-call",
|
|
17306
|
-
toolCallId: chunk.toolCallId,
|
|
17307
|
-
toolName: chunk.toolName,
|
|
17308
|
-
args: {},
|
|
17309
|
-
};
|
|
17310
|
-
toolParts.push(toolPart);
|
|
17311
|
-
}
|
|
17312
|
-
break;
|
|
17313
|
-
}
|
|
17314
|
-
case "tool-call": {
|
|
17315
|
-
toolArgsText = "";
|
|
17316
|
-
let args = chunk.args ? JSON.parse(chunk.args) : {};
|
|
17317
|
-
let message = {
|
|
17318
|
-
taskId: context.taskId,
|
|
17319
|
-
agentName: agentNode.name,
|
|
17320
|
-
nodeId: agentNode.id,
|
|
17321
|
-
type: "tool_use",
|
|
17322
|
-
toolId: chunk.toolCallId,
|
|
17323
|
-
toolName: chunk.toolName,
|
|
17324
|
-
params: args,
|
|
17325
|
-
};
|
|
17326
|
-
await streamCallback.onMessage(message, agentContext);
|
|
17327
|
-
if (toolPart == null) {
|
|
17328
|
-
toolParts.push({
|
|
17329
|
-
type: "tool-call",
|
|
17330
|
-
toolCallId: chunk.toolCallId,
|
|
17331
|
-
toolName: chunk.toolName,
|
|
17332
|
-
args: message.params || args,
|
|
17333
|
-
});
|
|
17334
|
-
}
|
|
17335
|
-
else {
|
|
17336
|
-
toolPart.args = message.params || args;
|
|
17337
|
-
toolPart = null;
|
|
17338
|
-
}
|
|
17339
|
-
break;
|
|
17340
|
-
}
|
|
17341
|
-
case "file": {
|
|
17342
|
-
await streamCallback.onMessage({
|
|
17343
|
-
taskId: context.taskId,
|
|
17344
|
-
agentName: agentNode.name,
|
|
17345
|
-
nodeId: agentNode.id,
|
|
17346
|
-
type: "file",
|
|
17347
|
-
mimeType: chunk.mimeType,
|
|
17348
|
-
data: chunk.data,
|
|
17349
|
-
}, agentContext);
|
|
17350
|
-
break;
|
|
17351
|
-
}
|
|
17352
|
-
case "error": {
|
|
17353
|
-
Log.error(`${agentNode.name} agent error: `, chunk);
|
|
17354
|
-
await streamCallback.onMessage({
|
|
17355
|
-
taskId: context.taskId,
|
|
17356
|
-
agentName: agentNode.name,
|
|
17357
|
-
nodeId: agentNode.id,
|
|
17358
|
-
type: "error",
|
|
17359
|
-
error: chunk.error,
|
|
17360
|
-
}, agentContext);
|
|
17361
|
-
throw new Error("LLM Error: " + chunk.error);
|
|
17362
|
-
}
|
|
17363
|
-
case "finish": {
|
|
17364
|
-
if (!textStreamDone) {
|
|
17365
|
-
textStreamDone = true;
|
|
17366
|
-
await streamCallback.onMessage({
|
|
17367
|
-
taskId: context.taskId,
|
|
17368
|
-
agentName: agentNode.name,
|
|
17369
|
-
nodeId: agentNode.id,
|
|
17370
|
-
type: "text",
|
|
17371
|
-
streamId,
|
|
17372
|
-
streamDone: true,
|
|
17373
|
-
text: streamText,
|
|
17374
|
-
}, agentContext);
|
|
17375
|
-
}
|
|
17376
|
-
if (toolPart) {
|
|
17377
|
-
await streamCallback.onMessage({
|
|
17378
|
-
taskId: context.taskId,
|
|
17379
|
-
agentName: agentNode.name,
|
|
17380
|
-
nodeId: agentNode.id,
|
|
17381
|
-
type: "tool_use",
|
|
17382
|
-
toolId: toolPart.toolCallId,
|
|
17383
|
-
toolName: toolPart.toolName,
|
|
17384
|
-
params: toolPart.args || {},
|
|
17385
|
-
}, agentContext);
|
|
17386
|
-
toolPart = null;
|
|
17387
|
-
}
|
|
17388
|
-
await streamCallback.onMessage({
|
|
17389
|
-
taskId: context.taskId,
|
|
17390
|
-
agentName: agentNode.name,
|
|
17391
|
-
nodeId: agentNode.id,
|
|
17392
|
-
type: "finish",
|
|
17393
|
-
finishReason: chunk.finishReason,
|
|
17394
|
-
usage: chunk.usage,
|
|
17395
|
-
}, agentContext);
|
|
17396
|
-
if (chunk.finishReason === "length" &&
|
|
17397
|
-
messages.length >= 10 &&
|
|
17398
|
-
!noCompress &&
|
|
17399
|
-
!retry) {
|
|
17400
|
-
await compressAgentMessages(agentContext, rlm, messages, tools);
|
|
17401
|
-
return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
|
|
17402
|
-
}
|
|
17403
|
-
break;
|
|
17404
|
-
}
|
|
17405
|
-
}
|
|
17406
|
-
}
|
|
17407
|
-
}
|
|
17408
|
-
catch (e) {
|
|
17409
|
-
if (e?.name === "AbortError") {
|
|
17410
|
-
throw e;
|
|
17411
|
-
}
|
|
17412
|
-
if (!retry && (e + "").indexOf("network error") > -1) {
|
|
17413
|
-
return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
|
|
17414
|
-
}
|
|
17415
|
-
throw e;
|
|
17416
|
-
}
|
|
17417
|
-
finally {
|
|
17418
|
-
reader.releaseLock();
|
|
17419
|
-
context.currentStepControllers.delete(stepController);
|
|
17420
|
-
}
|
|
17421
|
-
agentChain.agentResult = streamText;
|
|
17422
|
-
return streamText
|
|
17423
|
-
? [
|
|
17424
|
-
{ type: "text", text: streamText },
|
|
17425
|
-
...toolParts,
|
|
17426
|
-
]
|
|
17427
|
-
: toolParts;
|
|
17428
|
-
}
|
|
17429
|
-
function appendUserConversation(agentContext, messages) {
|
|
17430
|
-
const userPrompts = agentContext.context.conversation
|
|
17431
|
-
.splice(0, agentContext.context.conversation.length)
|
|
17432
|
-
.filter((s) => !!s);
|
|
17433
|
-
if (userPrompts.length > 0) {
|
|
17434
|
-
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");
|
|
17435
|
-
messages.push({
|
|
17436
|
-
role: "user",
|
|
17437
|
-
content: [{ type: "text", text: prompt }],
|
|
17438
|
-
});
|
|
17439
|
-
}
|
|
17440
|
-
}
|
|
17441
|
-
|
|
17442
|
-
function extractUsedTool(messages, agentTools) {
|
|
17443
|
-
let tools = [];
|
|
17444
|
-
let toolNames = [];
|
|
17445
|
-
for (let i = 0; i < messages.length; i++) {
|
|
17446
|
-
let message = messages[i];
|
|
17447
|
-
if (message.role == "tool") {
|
|
17448
|
-
for (let j = 0; j < message.content.length; j++) {
|
|
17449
|
-
let toolName = message.content[j].toolName;
|
|
17450
|
-
if (toolNames.indexOf(toolName) > -1) {
|
|
17451
|
-
continue;
|
|
17452
|
-
}
|
|
17453
|
-
toolNames.push(toolName);
|
|
17454
|
-
let tool = agentTools.filter((tool) => tool.name === toolName)[0];
|
|
17455
|
-
if (tool) {
|
|
17456
|
-
tools.push(tool);
|
|
17457
|
-
}
|
|
17458
|
-
}
|
|
17459
|
-
}
|
|
17460
|
-
}
|
|
17461
|
-
return tools;
|
|
17462
|
-
}
|
|
17463
|
-
function removeDuplicateToolUse(results) {
|
|
17464
|
-
if (results.length <= 1 ||
|
|
17465
|
-
results.filter((r) => r.type == "tool-call").length <= 1) {
|
|
17466
|
-
return results;
|
|
17467
|
-
}
|
|
17468
|
-
let _results = [];
|
|
17469
|
-
let tool_uniques = [];
|
|
17470
|
-
for (let i = 0; i < results.length; i++) {
|
|
17471
|
-
if (results[i].type === "tool-call") {
|
|
17472
|
-
let tool = results[i];
|
|
17473
|
-
let key = tool.toolName + tool.args;
|
|
17474
|
-
if (tool_uniques.indexOf(key) == -1) {
|
|
17475
|
-
_results.push(results[i]);
|
|
17476
|
-
tool_uniques.push(key);
|
|
17477
|
-
}
|
|
17478
|
-
}
|
|
17479
|
-
else {
|
|
17480
|
-
_results.push(results[i]);
|
|
17481
|
-
}
|
|
17482
|
-
}
|
|
17483
|
-
return _results;
|
|
17484
|
-
}
|
|
17485
|
-
async function compressAgentMessages(agentContext, rlm, messages, tools) {
|
|
17486
|
-
if (messages.length < 10) {
|
|
17487
|
-
return;
|
|
17488
|
-
}
|
|
17489
|
-
// extract used tool
|
|
17490
|
-
let usedTools = extractUsedTool(messages, tools);
|
|
17491
|
-
let snapshotTool = new TaskSnapshotTool();
|
|
17492
|
-
let newTools = mergeTools(usedTools, [
|
|
17493
|
-
{
|
|
17494
|
-
type: "function",
|
|
17495
|
-
name: snapshotTool.name,
|
|
17496
|
-
description: snapshotTool.description,
|
|
17497
|
-
parameters: snapshotTool.parameters,
|
|
17498
|
-
},
|
|
17499
|
-
]);
|
|
17500
|
-
// handle messages
|
|
17501
|
-
let lastToolIndex = messages.length - 1;
|
|
17502
|
-
let newMessages = messages;
|
|
17503
|
-
for (let r = newMessages.length - 1; r > 3; r--) {
|
|
17504
|
-
if (newMessages[r].role == "tool") {
|
|
17505
|
-
newMessages = newMessages.slice(0, r + 1);
|
|
17506
|
-
lastToolIndex = r;
|
|
17507
|
-
break;
|
|
17508
|
-
}
|
|
17509
|
-
}
|
|
17510
|
-
newMessages.push({
|
|
17511
|
-
role: "user",
|
|
17512
|
-
content: [
|
|
17513
|
-
{
|
|
17514
|
-
type: "text",
|
|
17515
|
-
text: "Please create a snapshot backup of the current task, keeping only key important information and node completion status.",
|
|
17516
|
-
},
|
|
17517
|
-
],
|
|
17518
|
-
});
|
|
17519
|
-
// compress snapshot
|
|
17520
|
-
let result = await callAgentLLM(agentContext, rlm, newMessages, newTools, true, {
|
|
17521
|
-
type: "tool",
|
|
17522
|
-
toolName: snapshotTool.name,
|
|
17523
|
-
});
|
|
17524
|
-
let toolCall = result.filter((s) => s.type == "tool-call")[0];
|
|
17525
|
-
let args = typeof toolCall.args == "string"
|
|
17526
|
-
? JSON.parse(toolCall.args || "{}")
|
|
17527
|
-
: toolCall.args || {};
|
|
17528
|
-
let toolResult = await snapshotTool.execute(args, agentContext);
|
|
17529
|
-
let callback = agentContext.context.config.callback;
|
|
17530
|
-
if (callback) {
|
|
17531
|
-
await callback.onMessage({
|
|
17532
|
-
taskId: agentContext.context.taskId,
|
|
17533
|
-
agentName: agentContext.agent.Name,
|
|
17534
|
-
nodeId: agentContext.agentChain.agent.id,
|
|
17535
|
-
type: "tool_result",
|
|
17536
|
-
toolId: toolCall.toolCallId,
|
|
17537
|
-
toolName: toolCall.toolName,
|
|
17538
|
-
params: args,
|
|
17539
|
-
toolResult: toolResult,
|
|
17540
|
-
}, agentContext);
|
|
17541
|
-
}
|
|
17542
|
-
// handle original messages
|
|
17543
|
-
let firstToolIndex = 3;
|
|
17544
|
-
for (let i = 0; i < messages.length; i++) {
|
|
17545
|
-
if (messages[0].role == "tool") {
|
|
17546
|
-
firstToolIndex = i;
|
|
17547
|
-
break;
|
|
17548
|
-
}
|
|
17549
|
-
}
|
|
17550
|
-
// system, user, assistant, tool(first), [...], <user>, assistant, tool(last), ...
|
|
17551
|
-
messages.splice(firstToolIndex + 1, lastToolIndex - firstToolIndex - 2, {
|
|
17552
|
-
role: "user",
|
|
17553
|
-
content: toolResult.content.filter((s) => s.type == "text"),
|
|
17554
|
-
});
|
|
17555
|
-
}
|
|
17556
|
-
function handleLargeContextMessages(messages) {
|
|
17557
|
-
let imageNum = 0;
|
|
17558
|
-
let fileNum = 0;
|
|
17559
|
-
let maxNum = config.maxDialogueImgFileNum;
|
|
17560
|
-
let longTextTools = {};
|
|
17561
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
17562
|
-
let message = messages[i];
|
|
17563
|
-
if (message.role == "user") {
|
|
17564
|
-
for (let j = 0; j < message.content.length; j++) {
|
|
17565
|
-
let content = message.content[j];
|
|
17566
|
-
if (content.type == "image") {
|
|
17567
|
-
if (++imageNum <= maxNum) {
|
|
17568
|
-
break;
|
|
17569
|
-
}
|
|
17570
|
-
content = {
|
|
17571
|
-
type: "text",
|
|
17572
|
-
text: "[image]",
|
|
17573
|
-
};
|
|
17574
|
-
message.content[j] = content;
|
|
17575
|
-
}
|
|
17576
|
-
else if (content.type == "file") {
|
|
17577
|
-
if (++fileNum <= maxNum) {
|
|
17578
|
-
break;
|
|
17579
|
-
}
|
|
17580
|
-
content = {
|
|
17581
|
-
type: "text",
|
|
17582
|
-
text: "[file]",
|
|
17583
|
-
};
|
|
17584
|
-
message.content[j] = content;
|
|
17585
|
-
}
|
|
17586
|
-
}
|
|
17587
|
-
}
|
|
17588
|
-
else if (message.role == "tool") {
|
|
17589
|
-
for (let j = 0; j < message.content.length; j++) {
|
|
17590
|
-
let toolResult = message.content[j];
|
|
17591
|
-
let toolContent = toolResult.content;
|
|
17592
|
-
if (!toolContent || toolContent.length == 0) {
|
|
17593
|
-
continue;
|
|
17188
|
+
}
|
|
17189
|
+
}
|
|
17190
|
+
else if (message.role == "tool") {
|
|
17191
|
+
for (let j = 0; j < message.content.length; j++) {
|
|
17192
|
+
let toolResult = message.content[j];
|
|
17193
|
+
let toolContent = toolResult.content;
|
|
17194
|
+
if (!toolContent || toolContent.length == 0) {
|
|
17195
|
+
continue;
|
|
17594
17196
|
}
|
|
17595
17197
|
for (let r = 0; r < toolContent.length; r++) {
|
|
17596
17198
|
let _content = toolContent[r];
|
|
@@ -18393,24 +17995,21 @@ class Agent {
|
|
|
18393
17995
|
mcpClient && (await mcpClient.close());
|
|
18394
17996
|
}
|
|
18395
17997
|
}
|
|
18396
|
-
async runWithContext(agentContext, mcpClient, maxReactNum = 100
|
|
17998
|
+
async runWithContext(agentContext, mcpClient, maxReactNum = 100) {
|
|
18397
17999
|
let loopNum = 0;
|
|
18398
|
-
this.agentContext = agentContext;
|
|
18399
18000
|
let context = agentContext.context;
|
|
18400
18001
|
let agentNode = agentContext.agentChain.agent;
|
|
18401
18002
|
const tools = [...this.tools, ...this.system_auto_tools(agentNode)];
|
|
18402
|
-
|
|
18003
|
+
let messages = [
|
|
18403
18004
|
{
|
|
18404
18005
|
role: "system",
|
|
18405
18006
|
content: await this.buildSystemPrompt(agentContext, tools),
|
|
18406
18007
|
},
|
|
18407
|
-
...historyMessages,
|
|
18408
18008
|
{
|
|
18409
18009
|
role: "user",
|
|
18410
18010
|
content: await this.buildUserPrompt(agentContext, tools),
|
|
18411
18011
|
},
|
|
18412
18012
|
];
|
|
18413
|
-
agentContext.messages = messages;
|
|
18414
18013
|
let rlm = new RetryLanguageModel(context.config.llms, this.llms);
|
|
18415
18014
|
let agentTools = tools;
|
|
18416
18015
|
while (loopNum < maxReactNum) {
|
|
@@ -18425,7 +18024,7 @@ class Agent {
|
|
|
18425
18024
|
}
|
|
18426
18025
|
}
|
|
18427
18026
|
await this.handleMessages(agentContext, messages, tools);
|
|
18428
|
-
let results = await
|
|
18027
|
+
let results = await callLLM(agentContext, rlm, messages, this.convertTools(agentTools), false, undefined, false, this.callback);
|
|
18429
18028
|
let finalResult = await this.handleCallResult(agentContext, messages, agentTools, results);
|
|
18430
18029
|
if (finalResult) {
|
|
18431
18030
|
return finalResult;
|
|
@@ -18667,6 +18266,29 @@ class Agent {
|
|
|
18667
18266
|
async handleMessages(agentContext, messages, tools) {
|
|
18668
18267
|
// Only keep the last image / file, large tool-text-result
|
|
18669
18268
|
handleLargeContextMessages(messages);
|
|
18269
|
+
// User dialogue
|
|
18270
|
+
const userPrompts = agentContext.context.conversation
|
|
18271
|
+
.splice(0, agentContext.context.conversation.length)
|
|
18272
|
+
.filter((s) => !!s);
|
|
18273
|
+
if (userPrompts.length > 0) {
|
|
18274
|
+
const lastMessage = messages[messages.length - 1];
|
|
18275
|
+
if (lastMessage.role == "user") {
|
|
18276
|
+
for (let i = 0; i < userPrompts.length; i++) {
|
|
18277
|
+
lastMessage.content.push({
|
|
18278
|
+
type: "text",
|
|
18279
|
+
text: userPrompts[i],
|
|
18280
|
+
});
|
|
18281
|
+
}
|
|
18282
|
+
}
|
|
18283
|
+
else {
|
|
18284
|
+
messages.push({
|
|
18285
|
+
role: "user",
|
|
18286
|
+
content: userPrompts.map((s) => {
|
|
18287
|
+
return { type: "text", text: s };
|
|
18288
|
+
}),
|
|
18289
|
+
});
|
|
18290
|
+
}
|
|
18291
|
+
}
|
|
18670
18292
|
}
|
|
18671
18293
|
async callInnerTool(fun) {
|
|
18672
18294
|
let result = await fun();
|
|
@@ -18718,9 +18340,222 @@ class Agent {
|
|
|
18718
18340
|
get McpClient() {
|
|
18719
18341
|
return this.mcpClient;
|
|
18720
18342
|
}
|
|
18721
|
-
|
|
18722
|
-
|
|
18343
|
+
}
|
|
18344
|
+
async function callLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, retry, callback) {
|
|
18345
|
+
if (messages.length >= config.compressThreshold && !noCompress) {
|
|
18346
|
+
await compressAgentMessages(agentContext, rlm, messages, tools);
|
|
18347
|
+
}
|
|
18348
|
+
let context = agentContext.context;
|
|
18349
|
+
let agentChain = agentContext.agentChain;
|
|
18350
|
+
let agentNode = agentChain.agent;
|
|
18351
|
+
let streamCallback = callback ||
|
|
18352
|
+
context.config.callback || {
|
|
18353
|
+
onMessage: async () => { },
|
|
18354
|
+
};
|
|
18355
|
+
let request = {
|
|
18356
|
+
tools: tools,
|
|
18357
|
+
toolChoice,
|
|
18358
|
+
messages: messages,
|
|
18359
|
+
abortSignal: context.controller.signal,
|
|
18360
|
+
};
|
|
18361
|
+
agentChain.agentRequest = request;
|
|
18362
|
+
let result = await rlm.callStream(request);
|
|
18363
|
+
let streamText = "";
|
|
18364
|
+
let thinkText = "";
|
|
18365
|
+
let toolArgsText = "";
|
|
18366
|
+
let streamId = uuidv4();
|
|
18367
|
+
let textStreamDone = false;
|
|
18368
|
+
let toolParts = [];
|
|
18369
|
+
const reader = result.stream.getReader();
|
|
18370
|
+
try {
|
|
18371
|
+
let toolPart = null;
|
|
18372
|
+
while (true) {
|
|
18373
|
+
await context.checkAborted();
|
|
18374
|
+
const { done, value } = await reader.read();
|
|
18375
|
+
if (done) {
|
|
18376
|
+
break;
|
|
18377
|
+
}
|
|
18378
|
+
let chunk = value;
|
|
18379
|
+
switch (chunk.type) {
|
|
18380
|
+
case "text-delta": {
|
|
18381
|
+
if (toolPart && !chunk.textDelta) {
|
|
18382
|
+
continue;
|
|
18383
|
+
}
|
|
18384
|
+
streamText += chunk.textDelta || "";
|
|
18385
|
+
await streamCallback.onMessage({
|
|
18386
|
+
taskId: context.taskId,
|
|
18387
|
+
agentName: agentNode.name,
|
|
18388
|
+
nodeId: agentNode.id,
|
|
18389
|
+
type: "text",
|
|
18390
|
+
streamId,
|
|
18391
|
+
streamDone: false,
|
|
18392
|
+
text: streamText,
|
|
18393
|
+
}, agentContext);
|
|
18394
|
+
if (toolPart) {
|
|
18395
|
+
await streamCallback.onMessage({
|
|
18396
|
+
taskId: context.taskId,
|
|
18397
|
+
agentName: agentNode.name,
|
|
18398
|
+
nodeId: agentNode.id,
|
|
18399
|
+
type: "tool_use",
|
|
18400
|
+
toolId: toolPart.toolCallId,
|
|
18401
|
+
toolName: toolPart.toolName,
|
|
18402
|
+
params: toolPart.args || {},
|
|
18403
|
+
}, agentContext);
|
|
18404
|
+
toolPart = null;
|
|
18405
|
+
}
|
|
18406
|
+
break;
|
|
18407
|
+
}
|
|
18408
|
+
case "reasoning": {
|
|
18409
|
+
thinkText += chunk.textDelta || "";
|
|
18410
|
+
await streamCallback.onMessage({
|
|
18411
|
+
taskId: context.taskId,
|
|
18412
|
+
agentName: agentNode.name,
|
|
18413
|
+
nodeId: agentNode.id,
|
|
18414
|
+
type: "thinking",
|
|
18415
|
+
streamId,
|
|
18416
|
+
streamDone: false,
|
|
18417
|
+
text: thinkText,
|
|
18418
|
+
}, agentContext);
|
|
18419
|
+
break;
|
|
18420
|
+
}
|
|
18421
|
+
case "tool-call-delta": {
|
|
18422
|
+
if (!textStreamDone) {
|
|
18423
|
+
textStreamDone = true;
|
|
18424
|
+
await streamCallback.onMessage({
|
|
18425
|
+
taskId: context.taskId,
|
|
18426
|
+
agentName: agentNode.name,
|
|
18427
|
+
nodeId: agentNode.id,
|
|
18428
|
+
type: "text",
|
|
18429
|
+
streamId,
|
|
18430
|
+
streamDone: true,
|
|
18431
|
+
text: streamText,
|
|
18432
|
+
}, agentContext);
|
|
18433
|
+
}
|
|
18434
|
+
toolArgsText += chunk.argsTextDelta || "";
|
|
18435
|
+
await streamCallback.onMessage({
|
|
18436
|
+
taskId: context.taskId,
|
|
18437
|
+
agentName: agentNode.name,
|
|
18438
|
+
nodeId: agentNode.id,
|
|
18439
|
+
type: "tool_streaming",
|
|
18440
|
+
toolId: chunk.toolCallId,
|
|
18441
|
+
toolName: chunk.toolName,
|
|
18442
|
+
paramsText: toolArgsText,
|
|
18443
|
+
}, agentContext);
|
|
18444
|
+
if (toolPart == null) {
|
|
18445
|
+
toolPart = {
|
|
18446
|
+
type: "tool-call",
|
|
18447
|
+
toolCallId: chunk.toolCallId,
|
|
18448
|
+
toolName: chunk.toolName,
|
|
18449
|
+
args: {},
|
|
18450
|
+
};
|
|
18451
|
+
toolParts.push(toolPart);
|
|
18452
|
+
}
|
|
18453
|
+
break;
|
|
18454
|
+
}
|
|
18455
|
+
case "tool-call": {
|
|
18456
|
+
toolArgsText = "";
|
|
18457
|
+
let args = chunk.args ? JSON.parse(chunk.args) : {};
|
|
18458
|
+
let message = {
|
|
18459
|
+
taskId: context.taskId,
|
|
18460
|
+
agentName: agentNode.name,
|
|
18461
|
+
nodeId: agentNode.id,
|
|
18462
|
+
type: "tool_use",
|
|
18463
|
+
toolId: chunk.toolCallId,
|
|
18464
|
+
toolName: chunk.toolName,
|
|
18465
|
+
params: args,
|
|
18466
|
+
};
|
|
18467
|
+
await streamCallback.onMessage(message, agentContext);
|
|
18468
|
+
if (toolPart == null) {
|
|
18469
|
+
toolParts.push({
|
|
18470
|
+
type: "tool-call",
|
|
18471
|
+
toolCallId: chunk.toolCallId,
|
|
18472
|
+
toolName: chunk.toolName,
|
|
18473
|
+
args: message.params || args,
|
|
18474
|
+
});
|
|
18475
|
+
}
|
|
18476
|
+
else {
|
|
18477
|
+
toolPart.args = message.params || args;
|
|
18478
|
+
toolPart = null;
|
|
18479
|
+
}
|
|
18480
|
+
break;
|
|
18481
|
+
}
|
|
18482
|
+
case "file": {
|
|
18483
|
+
await streamCallback.onMessage({
|
|
18484
|
+
taskId: context.taskId,
|
|
18485
|
+
agentName: agentNode.name,
|
|
18486
|
+
nodeId: agentNode.id,
|
|
18487
|
+
type: "file",
|
|
18488
|
+
mimeType: chunk.mimeType,
|
|
18489
|
+
data: chunk.data,
|
|
18490
|
+
}, agentContext);
|
|
18491
|
+
break;
|
|
18492
|
+
}
|
|
18493
|
+
case "error": {
|
|
18494
|
+
Log.error(`${agentNode.name} agent error: `, chunk);
|
|
18495
|
+
await streamCallback.onMessage({
|
|
18496
|
+
taskId: context.taskId,
|
|
18497
|
+
agentName: agentNode.name,
|
|
18498
|
+
nodeId: agentNode.id,
|
|
18499
|
+
type: "error",
|
|
18500
|
+
error: chunk.error,
|
|
18501
|
+
}, agentContext);
|
|
18502
|
+
throw new Error("LLM Error: " + chunk.error);
|
|
18503
|
+
}
|
|
18504
|
+
case "finish": {
|
|
18505
|
+
if (!textStreamDone) {
|
|
18506
|
+
textStreamDone = true;
|
|
18507
|
+
await streamCallback.onMessage({
|
|
18508
|
+
taskId: context.taskId,
|
|
18509
|
+
agentName: agentNode.name,
|
|
18510
|
+
nodeId: agentNode.id,
|
|
18511
|
+
type: "text",
|
|
18512
|
+
streamId,
|
|
18513
|
+
streamDone: true,
|
|
18514
|
+
text: streamText,
|
|
18515
|
+
}, agentContext);
|
|
18516
|
+
}
|
|
18517
|
+
if (toolPart) {
|
|
18518
|
+
await streamCallback.onMessage({
|
|
18519
|
+
taskId: context.taskId,
|
|
18520
|
+
agentName: agentNode.name,
|
|
18521
|
+
nodeId: agentNode.id,
|
|
18522
|
+
type: "tool_use",
|
|
18523
|
+
toolId: toolPart.toolCallId,
|
|
18524
|
+
toolName: toolPart.toolName,
|
|
18525
|
+
params: toolPart.args || {},
|
|
18526
|
+
}, agentContext);
|
|
18527
|
+
toolPart = null;
|
|
18528
|
+
}
|
|
18529
|
+
await streamCallback.onMessage({
|
|
18530
|
+
taskId: context.taskId,
|
|
18531
|
+
agentName: agentNode.name,
|
|
18532
|
+
nodeId: agentNode.id,
|
|
18533
|
+
type: "finish",
|
|
18534
|
+
finishReason: chunk.finishReason,
|
|
18535
|
+
usage: chunk.usage,
|
|
18536
|
+
}, agentContext);
|
|
18537
|
+
if (chunk.finishReason === "length" &&
|
|
18538
|
+
messages.length >= 10 &&
|
|
18539
|
+
!noCompress &&
|
|
18540
|
+
!retry) {
|
|
18541
|
+
await compressAgentMessages(agentContext, rlm, messages, tools);
|
|
18542
|
+
return callLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, true, streamCallback);
|
|
18543
|
+
}
|
|
18544
|
+
break;
|
|
18545
|
+
}
|
|
18546
|
+
}
|
|
18547
|
+
}
|
|
18548
|
+
}
|
|
18549
|
+
finally {
|
|
18550
|
+
reader.releaseLock();
|
|
18723
18551
|
}
|
|
18552
|
+
agentChain.agentResult = streamText;
|
|
18553
|
+
return streamText
|
|
18554
|
+
? [
|
|
18555
|
+
{ type: "text", text: streamText },
|
|
18556
|
+
...toolParts,
|
|
18557
|
+
]
|
|
18558
|
+
: toolParts;
|
|
18724
18559
|
}
|
|
18725
18560
|
|
|
18726
18561
|
const AGENT_NAME$5 = "Chat";
|
|
@@ -18755,9 +18590,7 @@ Your task is to understand the user's requirements, dynamically plan the user's
|
|
|
18755
18590
|
|
|
18756
18591
|
## Output Rules and Format
|
|
18757
18592
|
<root>
|
|
18758
|
-
<!-- Task Name (Short) -->
|
|
18759
18593
|
<name>Task Name</name>
|
|
18760
|
-
<!-- Need to break down the task into multi-agent collaboration. Please think step by step and output a detailed thought process. -->
|
|
18761
18594
|
<thought>Your thought process on user demand planning</thought>
|
|
18762
18595
|
<!-- Multiple Agents work together to complete the task -->
|
|
18763
18596
|
<agents>
|
|
@@ -18955,39 +18788,21 @@ function getPlanUserPrompt(task_prompt, task_website, ext_prompt) {
|
|
|
18955
18788
|
class Planner {
|
|
18956
18789
|
constructor(context, taskId) {
|
|
18957
18790
|
this.context = context;
|
|
18958
|
-
this.taskId = taskId
|
|
18959
|
-
}
|
|
18960
|
-
async plan(taskPrompt, saveHistory = true) {
|
|
18961
|
-
let taskPromptStr;
|
|
18962
|
-
let userPrompt;
|
|
18963
|
-
if (typeof taskPrompt === "string") {
|
|
18964
|
-
taskPromptStr = taskPrompt;
|
|
18965
|
-
userPrompt = {
|
|
18966
|
-
type: "text",
|
|
18967
|
-
text: getPlanUserPrompt(taskPrompt, this.context.variables.get("task_website"), this.context.variables.get("plan_ext_prompt")),
|
|
18968
|
-
};
|
|
18969
|
-
}
|
|
18970
|
-
else {
|
|
18971
|
-
userPrompt = taskPrompt;
|
|
18972
|
-
taskPromptStr = taskPrompt.text || "";
|
|
18973
|
-
}
|
|
18974
|
-
const messages = [
|
|
18975
|
-
{
|
|
18976
|
-
role: "system",
|
|
18977
|
-
content: this.context.variables.get("plan_sys_prompt") ||
|
|
18978
|
-
(await getPlanSystemPrompt(this.context)),
|
|
18979
|
-
},
|
|
18980
|
-
{
|
|
18981
|
-
role: "user",
|
|
18982
|
-
content: [userPrompt],
|
|
18983
|
-
},
|
|
18984
|
-
];
|
|
18985
|
-
return await this.doPlan(taskPromptStr, messages, saveHistory);
|
|
18791
|
+
this.taskId = taskId;
|
|
18986
18792
|
}
|
|
18987
|
-
async
|
|
18988
|
-
|
|
18989
|
-
|
|
18990
|
-
|
|
18793
|
+
async plan(taskPrompt) {
|
|
18794
|
+
return await this.doPlan(taskPrompt, false);
|
|
18795
|
+
}
|
|
18796
|
+
async replan(taskPrompt) {
|
|
18797
|
+
return await this.doPlan(taskPrompt, true);
|
|
18798
|
+
}
|
|
18799
|
+
async doPlan(taskPrompt, replan = false) {
|
|
18800
|
+
let config = this.context.config;
|
|
18801
|
+
let chain = this.context.chain;
|
|
18802
|
+
let rlm = new RetryLanguageModel(config.llms, config.planLlms);
|
|
18803
|
+
let messages;
|
|
18804
|
+
if (replan && chain.planRequest && chain.planResult) {
|
|
18805
|
+
messages = [
|
|
18991
18806
|
...chain.planRequest.messages,
|
|
18992
18807
|
{
|
|
18993
18808
|
role: "assistant",
|
|
@@ -18998,25 +18813,34 @@ class Planner {
|
|
|
18998
18813
|
content: [{ type: "text", text: taskPrompt }],
|
|
18999
18814
|
},
|
|
19000
18815
|
];
|
|
19001
|
-
return await this.doPlan(taskPrompt, messages, saveHistory);
|
|
19002
18816
|
}
|
|
19003
18817
|
else {
|
|
19004
|
-
|
|
18818
|
+
messages = [
|
|
18819
|
+
{
|
|
18820
|
+
role: "system",
|
|
18821
|
+
content: this.context.variables.get("plan_sys_prompt") ||
|
|
18822
|
+
(await getPlanSystemPrompt(this.context)),
|
|
18823
|
+
},
|
|
18824
|
+
{
|
|
18825
|
+
role: "user",
|
|
18826
|
+
content: [
|
|
18827
|
+
{
|
|
18828
|
+
type: "text",
|
|
18829
|
+
text: getPlanUserPrompt(taskPrompt, this.context.variables.get("task_website"), this.context.variables.get("plan_ext_prompt")),
|
|
18830
|
+
},
|
|
18831
|
+
],
|
|
18832
|
+
},
|
|
18833
|
+
];
|
|
19005
18834
|
}
|
|
19006
|
-
|
|
19007
|
-
async doPlan(taskPrompt, messages, saveHistory) {
|
|
19008
|
-
const config = this.context.config;
|
|
19009
|
-
const rlm = new RetryLanguageModel(config.llms, config.planLlms);
|
|
19010
|
-
const request = {
|
|
18835
|
+
let request = {
|
|
19011
18836
|
maxTokens: 4096,
|
|
19012
18837
|
temperature: 0.7,
|
|
19013
18838
|
messages: messages,
|
|
19014
18839
|
abortSignal: this.context.controller.signal,
|
|
19015
18840
|
};
|
|
19016
|
-
|
|
18841
|
+
let result = await rlm.callStream(request);
|
|
19017
18842
|
const reader = result.stream.getReader();
|
|
19018
18843
|
let streamText = "";
|
|
19019
|
-
let thinkingText = "";
|
|
19020
18844
|
try {
|
|
19021
18845
|
while (true) {
|
|
19022
18846
|
await this.context.checkAborted();
|
|
@@ -19029,14 +18853,11 @@ class Planner {
|
|
|
19029
18853
|
Log.error("Plan, LLM Error: ", chunk);
|
|
19030
18854
|
throw new Error("LLM Error: " + chunk.error);
|
|
19031
18855
|
}
|
|
19032
|
-
if (chunk.type == "reasoning") {
|
|
19033
|
-
thinkingText += chunk.textDelta || "";
|
|
19034
|
-
}
|
|
19035
18856
|
if (chunk.type == "text-delta") {
|
|
19036
18857
|
streamText += chunk.textDelta || "";
|
|
19037
18858
|
}
|
|
19038
18859
|
if (config.callback) {
|
|
19039
|
-
let workflow = parseWorkflow(this.taskId, streamText, false
|
|
18860
|
+
let workflow = parseWorkflow(this.taskId, streamText, false);
|
|
19040
18861
|
if (workflow) {
|
|
19041
18862
|
await config.callback.onMessage({
|
|
19042
18863
|
taskId: this.taskId,
|
|
@@ -19051,16 +18872,11 @@ class Planner {
|
|
|
19051
18872
|
}
|
|
19052
18873
|
finally {
|
|
19053
18874
|
reader.releaseLock();
|
|
19054
|
-
|
|
19055
|
-
Log.info("Planner result: \n" + streamText);
|
|
19056
|
-
}
|
|
18875
|
+
Log.info("Planner result: \n" + streamText);
|
|
19057
18876
|
}
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
chain.planResult = streamText;
|
|
19062
|
-
}
|
|
19063
|
-
let workflow = parseWorkflow(this.taskId, streamText, true, thinkingText);
|
|
18877
|
+
chain.planRequest = request;
|
|
18878
|
+
chain.planResult = streamText;
|
|
18879
|
+
let workflow = parseWorkflow(this.taskId, streamText, true);
|
|
19064
18880
|
if (config.callback) {
|
|
19065
18881
|
await config.callback.onMessage({
|
|
19066
18882
|
taskId: this.taskId,
|
|
@@ -19070,12 +18886,7 @@ class Planner {
|
|
|
19070
18886
|
workflow: workflow,
|
|
19071
18887
|
});
|
|
19072
18888
|
}
|
|
19073
|
-
|
|
19074
|
-
workflow.taskPrompt += "\n" + taskPrompt.trim();
|
|
19075
|
-
}
|
|
19076
|
-
else {
|
|
19077
|
-
workflow.taskPrompt = taskPrompt.trim();
|
|
19078
|
-
}
|
|
18889
|
+
workflow.taskPrompt = taskPrompt;
|
|
19079
18890
|
return workflow;
|
|
19080
18891
|
}
|
|
19081
18892
|
}
|
|
@@ -19125,8 +18936,8 @@ class Eko {
|
|
|
19125
18936
|
if (!context) {
|
|
19126
18937
|
throw new Error("The task does not exist");
|
|
19127
18938
|
}
|
|
19128
|
-
if (context.
|
|
19129
|
-
context.
|
|
18939
|
+
if (context.paused) {
|
|
18940
|
+
context.paused = false;
|
|
19130
18941
|
}
|
|
19131
18942
|
context.conversation = [];
|
|
19132
18943
|
if (context.controller.signal.aborted) {
|
|
@@ -19214,7 +19025,7 @@ class Eko {
|
|
|
19214
19025
|
abortTask(taskId, reason) {
|
|
19215
19026
|
let context = this.taskMap.get(taskId);
|
|
19216
19027
|
if (context) {
|
|
19217
|
-
context.
|
|
19028
|
+
context.paused = false;
|
|
19218
19029
|
this.onTaskStatus(context, "abort", reason);
|
|
19219
19030
|
context.controller.abort(reason);
|
|
19220
19031
|
return true;
|
|
@@ -19223,11 +19034,11 @@ class Eko {
|
|
|
19223
19034
|
return false;
|
|
19224
19035
|
}
|
|
19225
19036
|
}
|
|
19226
|
-
pauseTask(taskId,
|
|
19037
|
+
pauseTask(taskId, paused, reason) {
|
|
19227
19038
|
let context = this.taskMap.get(taskId);
|
|
19228
19039
|
if (context) {
|
|
19229
|
-
this.onTaskStatus(context,
|
|
19230
|
-
context.
|
|
19040
|
+
this.onTaskStatus(context, paused ? "pause" : "resume-pause", reason);
|
|
19041
|
+
context.paused = paused;
|
|
19231
19042
|
return true;
|
|
19232
19043
|
}
|
|
19233
19044
|
else {
|
|
@@ -21977,21 +21788,17 @@ exports.Eko = Eko;
|
|
|
21977
21788
|
exports.ForeachTaskTool = ForeachTaskTool;
|
|
21978
21789
|
exports.HumanInteractTool = HumanInteractTool;
|
|
21979
21790
|
exports.Log = Log;
|
|
21980
|
-
exports.Planner = Planner;
|
|
21981
21791
|
exports.RetryLanguageModel = RetryLanguageModel;
|
|
21982
21792
|
exports.SimpleSseMcpClient = SimpleSseMcpClient;
|
|
21983
21793
|
exports.TaskNodeStatusTool = TaskNodeStatusTool;
|
|
21984
21794
|
exports.VariableStorageTool = VariableStorageTool;
|
|
21985
21795
|
exports.WatchTriggerTool = WatchTriggerTool;
|
|
21986
|
-
exports.buildSimpleAgentWorkflow = buildSimpleAgentWorkflow;
|
|
21987
21796
|
exports.call_timeout = call_timeout;
|
|
21988
21797
|
exports.config = config;
|
|
21989
21798
|
exports.convertToolSchema = convertToolSchema;
|
|
21990
21799
|
exports.default = Eko;
|
|
21991
21800
|
exports.extract_page_content = extract_page_content;
|
|
21992
21801
|
exports.mergeTools = mergeTools;
|
|
21993
|
-
exports.parseWorkflow = parseWorkflow;
|
|
21994
|
-
exports.resetWorkflowXml = resetWorkflowXml;
|
|
21995
21802
|
exports.toImage = toImage;
|
|
21996
21803
|
exports.uuidv4 = uuidv4;
|
|
21997
21804
|
//# sourceMappingURL=index.cjs.js.map
|