@eko-ai/eko 4.0.3 → 4.0.5

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.
Files changed (38) hide show
  1. package/dist/agent/agent-llm.d.ts +3 -3
  2. package/dist/agent/agent-llm.d.ts.map +1 -1
  3. package/dist/agent/base.d.ts.map +1 -1
  4. package/dist/agent/browser/browser-base.d.ts.map +1 -1
  5. package/dist/agent/browser/utils.d.ts +9 -1
  6. package/dist/agent/browser/utils.d.ts.map +1 -1
  7. package/dist/agent/index.d.ts +2 -2
  8. package/dist/agent/index.d.ts.map +1 -1
  9. package/dist/chat/chat-agent.d.ts.map +1 -1
  10. package/dist/chat/chat-llm.d.ts +1 -2
  11. package/dist/chat/chat-llm.d.ts.map +1 -1
  12. package/dist/chat/tools/deep-action.d.ts.map +1 -1
  13. package/dist/common/utils.d.ts +1 -1
  14. package/dist/common/utils.d.ts.map +1 -1
  15. package/dist/index.cjs.js +685 -644
  16. package/dist/index.cjs.js.map +1 -1
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.esm.js +684 -645
  20. package/dist/index.esm.js.map +1 -1
  21. package/dist/llm/index.d.ts +2 -21
  22. package/dist/llm/index.d.ts.map +1 -1
  23. package/dist/llm/react.d.ts +5 -0
  24. package/dist/llm/react.d.ts.map +1 -0
  25. package/dist/llm/rlm.d.ts +22 -0
  26. package/dist/llm/rlm.d.ts.map +1 -0
  27. package/dist/memory/memory.d.ts.map +1 -1
  28. package/dist/types/agent.types.d.ts +2 -47
  29. package/dist/types/agent.types.d.ts.map +1 -1
  30. package/dist/types/chat.types.d.ts +3 -45
  31. package/dist/types/chat.types.d.ts.map +1 -1
  32. package/dist/types/config.types.d.ts +10 -10
  33. package/dist/types/config.types.d.ts.map +1 -1
  34. package/dist/types/index.d.ts +2 -2
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/types/llm.types.d.ts +51 -1
  37. package/dist/types/llm.types.d.ts.map +1 -1
  38. package/package.json +1 -1
package/dist/index.cjs.js CHANGED
@@ -399,9 +399,10 @@ async function compressImageData(imageBase64, imageType, compress, quality) {
399
399
  ctx: canvas.getContext("2d"),
400
400
  exportBase64: async (mime, q) => {
401
401
  const buffer = canvas.toBuffer(mime, { quality: q });
402
- return ((
402
+ const _Buffer =
403
403
  // @ts-ignore
404
- typeof Buffer !== "undefined" ? Buffer.from(buffer) : buffer).toString("base64"));
404
+ typeof Buffer !== "undefined" ? Buffer.from(buffer) : buffer;
405
+ return _Buffer.toString("base64");
405
406
  },
406
407
  };
407
408
  }
@@ -481,13 +482,19 @@ function mergeAgents(agents1, agents2) {
481
482
  }
482
483
  return agents;
483
484
  }
484
- function sub(str, maxLength, appendPoint = true) {
485
+ function sub(str, maxLength, appendPoint = true, showTruncated = true) {
485
486
  if (!str) {
486
487
  return "";
487
488
  }
488
489
  if (str.length > maxLength) {
489
- // return str.substring(0, maxLength) + (appendPoint ? "..." : "");
490
- return (Array.from(str).slice(0, maxLength).join("") + (appendPoint ? "..." : ""));
490
+ const truncatedLength = str.length - maxLength;
491
+ // return str.substring(0, maxLength) + (appendPoint ? showTruncated ? `...(truncated: +${truncatedLength} chars)` : "..." : "");
492
+ return (Array.from(str).slice(0, maxLength).join("") +
493
+ (appendPoint
494
+ ? showTruncated
495
+ ? `...(truncated: +${truncatedLength} chars)`
496
+ : "..."
497
+ : ""));
491
498
  }
492
499
  return str;
493
500
  }
@@ -30056,7 +30063,7 @@ function defaultLLMProviderOptions() {
30056
30063
  },
30057
30064
  openrouter: {
30058
30065
  reasoning: {
30059
- max_tokens: 10,
30066
+ effort: "low",
30060
30067
  },
30061
30068
  },
30062
30069
  };
@@ -30075,12 +30082,12 @@ function defaultMessageProviderOptions() {
30075
30082
  };
30076
30083
  }
30077
30084
  function convertTools(tools) {
30078
- return tools.map((tool) => ({
30085
+ return tools.map((tool, index) => ({
30079
30086
  type: "function",
30080
30087
  name: tool.name,
30081
30088
  description: tool.description,
30082
30089
  inputSchema: tool.parameters,
30083
- // providerOptions: defaultMessageProviderOptions()
30090
+ providerOptions: index < 3 ? defaultMessageProviderOptions() : undefined,
30084
30091
  }));
30085
30092
  }
30086
30093
  function getTool(tools, name) {
@@ -30196,7 +30203,7 @@ function convertToolResult(toolUse, toolResult, user_messages) {
30196
30203
  output: result,
30197
30204
  };
30198
30205
  }
30199
- async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, retryNum = 0, callback, requestHandler) {
30206
+ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, callback, requestHandler) {
30200
30207
  await agentContext.context.checkAborted();
30201
30208
  if (!noCompress &&
30202
30209
  (messages.length >= config$1.compressThreshold ||
@@ -30229,300 +30236,47 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
30229
30236
  abortSignal: signal,
30230
30237
  };
30231
30238
  requestHandler && requestHandler(request);
30232
- let streamText = "";
30233
- let thinkText = "";
30234
- let toolArgsText = "";
30235
- let textStreamId = uuidv4();
30236
- let thinkStreamId = uuidv4();
30237
- let textStreamDone = false;
30238
- const toolParts = [];
30239
- let reader = null;
30240
30239
  try {
30241
30240
  agentChain.agentRequest = request;
30242
30241
  context.currentStepControllers.add(stepController);
30243
- const result = await rlm.callStream(request);
30244
- reader = result.stream.getReader();
30245
- let toolPart = null;
30246
- while (true) {
30242
+ const result = await callLLM(rlm, request, async (message) => {
30247
30243
  await context.checkAborted();
30248
- const { done, value } = await reader.read();
30249
- if (done) {
30250
- break;
30244
+ await streamCallback.onMessage({
30245
+ streamType: "agent",
30246
+ chatId: context.chatId,
30247
+ taskId: context.taskId,
30248
+ agentName: agentNode.name,
30249
+ nodeId: agentNode.id,
30250
+ ...message,
30251
+ });
30252
+ }, async (request, error) => {
30253
+ if ((error + "").indexOf("is too long") > -1) {
30254
+ await compressAgentMessages(agentContext, messages, tools);
30251
30255
  }
30252
- const chunk = value;
30253
- switch (chunk.type) {
30254
- case "text-start": {
30255
- textStreamId = uuidv4();
30256
- break;
30257
- }
30258
- case "text-delta": {
30259
- if (toolPart && !chunk.delta) {
30260
- continue;
30261
- }
30262
- streamText += chunk.delta || "";
30263
- await streamCallback.onMessage({
30264
- streamType: "agent",
30265
- chatId: context.chatId,
30266
- taskId: context.taskId,
30267
- agentName: agentNode.name,
30268
- nodeId: agentNode.id,
30269
- type: "text",
30270
- streamId: textStreamId,
30271
- streamDone: false,
30272
- text: streamText,
30273
- }, agentContext);
30274
- if (toolPart) {
30275
- await streamCallback.onMessage({
30276
- streamType: "agent",
30277
- chatId: context.chatId,
30278
- taskId: context.taskId,
30279
- agentName: agentNode.name,
30280
- nodeId: agentNode.id,
30281
- type: "tool_use",
30282
- toolCallId: toolPart.toolCallId,
30283
- toolName: toolPart.toolName,
30284
- params: toolPart.input || {},
30285
- }, agentContext);
30286
- toolPart = null;
30287
- }
30288
- break;
30289
- }
30290
- case "text-end": {
30291
- textStreamDone = true;
30292
- if (streamText) {
30293
- await streamCallback.onMessage({
30294
- streamType: "agent",
30295
- chatId: context.chatId,
30296
- taskId: context.taskId,
30297
- agentName: agentNode.name,
30298
- nodeId: agentNode.id,
30299
- type: "text",
30300
- streamId: textStreamId,
30301
- streamDone: true,
30302
- text: streamText,
30303
- }, agentContext);
30304
- }
30305
- break;
30306
- }
30307
- case "reasoning-start": {
30308
- thinkStreamId = uuidv4();
30309
- break;
30310
- }
30311
- case "reasoning-delta": {
30312
- thinkText += chunk.delta || "";
30313
- await streamCallback.onMessage({
30314
- streamType: "agent",
30315
- chatId: context.chatId,
30316
- taskId: context.taskId,
30317
- agentName: agentNode.name,
30318
- nodeId: agentNode.id,
30319
- type: "thinking",
30320
- streamId: thinkStreamId,
30321
- streamDone: false,
30322
- text: thinkText,
30323
- }, agentContext);
30324
- break;
30325
- }
30326
- case "reasoning-end": {
30327
- if (thinkText) {
30328
- await streamCallback.onMessage({
30329
- streamType: "agent",
30330
- chatId: context.chatId,
30331
- taskId: context.taskId,
30332
- agentName: agentNode.name,
30333
- nodeId: agentNode.id,
30334
- type: "thinking",
30335
- streamId: thinkStreamId,
30336
- streamDone: true,
30337
- text: thinkText,
30338
- }, agentContext);
30339
- }
30340
- break;
30341
- }
30342
- case "tool-input-start": {
30343
- if (toolPart && toolPart.toolCallId == chunk.id) {
30344
- toolPart.toolName = chunk.toolName;
30345
- }
30346
- else {
30347
- toolPart = {
30348
- type: "tool-call",
30349
- toolCallId: chunk.id,
30350
- toolName: chunk.toolName,
30351
- input: {},
30352
- };
30353
- toolParts.push(toolPart);
30354
- }
30355
- break;
30356
- }
30357
- case "tool-input-delta": {
30358
- if (!textStreamDone) {
30359
- textStreamDone = true;
30360
- await streamCallback.onMessage({
30361
- streamType: "agent",
30362
- chatId: context.chatId,
30363
- taskId: context.taskId,
30364
- agentName: agentNode.name,
30365
- nodeId: agentNode.id,
30366
- type: "text",
30367
- streamId: textStreamId,
30368
- streamDone: true,
30369
- text: streamText,
30370
- }, agentContext);
30371
- }
30372
- toolArgsText += chunk.delta || "";
30373
- await streamCallback.onMessage({
30374
- streamType: "agent",
30375
- chatId: context.chatId,
30376
- taskId: context.taskId,
30377
- agentName: agentNode.name,
30378
- nodeId: agentNode.id,
30379
- type: "tool_streaming",
30380
- toolCallId: chunk.id,
30381
- toolName: toolPart?.toolName || "",
30382
- paramsText: toolArgsText,
30383
- }, agentContext);
30384
- break;
30385
- }
30386
- case "tool-call": {
30387
- toolArgsText = "";
30388
- const args = chunk.input ? JSON.parse(chunk.input) : {};
30389
- const message = {
30390
- streamType: "agent",
30391
- chatId: context.chatId,
30392
- taskId: context.taskId,
30393
- agentName: agentNode.name,
30394
- nodeId: agentNode.id,
30395
- type: "tool_use",
30396
- toolCallId: chunk.toolCallId,
30397
- toolName: chunk.toolName,
30398
- params: args,
30399
- };
30400
- await streamCallback.onMessage(message, agentContext);
30401
- if (toolPart == null) {
30402
- toolParts.push({
30403
- type: "tool-call",
30404
- toolCallId: chunk.toolCallId,
30405
- toolName: chunk.toolName,
30406
- input: message.params || args,
30407
- });
30408
- }
30409
- else {
30410
- toolPart.input = message.params || args;
30411
- toolPart = null;
30412
- }
30413
- break;
30414
- }
30415
- case "file": {
30416
- await streamCallback.onMessage({
30417
- streamType: "agent",
30418
- chatId: context.chatId,
30419
- taskId: context.taskId,
30420
- agentName: agentNode.name,
30421
- nodeId: agentNode.id,
30422
- type: "file",
30423
- mimeType: chunk.mediaType,
30424
- data: chunk.data,
30425
- }, agentContext);
30426
- break;
30427
- }
30428
- case "error": {
30429
- Log.error(`${agentNode.name} agent error: `, chunk);
30430
- await streamCallback.onMessage({
30431
- streamType: "agent",
30432
- chatId: context.chatId,
30433
- taskId: context.taskId,
30434
- agentName: agentNode.name,
30435
- nodeId: agentNode.id,
30436
- type: "error",
30437
- error: chunk.error,
30438
- }, agentContext);
30439
- throw new Error("LLM Error: " + chunk.error);
30440
- }
30441
- case "finish": {
30442
- if (!textStreamDone) {
30443
- textStreamDone = true;
30444
- await streamCallback.onMessage({
30445
- streamType: "agent",
30446
- chatId: context.chatId,
30447
- taskId: context.taskId,
30448
- agentName: agentNode.name,
30449
- nodeId: agentNode.id,
30450
- type: "text",
30451
- streamId: textStreamId,
30452
- streamDone: true,
30453
- text: streamText,
30454
- }, agentContext);
30455
- }
30456
- if (chunk.finishReason === "content-filter") {
30457
- throw new Error("LLM error: trigger content filtering violation");
30458
- }
30459
- else if (chunk.finishReason === "other") {
30460
- throw new Error("LLM error: terminated due to other reasons");
30461
- }
30462
- else if (chunk.finishReason === "length" &&
30463
- messages.length >= 3 &&
30464
- !noCompress &&
30465
- retryNum < config$1.maxRetryNum) {
30466
- await compressAgentMessages(agentContext, messages, tools);
30467
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
30468
- }
30469
- if (toolPart) {
30470
- await streamCallback.onMessage({
30471
- streamType: "agent",
30472
- chatId: context.chatId,
30473
- taskId: context.taskId,
30474
- agentName: agentNode.name,
30475
- nodeId: agentNode.id,
30476
- type: "tool_use",
30477
- toolCallId: toolPart.toolCallId,
30478
- toolName: toolPart.toolName,
30479
- params: toolPart.input || {},
30480
- }, agentContext);
30481
- toolPart = null;
30482
- }
30483
- await streamCallback.onMessage({
30484
- streamType: "agent",
30485
- chatId: context.chatId,
30486
- taskId: context.taskId,
30487
- agentName: agentNode.name,
30488
- nodeId: agentNode.id,
30489
- type: "finish",
30490
- finishReason: chunk.finishReason,
30491
- usage: {
30492
- promptTokens: chunk.usage.inputTokens || 0,
30493
- completionTokens: chunk.usage.outputTokens || 0,
30494
- totalTokens: chunk.usage.totalTokens ||
30495
- (chunk.usage.inputTokens || 0) +
30496
- (chunk.usage.outputTokens || 0),
30497
- },
30498
- }, agentContext);
30499
- break;
30500
- }
30256
+ }, async (request, finishReason, value, retryNum) => {
30257
+ if (finishReason === "content-filter") {
30258
+ throw new Error("LLM error: trigger content filtering violation");
30501
30259
  }
30502
- }
30503
- }
30504
- catch (e) {
30505
- await context.checkAborted();
30506
- if (retryNum < config$1.maxRetryNum) {
30507
- await sleep(300 * (retryNum + 1) * (retryNum + 1));
30508
- if ((e + "").indexOf("is too long") > -1) {
30260
+ else if (finishReason === "other") {
30261
+ throw new Error("LLM error: terminated due to other reasons");
30262
+ }
30263
+ else if (finishReason === "length" &&
30264
+ messages.length >= 3 &&
30265
+ !noCompress &&
30266
+ retryNum < config$1.maxRetryNum) {
30509
30267
  await compressAgentMessages(agentContext, messages, tools);
30268
+ return "retry";
30510
30269
  }
30511
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
30512
- }
30513
- throw e;
30270
+ });
30271
+ agentChain.agentResult = result
30272
+ .filter((s) => s.type == "text")
30273
+ .map((s) => s.text)
30274
+ .join("\n\n");
30275
+ return result;
30514
30276
  }
30515
30277
  finally {
30516
- reader && reader.releaseLock();
30517
30278
  context.currentStepControllers.delete(stepController);
30518
30279
  }
30519
- agentChain.agentResult = streamText;
30520
- return streamText
30521
- ? [
30522
- { type: "text", text: streamText },
30523
- ...toolParts,
30524
- ]
30525
- : toolParts;
30526
30280
  }
30527
30281
  function estimatePromptTokens(messages, tools) {
30528
30282
  let tokens = messages.reduce((total, message) => {
@@ -31023,22 +30777,309 @@ class RetryLanguageModel {
31023
30777
  }
31024
30778
  }
31025
30779
 
30780
+ async function callWithReAct(rlm, request, toolCallCallback, streamCallback, errorHandler, finishHandler, loopControl) {
30781
+ if (!loopControl) {
30782
+ loopControl = async (request, assistantParts, loopNum) => {
30783
+ if (loopNum >= 15) {
30784
+ return false;
30785
+ }
30786
+ return assistantParts.filter((s) => s.type == "tool-call").length > 0;
30787
+ };
30788
+ }
30789
+ let loopNum = 0;
30790
+ let assistantParts = null;
30791
+ while (true) {
30792
+ assistantParts = await callLLM(rlm, request, streamCallback, errorHandler, finishHandler);
30793
+ if (assistantParts.length > 0) {
30794
+ request.messages.push({
30795
+ role: "assistant",
30796
+ content: assistantParts
30797
+ .filter((part) => part.type == "text" || part.type == "tool-call")
30798
+ .map((part) => part.type === "text"
30799
+ ? {
30800
+ type: "text",
30801
+ text: part.text,
30802
+ }
30803
+ : {
30804
+ type: "tool-call",
30805
+ toolCallId: part.toolCallId,
30806
+ toolName: part.toolName,
30807
+ input: JSON.parse((part.input || "{}")),
30808
+ }),
30809
+ });
30810
+ }
30811
+ const continueLoop = await loopControl(request, assistantParts, loopNum);
30812
+ if (!continueLoop) {
30813
+ break;
30814
+ }
30815
+ const toolUses = assistantParts.filter((s) => s.type == "tool-call");
30816
+ const toolResults = await toolCallCallback(request, toolUses);
30817
+ if (toolResults.length > 0) {
30818
+ request.messages.push({
30819
+ role: "tool",
30820
+ content: toolResults.map((result, index) => ({
30821
+ type: "tool-result",
30822
+ toolCallId: toolUses[index].toolCallId,
30823
+ toolName: toolUses[index].toolName,
30824
+ output: result,
30825
+ })),
30826
+ });
30827
+ }
30828
+ loopNum++;
30829
+ }
30830
+ return assistantParts;
30831
+ }
30832
+ async function callLLM(rlm, request, streamCallback, errorHandler, finishHandler, retryNum = 0) {
30833
+ let streamText = "";
30834
+ let thinkText = "";
30835
+ let toolArgsText = "";
30836
+ let textStreamId = uuidv4();
30837
+ let thinkStreamId = uuidv4();
30838
+ let textStreamDone = false;
30839
+ const toolParts = [];
30840
+ let reader = null;
30841
+ try {
30842
+ const result = await rlm.callStream(request);
30843
+ reader = result.stream.getReader();
30844
+ let toolPart = null;
30845
+ while (true) {
30846
+ const { done, value } = await reader.read();
30847
+ if (done) {
30848
+ break;
30849
+ }
30850
+ const chunk = value;
30851
+ switch (chunk.type) {
30852
+ case "text-start": {
30853
+ textStreamId = uuidv4();
30854
+ break;
30855
+ }
30856
+ case "text-delta": {
30857
+ if (toolPart && !chunk.delta) {
30858
+ continue;
30859
+ }
30860
+ streamText += chunk.delta || "";
30861
+ await streamCallback?.({
30862
+ type: "text",
30863
+ streamId: textStreamId,
30864
+ streamDone: false,
30865
+ text: streamText,
30866
+ });
30867
+ if (toolPart) {
30868
+ await streamCallback?.({
30869
+ type: "tool_use",
30870
+ toolCallId: toolPart.toolCallId,
30871
+ toolName: toolPart.toolName,
30872
+ params: toolPart.input || {},
30873
+ });
30874
+ toolPart = null;
30875
+ }
30876
+ break;
30877
+ }
30878
+ case "text-end": {
30879
+ textStreamDone = true;
30880
+ if (streamText) {
30881
+ await streamCallback?.({
30882
+ type: "text",
30883
+ streamId: textStreamId,
30884
+ streamDone: true,
30885
+ text: streamText,
30886
+ });
30887
+ }
30888
+ break;
30889
+ }
30890
+ case "reasoning-start": {
30891
+ thinkStreamId = uuidv4();
30892
+ break;
30893
+ }
30894
+ case "reasoning-delta": {
30895
+ thinkText += chunk.delta || "";
30896
+ await streamCallback?.({
30897
+ type: "thinking",
30898
+ streamId: thinkStreamId,
30899
+ streamDone: false,
30900
+ text: thinkText,
30901
+ });
30902
+ break;
30903
+ }
30904
+ case "reasoning-end": {
30905
+ if (thinkText) {
30906
+ await streamCallback?.({
30907
+ type: "thinking",
30908
+ streamId: thinkStreamId,
30909
+ streamDone: true,
30910
+ text: thinkText,
30911
+ });
30912
+ }
30913
+ break;
30914
+ }
30915
+ case "tool-input-start": {
30916
+ if (toolPart && toolPart.toolCallId == chunk.id) {
30917
+ toolPart.toolName = chunk.toolName;
30918
+ }
30919
+ else {
30920
+ const _toolPart = toolParts.filter((s) => s.toolCallId == chunk.id)[0];
30921
+ if (_toolPart) {
30922
+ toolPart = _toolPart;
30923
+ toolPart.toolName = _toolPart.toolName || chunk.toolName;
30924
+ toolPart.input = _toolPart.input || {};
30925
+ }
30926
+ else {
30927
+ toolPart = {
30928
+ type: "tool-call",
30929
+ toolCallId: chunk.id,
30930
+ toolName: chunk.toolName,
30931
+ input: {},
30932
+ };
30933
+ toolParts.push(toolPart);
30934
+ }
30935
+ }
30936
+ break;
30937
+ }
30938
+ case "tool-input-delta": {
30939
+ if (!textStreamDone) {
30940
+ textStreamDone = true;
30941
+ await streamCallback?.({
30942
+ type: "text",
30943
+ streamId: textStreamId,
30944
+ streamDone: true,
30945
+ text: streamText,
30946
+ });
30947
+ }
30948
+ toolArgsText += chunk.delta || "";
30949
+ await streamCallback?.({
30950
+ type: "tool_streaming",
30951
+ toolCallId: chunk.id,
30952
+ toolName: toolPart?.toolName || "",
30953
+ paramsText: toolArgsText,
30954
+ });
30955
+ break;
30956
+ }
30957
+ case "tool-call": {
30958
+ toolArgsText = "";
30959
+ const args = chunk.input ? JSON.parse(chunk.input) : {};
30960
+ const message = {
30961
+ type: "tool_use",
30962
+ toolCallId: chunk.toolCallId,
30963
+ toolName: chunk.toolName,
30964
+ params: args,
30965
+ };
30966
+ await streamCallback?.(message);
30967
+ if (toolPart == null) {
30968
+ const _toolPart = toolParts.filter((s) => s.toolCallId == chunk.toolCallId)[0];
30969
+ if (_toolPart) {
30970
+ _toolPart.input = message.params || args;
30971
+ }
30972
+ else {
30973
+ toolParts.push({
30974
+ type: "tool-call",
30975
+ toolCallId: chunk.toolCallId,
30976
+ toolName: chunk.toolName,
30977
+ input: message.params || args,
30978
+ });
30979
+ }
30980
+ }
30981
+ else {
30982
+ toolPart.input = message.params || args;
30983
+ toolPart = null;
30984
+ }
30985
+ break;
30986
+ }
30987
+ case "file": {
30988
+ await streamCallback?.({
30989
+ type: "file",
30990
+ mimeType: chunk.mediaType,
30991
+ data: chunk.data,
30992
+ });
30993
+ break;
30994
+ }
30995
+ case "error": {
30996
+ Log.error(`chatLLM error: `, chunk);
30997
+ await streamCallback?.({
30998
+ type: "error",
30999
+ error: chunk.error,
31000
+ });
31001
+ throw new Error("LLM Error: " + chunk.error);
31002
+ }
31003
+ case "finish": {
31004
+ if (!textStreamDone) {
31005
+ textStreamDone = true;
31006
+ await streamCallback?.({
31007
+ type: "text",
31008
+ streamId: textStreamId,
31009
+ streamDone: true,
31010
+ text: streamText,
31011
+ });
31012
+ }
31013
+ if (toolPart) {
31014
+ await streamCallback?.({
31015
+ type: "tool_use",
31016
+ toolCallId: toolPart.toolCallId,
31017
+ toolName: toolPart.toolName,
31018
+ params: toolPart.input || {},
31019
+ });
31020
+ toolPart = null;
31021
+ }
31022
+ if (finishHandler) {
31023
+ const type = await finishHandler(request, chunk.finishReason, chunk, retryNum);
31024
+ if (type == "retry") {
31025
+ await sleep(200 * (retryNum + 1) * (retryNum + 1));
31026
+ return callLLM(rlm, request, streamCallback, errorHandler, finishHandler, ++retryNum);
31027
+ }
31028
+ }
31029
+ await streamCallback?.({
31030
+ type: "finish",
31031
+ finishReason: chunk.finishReason,
31032
+ usage: {
31033
+ promptTokens: chunk.usage.inputTokens || 0,
31034
+ completionTokens: chunk.usage.outputTokens || 0,
31035
+ totalTokens: chunk.usage.totalTokens ||
31036
+ (chunk.usage.inputTokens || 0) +
31037
+ (chunk.usage.outputTokens || 0),
31038
+ },
31039
+ });
31040
+ break;
31041
+ }
31042
+ }
31043
+ }
31044
+ }
31045
+ catch (e) {
31046
+ if (retryNum < config$1.maxRetryNum) {
31047
+ await sleep(200 * (retryNum + 1) * (retryNum + 1));
31048
+ if (errorHandler) {
31049
+ await errorHandler(request, e, retryNum);
31050
+ }
31051
+ return callLLM(rlm, request, streamCallback, errorHandler, finishHandler, ++retryNum);
31052
+ }
31053
+ throw e;
31054
+ }
31055
+ finally {
31056
+ reader && reader.releaseLock();
31057
+ }
31058
+ return streamText
31059
+ ? [
31060
+ { type: "text", text: streamText },
31061
+ ...toolParts,
31062
+ ]
31063
+ : toolParts;
31064
+ }
31065
+
31026
31066
  const global = {
31027
31067
  chatMap: new Map(),
31028
31068
  taskMap: new Map(),
31029
31069
  prompts: new Map(),
31030
31070
  };
31031
31071
 
31032
- const GlobalPromptKey = {
31033
- planner_system: "planner_system",
31034
- planner_example: "planner_example",
31035
- planner_user: "planner_user",
31036
- agent_system: "agent_system",
31037
- chat_system: "chat_system",
31038
- webpage_qa_prompt: "webpage_qa_prompt",
31039
- deep_action_description: "deep_action_description",
31040
- deep_action_param_task_description: "deep_action_param_task_description",
31041
- };
31072
+ var GlobalPromptKey;
31073
+ (function (GlobalPromptKey) {
31074
+ GlobalPromptKey["planner_system"] = "planner_system";
31075
+ GlobalPromptKey["planner_example"] = "planner_example";
31076
+ GlobalPromptKey["planner_user"] = "planner_user";
31077
+ GlobalPromptKey["agent_system"] = "agent_system";
31078
+ GlobalPromptKey["chat_system"] = "chat_system";
31079
+ GlobalPromptKey["webpage_qa_prompt"] = "webpage_qa_prompt";
31080
+ GlobalPromptKey["deep_action_description"] = "deep_action_description";
31081
+ GlobalPromptKey["deep_action_param_task_description"] = "deep_action_param_task_description";
31082
+ })(GlobalPromptKey || (GlobalPromptKey = {}));
31042
31083
 
31043
31084
  class PromptTemplate {
31044
31085
  /**
@@ -33020,7 +33061,7 @@ function buildPreTaskResult(context) {
33020
33061
  for (let i = 0; i < context.chain.agents.length; i++) {
33021
33062
  const agentChain = context.chain.agents[i];
33022
33063
  if (agentChain.agentResult) {
33023
- preTaskResult += `<subtask_result agent="${agentChain.agent.name}">Subtask: ${agentChain.agent.task}\nResult: ${sub(agentChain.agentResult, 600)}</subtask_result>`;
33064
+ preTaskResult += `<subtask_result agent="${agentChain.agent.name}">\nSubtask: ${agentChain.agent.task}\nResult: ${sub(agentChain.agentResult, 600).trim()}\n</subtask_result>`;
33024
33065
  }
33025
33066
  }
33026
33067
  return preTaskResult.trim();
@@ -33082,7 +33123,6 @@ class Agent {
33082
33123
  {
33083
33124
  role: "user",
33084
33125
  content: userPrompt,
33085
- providerOptions: defaultMessageProviderOptions(),
33086
33126
  },
33087
33127
  ];
33088
33128
  agentContext.messages = messages;
@@ -33102,7 +33142,7 @@ class Agent {
33102
33142
  }
33103
33143
  await this.handleMessages(agentContext, messages, tools);
33104
33144
  const llm_tools = convertTools(agentTools);
33105
- const results = await callAgentLLM(agentContext, rlm, messages, llm_tools, false, undefined, 0, this.callback, this.requestHandler);
33145
+ const results = await callAgentLLM(agentContext, rlm, messages, llm_tools, false, undefined, this.callback, this.requestHandler);
33106
33146
  const forceStop = agentContext.variables.get("forceStop");
33107
33147
  if (forceStop) {
33108
33148
  return forceStop;
@@ -33374,123 +33414,344 @@ class Agent {
33374
33414
  }
33375
33415
  }
33376
33416
 
33377
- function extract_page_content(max_url_length = 200, max_content_length = 50000) {
33378
- let result = "";
33379
- max_url_length = max_url_length || 200;
33380
- try {
33381
- function traverse(node) {
33382
- if (node.nodeType === Node.ELEMENT_NODE) {
33383
- const tagName = node.tagName.toLowerCase();
33384
- if (["script", "style", "noscript"].includes(tagName)) {
33385
- return;
33417
+ function extract_page_content(params) {
33418
+ params = params || {};
33419
+ const IGNORED_TAGS = new Set(params.ignored_tags || ["script", "style", "noscript", "svg", "canvas"]);
33420
+ const FORM_TAGS = new Set(["input", "select", "textarea"]);
33421
+ const KEY_ATTRIBUTES = new Set(params.key_attributes || [
33422
+ "id",
33423
+ "title",
33424
+ "name",
33425
+ "alt",
33426
+ "src",
33427
+ "url",
33428
+ "href",
33429
+ "value",
33430
+ "checked",
33431
+ "selected",
33432
+ ]);
33433
+ const urlLimit = params.max_url_length || 200;
33434
+ const contentLimit = params.max_content_length || 50000;
33435
+ const minImageArea = params.min_image_area || 1600;
33436
+ const parts = [];
33437
+ let currentLength = 0;
33438
+ const escapeHtml = (text) => {
33439
+ const map = {
33440
+ "<": "&lt;",
33441
+ ">": "&gt;",
33442
+ };
33443
+ return text.replace(/[<>]/g, (m) => map[m] || m);
33444
+ };
33445
+ const getKeyAttributes = (element) => {
33446
+ const attrs = {};
33447
+ const attributes = element.attributes;
33448
+ for (let i = 0; i < attributes.length; i++) {
33449
+ const attr = attributes[i];
33450
+ const name = attr.name.toLowerCase();
33451
+ if (KEY_ATTRIBUTES.has(name)) {
33452
+ const value = attr.value?.trim();
33453
+ if (value) {
33454
+ attrs[name] = value;
33386
33455
  }
33387
- const style = window.getComputedStyle(node);
33388
- if (style.display == "none" ||
33389
- style.visibility == "hidden" ||
33390
- style.opacity == "0") {
33391
- return;
33456
+ }
33457
+ }
33458
+ if (element instanceof HTMLInputElement) {
33459
+ const inputType = element.type.toLowerCase();
33460
+ if (inputType === "checkbox" || inputType === "radio") {
33461
+ if (element.checked) {
33462
+ attrs.checked = "true";
33392
33463
  }
33393
33464
  }
33394
- if (node.nodeType === Node.TEXT_NODE) {
33395
- // text
33396
- const text = node.textContent.trim();
33397
- if (text) {
33398
- result += text + " ";
33399
- }
33400
- }
33401
- else if (node.nodeType === Node.ELEMENT_NODE) {
33402
- const tagName = node.tagName.toLowerCase();
33403
- if (["input", "select", "textarea"].includes(tagName)) {
33404
- // input / select / textarea
33405
- if (tagName == "input" && node.type == "checkbox") {
33406
- result += node.checked + " ";
33407
- }
33408
- else if (tagName == "input" && node.type == "radio") {
33409
- if (node.checked && node.value) {
33410
- result += node.value + " ";
33411
- }
33412
- }
33413
- else if (node.value) {
33414
- result += node.value + " ";
33465
+ if (element.value && !attrs.value) {
33466
+ attrs.value = element.value;
33467
+ }
33468
+ if (element.name && !attrs.name) {
33469
+ attrs.name = element.name;
33470
+ }
33471
+ if (attrs.value || Object.keys(attrs).length > 0) {
33472
+ attrs.type = inputType;
33473
+ }
33474
+ }
33475
+ else if (element instanceof HTMLSelectElement) {
33476
+ if (element.selectedIndex >= 0) {
33477
+ const selectedOption = element.options[element.selectedIndex];
33478
+ if (selectedOption) {
33479
+ attrs.selected = String(element.selectedIndex);
33480
+ if (selectedOption.value && !attrs.value) {
33481
+ attrs.value = selectedOption.value;
33415
33482
  }
33416
33483
  }
33417
- else if (tagName === "img") {
33418
- // image
33419
- const src = node.src ||
33420
- node.getAttribute("src") ||
33421
- node.getAttribute("data-src");
33422
- const alt = node.alt || node.title || "";
33423
- if (src &&
33424
- src.length <= max_url_length &&
33425
- node.width * node.height >= 10000 &&
33426
- src.startsWith("http")) {
33427
- result += `![${alt ? alt : "image"}](${src.trim()}) `;
33428
- }
33484
+ }
33485
+ if (element.name && !attrs.name) {
33486
+ attrs.name = element.name;
33487
+ }
33488
+ }
33489
+ else if (element instanceof HTMLTextAreaElement) {
33490
+ if (element.value && !attrs.value) {
33491
+ attrs.value = element.value;
33492
+ }
33493
+ if (element.name && !attrs.name) {
33494
+ attrs.name = element.name;
33495
+ }
33496
+ }
33497
+ else if (element instanceof HTMLImageElement) {
33498
+ const src = element.src ||
33499
+ element.getAttribute("src") ||
33500
+ element.getAttribute("data-src");
33501
+ if (src && !attrs.src) {
33502
+ attrs.src = src;
33503
+ }
33504
+ if (element.alt && !attrs.alt) {
33505
+ attrs.alt = element.alt;
33506
+ }
33507
+ }
33508
+ else if (element instanceof HTMLAnchorElement) {
33509
+ if (element.href && !attrs.href) {
33510
+ attrs.href = element.href;
33511
+ }
33512
+ if (element.title && !attrs.title) {
33513
+ attrs.title = element.title;
33514
+ }
33515
+ }
33516
+ else if (element instanceof HTMLVideoElement ||
33517
+ element instanceof HTMLAudioElement) {
33518
+ const src = element.src || element.getAttribute("src");
33519
+ if (src && !attrs.src) {
33520
+ attrs.src = src;
33521
+ }
33522
+ }
33523
+ return attrs;
33524
+ };
33525
+ const buildAttributesString = (attrs) => {
33526
+ if (Object.keys(attrs).length === 0) {
33527
+ return "";
33528
+ }
33529
+ const attrStrings = [];
33530
+ for (const [key, value] of Object.entries(attrs)) {
33531
+ if (value) {
33532
+ attrStrings.push(`${key}="${escapeHtml(value)}"`);
33533
+ }
33534
+ }
33535
+ return attrStrings.length > 0 ? " " + attrStrings.join(" ") : "";
33536
+ };
33537
+ const hasKeyAttributes = (attrs) => {
33538
+ return Object.keys(attrs).length > 0;
33539
+ };
33540
+ const addHtmlContent = (content) => {
33541
+ if (!content || currentLength >= contentLimit) {
33542
+ return false;
33543
+ }
33544
+ const contentLength = content.length;
33545
+ if (currentLength + contentLength > contentLimit) {
33546
+ const remaining = contentLimit - currentLength;
33547
+ if (remaining > 0) {
33548
+ parts.push(content.slice(0, remaining));
33549
+ }
33550
+ return false;
33551
+ }
33552
+ currentLength += contentLength;
33553
+ parts.push(content);
33554
+ return true;
33555
+ };
33556
+ const hasDirectTextChild = (node) => {
33557
+ for (const child of node.childNodes) {
33558
+ if (child.nodeType === Node.TEXT_NODE) {
33559
+ const text = child.textContent || "";
33560
+ if (text.trim()) {
33561
+ return true;
33429
33562
  }
33430
- else if (tagName === "a" && node.children.length == 0) {
33431
- // link
33432
- const href = node.href || node.getAttribute("href");
33433
- const text = node.innerText.trim() || node.title;
33434
- if (text &&
33435
- href &&
33436
- href.length <= max_url_length &&
33437
- href.startsWith("http")) {
33438
- result += `[${text}](${href.trim()}) `;
33439
- }
33440
- else {
33441
- result += text + " ";
33563
+ }
33564
+ }
33565
+ return false;
33566
+ };
33567
+ const traverse = (node) => {
33568
+ if (currentLength >= contentLimit) {
33569
+ return "";
33570
+ }
33571
+ if (node.nodeType === Node.TEXT_NODE) {
33572
+ const text = node.textContent || "";
33573
+ const trimmed = text.trim();
33574
+ if (trimmed) {
33575
+ return escapeHtml(trimmed);
33576
+ }
33577
+ return "";
33578
+ }
33579
+ if (node.nodeType !== Node.ELEMENT_NODE) {
33580
+ return "";
33581
+ }
33582
+ const element = node;
33583
+ const tagName = element.tagName.toLowerCase();
33584
+ if (IGNORED_TAGS.has(tagName)) {
33585
+ return "";
33586
+ }
33587
+ try {
33588
+ const style = window.getComputedStyle(element);
33589
+ if (style.display === "none") {
33590
+ return "";
33591
+ }
33592
+ }
33593
+ catch (e) { }
33594
+ const attrs = getKeyAttributes(element);
33595
+ const attrsString = buildAttributesString(attrs);
33596
+ const hasKeyAttrs = hasKeyAttributes(attrs);
33597
+ const hasDirectText = hasDirectTextChild(node);
33598
+ if (FORM_TAGS.has(tagName)) {
33599
+ let value = "";
33600
+ if (tagName === "input") {
33601
+ const input = element;
33602
+ const inputType = input.type.toLowerCase();
33603
+ if (inputType === "checkbox" || inputType === "radio") {
33604
+ if (!input.checked) {
33605
+ return "";
33442
33606
  }
33607
+ value = input.value || String(input.checked);
33443
33608
  }
33444
- else if (tagName === "video" || tagName == "audio") {
33445
- // video / audio
33446
- let src = node.src || node.getAttribute("src");
33447
- const sources = node.querySelectorAll("source");
33448
- if (sources.length > 0 && sources[0].src) {
33449
- src = sources[0].src;
33450
- if (src && src.startsWith("http") && sources[0].type) {
33451
- result += sources[0].type + " ";
33452
- }
33453
- }
33454
- if (src && src.startsWith("http")) {
33455
- result += src.trim() + " ";
33456
- }
33609
+ else if (inputType === "password") {
33610
+ return "";
33457
33611
  }
33458
- else if (tagName === "br") {
33459
- // br
33460
- result += "\n";
33612
+ else {
33613
+ value = input.value || "";
33461
33614
  }
33462
- else if (["p", "div", "h1", "h2", "h3", "h4", "h5", "h6"].includes(tagName)) {
33463
- // block
33464
- result += "\n";
33465
- for (let child of node.childNodes) {
33466
- traverse(child);
33467
- }
33468
- result += "\n";
33469
- return;
33615
+ }
33616
+ else if (tagName === "select") {
33617
+ const select = element;
33618
+ if (select.selectedIndex >= 0) {
33619
+ const selectedOption = select.options[select.selectedIndex];
33620
+ value = selectedOption
33621
+ ? selectedOption.text || selectedOption.value
33622
+ : "";
33470
33623
  }
33471
- else if (tagName === "hr") {
33472
- // hr
33473
- result += "\n--------\n";
33624
+ }
33625
+ else if (tagName === "textarea") {
33626
+ value = element.value || "";
33627
+ }
33628
+ if (value || hasKeyAttrs || tagName === "textarea") {
33629
+ const escapedValue = escapeHtml(value);
33630
+ return `<${tagName}${attrsString}>${escapedValue}</${tagName}>`;
33631
+ }
33632
+ return "";
33633
+ }
33634
+ if (tagName === "img") {
33635
+ const img = element;
33636
+ const src = img.src || img.getAttribute("src") || img.getAttribute("data-src");
33637
+ if (src &&
33638
+ src.length <= urlLimit &&
33639
+ img.width * img.height >= minImageArea &&
33640
+ src.startsWith("http")) {
33641
+ if (!attrs.alt && (img.alt || img.title)) {
33642
+ attrs.alt = img.alt || img.title || "";
33474
33643
  }
33475
- else {
33476
- // recursive
33477
- for (let child of node.childNodes) {
33478
- traverse(child);
33479
- }
33644
+ if (!attrs.src) {
33645
+ attrs.src = src.trim();
33646
+ }
33647
+ const imgAttrsString = buildAttributesString(attrs);
33648
+ return `<img${imgAttrsString} />`;
33649
+ }
33650
+ return "";
33651
+ }
33652
+ if (tagName === "a") {
33653
+ const anchor = element;
33654
+ const href = anchor.href || anchor.getAttribute("href");
33655
+ const childContent = [];
33656
+ for (const child of node.childNodes) {
33657
+ const content = traverse(child);
33658
+ if (content) {
33659
+ childContent.push(content);
33660
+ }
33661
+ }
33662
+ const innerContent = childContent.join("");
33663
+ if (!innerContent && !hasKeyAttrs) {
33664
+ return "";
33665
+ }
33666
+ if (href && href.length <= urlLimit && href.startsWith("http")) {
33667
+ if (!attrs.href) {
33668
+ attrs.href = href.trim();
33480
33669
  }
33670
+ const linkAttrsString = buildAttributesString(attrs);
33671
+ return `<a${linkAttrsString}>${innerContent}</a>`;
33672
+ }
33673
+ else if (hasKeyAttrs || hasDirectText) {
33674
+ return `<a${attrsString}>${innerContent}</a>`;
33675
+ }
33676
+ return innerContent;
33677
+ }
33678
+ if (tagName === "video" || tagName === "audio") {
33679
+ const media = element;
33680
+ let src = media.src || media.getAttribute("src");
33681
+ const sources = element.querySelectorAll("source");
33682
+ if (sources.length > 0 && sources[0].src) {
33683
+ src = sources[0].src;
33684
+ }
33685
+ if (src && src.startsWith("http") && src.length <= urlLimit) {
33686
+ if (!attrs.src) {
33687
+ attrs.src = src.trim();
33688
+ }
33689
+ const mediaAttrsString = buildAttributesString(attrs);
33690
+ return `<${tagName}${mediaAttrsString}></${tagName}>`;
33691
+ }
33692
+ return "";
33693
+ }
33694
+ const childContent = [];
33695
+ for (const child of node.childNodes) {
33696
+ const content = traverse(child);
33697
+ if (content) {
33698
+ childContent.push(content);
33699
+ }
33700
+ }
33701
+ const innerContent = childContent.join("");
33702
+ if (!innerContent) {
33703
+ return "";
33704
+ }
33705
+ if (hasKeyAttrs || hasDirectText) {
33706
+ return `<${tagName}${attrsString}>${innerContent}</${tagName}>`;
33707
+ }
33708
+ return innerContent;
33709
+ };
33710
+ if (!params.root_element) {
33711
+ if (params.root_selector) {
33712
+ params.root_element = document.querySelector(params.root_selector);
33713
+ if (!params.root_element) {
33714
+ return "";
33715
+ }
33716
+ }
33717
+ else {
33718
+ params.root_element = document.body;
33719
+ }
33720
+ }
33721
+ const rootTabName = params.root_element.tagName.toLowerCase();
33722
+ try {
33723
+ if (params.root_element) {
33724
+ const content = traverse(params.root_element);
33725
+ if (content) {
33726
+ addHtmlContent(content);
33481
33727
  }
33482
33728
  }
33483
- traverse(document.body);
33484
33729
  }
33485
33730
  catch (e) {
33486
- result = document.body.innerText;
33731
+ try {
33732
+ const fallbackText = params.root_element.innerText || "";
33733
+ if (fallbackText) {
33734
+ const escaped = escapeHtml(fallbackText);
33735
+ const truncated = escaped.length > contentLimit
33736
+ ? Array.from(escaped).slice(0, contentLimit).join("").trim() + "..."
33737
+ : escaped;
33738
+ return truncated.startsWith(`<${rootTabName}`)
33739
+ ? truncated
33740
+ : `<${rootTabName}>${truncated}</${rootTabName}>`;
33741
+ }
33742
+ return "";
33743
+ }
33744
+ catch {
33745
+ return "";
33746
+ }
33487
33747
  }
33488
- result = result.replace(/\s*\n/g, "\n").replace(/\n+/g, "\n").trim();
33489
- if (result.length > max_content_length) {
33490
- // result = result.slice(0, max_content_length) + "...";
33491
- result = Array.from(result).slice(0, max_content_length).join("") + "...";
33748
+ let result = parts.join("");
33749
+ if (result.length > contentLimit) {
33750
+ result = Array.from(result).slice(0, contentLimit).join("").trim() + "...";
33492
33751
  }
33493
- return result;
33752
+ return result.startsWith(`<${rootTabName}`)
33753
+ ? result
33754
+ : `<${rootTabName}>${result}</${rootTabName}>`;
33494
33755
  }
33495
33756
  function mark_screenshot_highlight_elements(screenshot, area_map, client_rect) {
33496
33757
  return new Promise(async (resolve, reject) => {
@@ -33498,8 +33759,13 @@ function mark_screenshot_highlight_elements(screenshot, area_map, client_rect) {
33498
33759
  const hasOffscreen = typeof OffscreenCanvas !== "undefined";
33499
33760
  const hasCreateImageBitmap = typeof createImageBitmap !== "undefined";
33500
33761
  const hasDOM = typeof document !== "undefined" && typeof Image !== "undefined";
33501
- // @ts-ignore
33502
- const isNode = typeof window === "undefined" && typeof process !== "undefined" && !!process.versions && !!process.versions.node;
33762
+ const isNode = typeof window === "undefined" &&
33763
+ // @ts-ignore
33764
+ typeof process !== "undefined" &&
33765
+ // @ts-ignore
33766
+ !!process.versions &&
33767
+ // @ts-ignore
33768
+ !!process.versions.node;
33503
33769
  const loadImageAny = async () => {
33504
33770
  if (hasCreateImageBitmap) {
33505
33771
  const base64Data = screenshot.imageBase64;
@@ -35813,7 +36079,6 @@ class EkoMemory {
35813
36079
  };
35814
36080
  }
35815
36081
  }),
35816
- providerOptions: defaultMessageProviderOptions(),
35817
36082
  });
35818
36083
  }
35819
36084
  else if (message.role == "assistant") {
@@ -36330,251 +36595,24 @@ class SimpleHttpMcpClient {
36330
36595
  }
36331
36596
  }
36332
36597
 
36333
- async function callChatLLM(messageId, chatContext, rlm, messages, tools, toolChoice, retryNum = 0, callback, signal) {
36598
+ async function callChatLLM(chatId, messageId, rlm, messages, tools, toolChoice, callback, signal) {
36334
36599
  const streamCallback = callback?.chatCallback || {
36335
36600
  onMessage: async () => { },
36336
36601
  };
36337
36602
  const request = {
36338
- tools: tools,
36603
+ tools,
36604
+ messages,
36339
36605
  toolChoice,
36340
- messages: messages,
36341
36606
  abortSignal: signal,
36342
36607
  };
36343
- let streamText = "";
36344
- let thinkText = "";
36345
- let toolArgsText = "";
36346
- let textStreamId = uuidv4();
36347
- let thinkStreamId = uuidv4();
36348
- let textStreamDone = false;
36349
- const toolParts = [];
36350
- let reader = null;
36351
- try {
36352
- const result = await rlm.callStream(request);
36353
- reader = result.stream.getReader();
36354
- let toolPart = null;
36355
- while (true) {
36356
- const { done, value } = await reader.read();
36357
- if (done) {
36358
- break;
36359
- }
36360
- const chunk = value;
36361
- switch (chunk.type) {
36362
- case "text-start": {
36363
- textStreamId = uuidv4();
36364
- break;
36365
- }
36366
- case "text-delta": {
36367
- if (toolPart && !chunk.delta) {
36368
- continue;
36369
- }
36370
- streamText += chunk.delta || "";
36371
- await streamCallback.onMessage({
36372
- streamType: "chat",
36373
- chatId: chatContext.getChatId(),
36374
- messageId,
36375
- type: "text",
36376
- streamId: textStreamId,
36377
- streamDone: false,
36378
- text: streamText,
36379
- });
36380
- if (toolPart) {
36381
- await streamCallback.onMessage({
36382
- streamType: "chat",
36383
- chatId: chatContext.getChatId(),
36384
- messageId,
36385
- type: "tool_use",
36386
- toolCallId: toolPart.toolCallId,
36387
- toolName: toolPart.toolName,
36388
- params: toolPart.input || {},
36389
- });
36390
- toolPart = null;
36391
- }
36392
- break;
36393
- }
36394
- case "text-end": {
36395
- textStreamDone = true;
36396
- if (streamText) {
36397
- await streamCallback.onMessage({
36398
- streamType: "chat",
36399
- chatId: chatContext.getChatId(),
36400
- messageId,
36401
- type: "text",
36402
- streamId: textStreamId,
36403
- streamDone: true,
36404
- text: streamText,
36405
- });
36406
- }
36407
- break;
36408
- }
36409
- case "reasoning-start": {
36410
- thinkStreamId = uuidv4();
36411
- break;
36412
- }
36413
- case "reasoning-delta": {
36414
- thinkText += chunk.delta || "";
36415
- await streamCallback.onMessage({
36416
- streamType: "chat",
36417
- chatId: chatContext.getChatId(),
36418
- messageId,
36419
- type: "thinking",
36420
- streamId: thinkStreamId,
36421
- streamDone: false,
36422
- text: thinkText,
36423
- });
36424
- break;
36425
- }
36426
- case "reasoning-end": {
36427
- if (thinkText) {
36428
- await streamCallback.onMessage({
36429
- streamType: "chat",
36430
- chatId: chatContext.getChatId(),
36431
- messageId,
36432
- type: "thinking",
36433
- streamId: thinkStreamId,
36434
- streamDone: true,
36435
- text: thinkText,
36436
- });
36437
- }
36438
- break;
36439
- }
36440
- case "tool-input-start": {
36441
- if (toolPart && toolPart.toolCallId == chunk.id) {
36442
- toolPart.toolName = chunk.toolName;
36443
- }
36444
- else {
36445
- toolPart = {
36446
- type: "tool-call",
36447
- toolCallId: chunk.id,
36448
- toolName: chunk.toolName,
36449
- input: {},
36450
- };
36451
- toolParts.push(toolPart);
36452
- }
36453
- break;
36454
- }
36455
- case "tool-input-delta": {
36456
- if (!textStreamDone) {
36457
- textStreamDone = true;
36458
- await streamCallback.onMessage({
36459
- streamType: "chat",
36460
- chatId: chatContext.getChatId(),
36461
- messageId,
36462
- type: "text",
36463
- streamId: textStreamId,
36464
- streamDone: true,
36465
- text: streamText,
36466
- });
36467
- }
36468
- toolArgsText += chunk.delta || "";
36469
- await streamCallback.onMessage({
36470
- streamType: "chat",
36471
- chatId: chatContext.getChatId(),
36472
- messageId,
36473
- type: "tool_streaming",
36474
- toolCallId: chunk.id,
36475
- toolName: toolPart?.toolName || "",
36476
- paramsText: toolArgsText,
36477
- });
36478
- break;
36479
- }
36480
- case "tool-call": {
36481
- toolArgsText = "";
36482
- const args = chunk.input ? JSON.parse(chunk.input) : {};
36483
- const message = {
36484
- streamType: "chat",
36485
- chatId: chatContext.getChatId(),
36486
- messageId,
36487
- type: "tool_use",
36488
- toolCallId: chunk.toolCallId,
36489
- toolName: chunk.toolName,
36490
- params: args,
36491
- };
36492
- await streamCallback.onMessage(message);
36493
- if (toolPart == null) {
36494
- toolParts.push({
36495
- type: "tool-call",
36496
- toolCallId: chunk.toolCallId,
36497
- toolName: chunk.toolName,
36498
- input: message.params || args,
36499
- });
36500
- }
36501
- else {
36502
- toolPart.input = message.params || args;
36503
- toolPart = null;
36504
- }
36505
- break;
36506
- }
36507
- case "error": {
36508
- Log.error(`chatLLM error: `, chunk);
36509
- await streamCallback.onMessage({
36510
- streamType: "chat",
36511
- chatId: chatContext.getChatId(),
36512
- messageId,
36513
- type: "error",
36514
- error: chunk.error,
36515
- });
36516
- throw new Error("LLM Error: " + chunk.error);
36517
- }
36518
- case "finish": {
36519
- if (!textStreamDone) {
36520
- textStreamDone = true;
36521
- await streamCallback.onMessage({
36522
- streamType: "chat",
36523
- chatId: chatContext.getChatId(),
36524
- messageId,
36525
- type: "text",
36526
- streamId: textStreamId,
36527
- streamDone: true,
36528
- text: streamText,
36529
- });
36530
- }
36531
- if (toolPart) {
36532
- await streamCallback.onMessage({
36533
- streamType: "chat",
36534
- chatId: chatContext.getChatId(),
36535
- messageId,
36536
- type: "tool_use",
36537
- toolCallId: toolPart.toolCallId,
36538
- toolName: toolPart.toolName,
36539
- params: toolPart.input || {},
36540
- });
36541
- toolPart = null;
36542
- }
36543
- await streamCallback.onMessage({
36544
- streamType: "chat",
36545
- chatId: chatContext.getChatId(),
36546
- messageId,
36547
- type: "finish",
36548
- finishReason: chunk.finishReason,
36549
- usage: {
36550
- promptTokens: chunk.usage.inputTokens || 0,
36551
- completionTokens: chunk.usage.outputTokens || 0,
36552
- totalTokens: chunk.usage.totalTokens ||
36553
- (chunk.usage.inputTokens || 0) +
36554
- (chunk.usage.outputTokens || 0),
36555
- },
36556
- });
36557
- break;
36558
- }
36559
- }
36560
- }
36561
- }
36562
- catch (e) {
36563
- if (retryNum < config$1.maxRetryNum) {
36564
- await sleep(200 * (retryNum + 1) * (retryNum + 1));
36565
- return callChatLLM(messageId, chatContext, rlm, messages, tools, toolChoice, ++retryNum, callback, signal);
36566
- }
36567
- throw e;
36568
- }
36569
- finally {
36570
- reader && reader.releaseLock();
36571
- }
36572
- return streamText
36573
- ? [
36574
- { type: "text", text: streamText },
36575
- ...toolParts,
36576
- ]
36577
- : toolParts;
36608
+ return await callLLM(rlm, request, async (message) => {
36609
+ await streamCallback.onMessage({
36610
+ streamType: "chat",
36611
+ chatId,
36612
+ messageId,
36613
+ ...message,
36614
+ });
36615
+ });
36578
36616
  }
36579
36617
  function convertAssistantToolResults(results) {
36580
36618
  return results.map((part) => {
@@ -36934,6 +36972,7 @@ class DeepActionTool {
36934
36972
  });
36935
36973
  const taskWebsite = await this.gettaskWebsite(tabIds);
36936
36974
  const workflow = await eko.generate(taskDescription, messageId, {
36975
+ ...(this.params.extra || {}),
36937
36976
  ...globalVariables,
36938
36977
  tabIds: tabIds,
36939
36978
  language: language,
@@ -37177,7 +37216,7 @@ class ChatAgent {
37177
37216
  const rlm = new RetryLanguageModel(config.llms, config.chatLlms);
37178
37217
  for (; reactLoopNum < 15; reactLoopNum++) {
37179
37218
  const messages = this.memory.buildMessages();
37180
- const results = await callChatLLM(params.messageId, this.chatContext, rlm, messages, convertTools(chatTools), undefined, 0, params.callback, params.signal);
37219
+ const results = await callChatLLM(this.chatContext.getChatId(), params.messageId, rlm, messages, convertTools(chatTools), undefined, params.callback, params.signal);
37181
37220
  const finalResult = await this.handleCallResult(params.messageId, chatTools, results, params.callback);
37182
37221
  if (finalResult) {
37183
37222
  return finalResult;
@@ -37397,6 +37436,8 @@ exports.WebSearchTool = WebSearchTool;
37397
37436
  exports.WebpageQaTool = WebpageQaTool;
37398
37437
  exports.buildAgentTree = buildAgentTree;
37399
37438
  exports.buildSimpleAgentWorkflow = buildSimpleAgentWorkflow;
37439
+ exports.callLLM = callLLM;
37440
+ exports.callWithReAct = callWithReAct;
37400
37441
  exports.call_timeout = call_timeout;
37401
37442
  exports.compressImageData = compressImageData;
37402
37443
  exports.config = config$1;