@eko-ai/eko 4.0.4 → 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 (37) 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 +681 -666
  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 +680 -667
  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/types/agent.types.d.ts +2 -47
  28. package/dist/types/agent.types.d.ts.map +1 -1
  29. package/dist/types/chat.types.d.ts +3 -45
  30. package/dist/types/chat.types.d.ts.map +1 -1
  31. package/dist/types/config.types.d.ts +10 -10
  32. package/dist/types/config.types.d.ts.map +1 -1
  33. package/dist/types/index.d.ts +2 -2
  34. package/dist/types/index.d.ts.map +1 -1
  35. package/dist/types/llm.types.d.ts +51 -1
  36. package/dist/types/llm.types.d.ts.map +1 -1
  37. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -393,9 +393,10 @@ async function compressImageData(imageBase64, imageType, compress, quality) {
393
393
  ctx: canvas.getContext("2d"),
394
394
  exportBase64: async (mime, q) => {
395
395
  const buffer = canvas.toBuffer(mime, { quality: q });
396
- return ((
396
+ const _Buffer =
397
397
  // @ts-ignore
398
- typeof Buffer !== "undefined" ? Buffer.from(buffer) : buffer).toString("base64"));
398
+ typeof Buffer !== "undefined" ? Buffer.from(buffer) : buffer;
399
+ return _Buffer.toString("base64");
399
400
  },
400
401
  };
401
402
  }
@@ -475,13 +476,19 @@ function mergeAgents(agents1, agents2) {
475
476
  }
476
477
  return agents;
477
478
  }
478
- function sub(str, maxLength, appendPoint = true) {
479
+ function sub(str, maxLength, appendPoint = true, showTruncated = true) {
479
480
  if (!str) {
480
481
  return "";
481
482
  }
482
483
  if (str.length > maxLength) {
483
- // return str.substring(0, maxLength) + (appendPoint ? "..." : "");
484
- return (Array.from(str).slice(0, maxLength).join("") + (appendPoint ? "..." : ""));
484
+ const truncatedLength = str.length - maxLength;
485
+ // return str.substring(0, maxLength) + (appendPoint ? showTruncated ? `...(truncated: +${truncatedLength} chars)` : "..." : "");
486
+ return (Array.from(str).slice(0, maxLength).join("") +
487
+ (appendPoint
488
+ ? showTruncated
489
+ ? `...(truncated: +${truncatedLength} chars)`
490
+ : "..."
491
+ : ""));
485
492
  }
486
493
  return str;
487
494
  }
@@ -30161,7 +30168,7 @@ function convertToolResult(toolUse, toolResult, user_messages) {
30161
30168
  output: result,
30162
30169
  };
30163
30170
  }
30164
- async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, retryNum = 0, callback, requestHandler) {
30171
+ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, callback, requestHandler) {
30165
30172
  await agentContext.context.checkAborted();
30166
30173
  if (!noCompress &&
30167
30174
  (messages.length >= config$1.compressThreshold ||
@@ -30194,314 +30201,47 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
30194
30201
  abortSignal: signal,
30195
30202
  };
30196
30203
  requestHandler && requestHandler(request);
30197
- let streamText = "";
30198
- let thinkText = "";
30199
- let toolArgsText = "";
30200
- let textStreamId = uuidv4();
30201
- let thinkStreamId = uuidv4();
30202
- let textStreamDone = false;
30203
- const toolParts = [];
30204
- let reader = null;
30205
30204
  try {
30206
30205
  agentChain.agentRequest = request;
30207
30206
  context.currentStepControllers.add(stepController);
30208
- const result = await rlm.callStream(request);
30209
- reader = result.stream.getReader();
30210
- let toolPart = null;
30211
- while (true) {
30207
+ const result = await callLLM(rlm, request, async (message) => {
30212
30208
  await context.checkAborted();
30213
- const { done, value } = await reader.read();
30214
- if (done) {
30215
- break;
30209
+ await streamCallback.onMessage({
30210
+ streamType: "agent",
30211
+ chatId: context.chatId,
30212
+ taskId: context.taskId,
30213
+ agentName: agentNode.name,
30214
+ nodeId: agentNode.id,
30215
+ ...message,
30216
+ });
30217
+ }, async (request, error) => {
30218
+ if ((error + "").indexOf("is too long") > -1) {
30219
+ await compressAgentMessages(agentContext, messages, tools);
30216
30220
  }
30217
- const chunk = value;
30218
- switch (chunk.type) {
30219
- case "text-start": {
30220
- textStreamId = uuidv4();
30221
- break;
30222
- }
30223
- case "text-delta": {
30224
- if (toolPart && !chunk.delta) {
30225
- continue;
30226
- }
30227
- streamText += chunk.delta || "";
30228
- await streamCallback.onMessage({
30229
- streamType: "agent",
30230
- chatId: context.chatId,
30231
- taskId: context.taskId,
30232
- agentName: agentNode.name,
30233
- nodeId: agentNode.id,
30234
- type: "text",
30235
- streamId: textStreamId,
30236
- streamDone: false,
30237
- text: streamText,
30238
- }, agentContext);
30239
- if (toolPart) {
30240
- await streamCallback.onMessage({
30241
- streamType: "agent",
30242
- chatId: context.chatId,
30243
- taskId: context.taskId,
30244
- agentName: agentNode.name,
30245
- nodeId: agentNode.id,
30246
- type: "tool_use",
30247
- toolCallId: toolPart.toolCallId,
30248
- toolName: toolPart.toolName,
30249
- params: toolPart.input || {},
30250
- }, agentContext);
30251
- toolPart = null;
30252
- }
30253
- break;
30254
- }
30255
- case "text-end": {
30256
- textStreamDone = true;
30257
- if (streamText) {
30258
- await streamCallback.onMessage({
30259
- streamType: "agent",
30260
- chatId: context.chatId,
30261
- taskId: context.taskId,
30262
- agentName: agentNode.name,
30263
- nodeId: agentNode.id,
30264
- type: "text",
30265
- streamId: textStreamId,
30266
- streamDone: true,
30267
- text: streamText,
30268
- }, agentContext);
30269
- }
30270
- break;
30271
- }
30272
- case "reasoning-start": {
30273
- thinkStreamId = uuidv4();
30274
- break;
30275
- }
30276
- case "reasoning-delta": {
30277
- thinkText += chunk.delta || "";
30278
- await streamCallback.onMessage({
30279
- streamType: "agent",
30280
- chatId: context.chatId,
30281
- taskId: context.taskId,
30282
- agentName: agentNode.name,
30283
- nodeId: agentNode.id,
30284
- type: "thinking",
30285
- streamId: thinkStreamId,
30286
- streamDone: false,
30287
- text: thinkText,
30288
- }, agentContext);
30289
- break;
30290
- }
30291
- case "reasoning-end": {
30292
- if (thinkText) {
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: "thinking",
30300
- streamId: thinkStreamId,
30301
- streamDone: true,
30302
- text: thinkText,
30303
- }, agentContext);
30304
- }
30305
- break;
30306
- }
30307
- case "tool-input-start": {
30308
- if (toolPart && toolPart.toolCallId == chunk.id) {
30309
- toolPart.toolName = chunk.toolName;
30310
- }
30311
- else {
30312
- const _toolPart = toolParts.filter((s) => s.toolCallId == chunk.id)[0];
30313
- if (_toolPart) {
30314
- toolPart = _toolPart;
30315
- toolPart.toolName = _toolPart.toolName || chunk.toolName;
30316
- toolPart.input = _toolPart.input || {};
30317
- }
30318
- else {
30319
- toolPart = {
30320
- type: "tool-call",
30321
- toolCallId: chunk.id,
30322
- toolName: chunk.toolName,
30323
- input: {},
30324
- };
30325
- toolParts.push(toolPart);
30326
- }
30327
- }
30328
- break;
30329
- }
30330
- case "tool-input-delta": {
30331
- if (!textStreamDone) {
30332
- textStreamDone = true;
30333
- await streamCallback.onMessage({
30334
- streamType: "agent",
30335
- chatId: context.chatId,
30336
- taskId: context.taskId,
30337
- agentName: agentNode.name,
30338
- nodeId: agentNode.id,
30339
- type: "text",
30340
- streamId: textStreamId,
30341
- streamDone: true,
30342
- text: streamText,
30343
- }, agentContext);
30344
- }
30345
- toolArgsText += chunk.delta || "";
30346
- await streamCallback.onMessage({
30347
- streamType: "agent",
30348
- chatId: context.chatId,
30349
- taskId: context.taskId,
30350
- agentName: agentNode.name,
30351
- nodeId: agentNode.id,
30352
- type: "tool_streaming",
30353
- toolCallId: chunk.id,
30354
- toolName: toolPart?.toolName || "",
30355
- paramsText: toolArgsText,
30356
- }, agentContext);
30357
- break;
30358
- }
30359
- case "tool-call": {
30360
- toolArgsText = "";
30361
- const args = chunk.input ? JSON.parse(chunk.input) : {};
30362
- const message = {
30363
- streamType: "agent",
30364
- chatId: context.chatId,
30365
- taskId: context.taskId,
30366
- agentName: agentNode.name,
30367
- nodeId: agentNode.id,
30368
- type: "tool_use",
30369
- toolCallId: chunk.toolCallId,
30370
- toolName: chunk.toolName,
30371
- params: args,
30372
- };
30373
- await streamCallback.onMessage(message, agentContext);
30374
- if (toolPart == null) {
30375
- const _toolPart = toolParts.filter((s) => s.toolCallId == chunk.toolCallId)[0];
30376
- if (_toolPart) {
30377
- _toolPart.input = message.params || args;
30378
- }
30379
- else {
30380
- toolParts.push({
30381
- type: "tool-call",
30382
- toolCallId: chunk.toolCallId,
30383
- toolName: chunk.toolName,
30384
- input: message.params || args,
30385
- });
30386
- }
30387
- }
30388
- else {
30389
- toolPart.input = message.params || args;
30390
- toolPart = null;
30391
- }
30392
- break;
30393
- }
30394
- case "file": {
30395
- await streamCallback.onMessage({
30396
- streamType: "agent",
30397
- chatId: context.chatId,
30398
- taskId: context.taskId,
30399
- agentName: agentNode.name,
30400
- nodeId: agentNode.id,
30401
- type: "file",
30402
- mimeType: chunk.mediaType,
30403
- data: chunk.data,
30404
- }, agentContext);
30405
- break;
30406
- }
30407
- case "error": {
30408
- Log.error(`${agentNode.name} agent error: `, chunk);
30409
- await streamCallback.onMessage({
30410
- streamType: "agent",
30411
- chatId: context.chatId,
30412
- taskId: context.taskId,
30413
- agentName: agentNode.name,
30414
- nodeId: agentNode.id,
30415
- type: "error",
30416
- error: chunk.error,
30417
- }, agentContext);
30418
- throw new Error("LLM Error: " + chunk.error);
30419
- }
30420
- case "finish": {
30421
- if (!textStreamDone) {
30422
- textStreamDone = true;
30423
- await streamCallback.onMessage({
30424
- streamType: "agent",
30425
- chatId: context.chatId,
30426
- taskId: context.taskId,
30427
- agentName: agentNode.name,
30428
- nodeId: agentNode.id,
30429
- type: "text",
30430
- streamId: textStreamId,
30431
- streamDone: true,
30432
- text: streamText,
30433
- }, agentContext);
30434
- }
30435
- if (chunk.finishReason === "content-filter") {
30436
- throw new Error("LLM error: trigger content filtering violation");
30437
- }
30438
- else if (chunk.finishReason === "other") {
30439
- throw new Error("LLM error: terminated due to other reasons");
30440
- }
30441
- else if (chunk.finishReason === "length" &&
30442
- messages.length >= 3 &&
30443
- !noCompress &&
30444
- retryNum < config$1.maxRetryNum) {
30445
- await compressAgentMessages(agentContext, messages, tools);
30446
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
30447
- }
30448
- if (toolPart) {
30449
- await streamCallback.onMessage({
30450
- streamType: "agent",
30451
- chatId: context.chatId,
30452
- taskId: context.taskId,
30453
- agentName: agentNode.name,
30454
- nodeId: agentNode.id,
30455
- type: "tool_use",
30456
- toolCallId: toolPart.toolCallId,
30457
- toolName: toolPart.toolName,
30458
- params: toolPart.input || {},
30459
- }, agentContext);
30460
- toolPart = null;
30461
- }
30462
- await streamCallback.onMessage({
30463
- streamType: "agent",
30464
- chatId: context.chatId,
30465
- taskId: context.taskId,
30466
- agentName: agentNode.name,
30467
- nodeId: agentNode.id,
30468
- type: "finish",
30469
- finishReason: chunk.finishReason,
30470
- usage: {
30471
- promptTokens: chunk.usage.inputTokens || 0,
30472
- completionTokens: chunk.usage.outputTokens || 0,
30473
- totalTokens: chunk.usage.totalTokens ||
30474
- (chunk.usage.inputTokens || 0) +
30475
- (chunk.usage.outputTokens || 0),
30476
- },
30477
- }, agentContext);
30478
- break;
30479
- }
30221
+ }, async (request, finishReason, value, retryNum) => {
30222
+ if (finishReason === "content-filter") {
30223
+ throw new Error("LLM error: trigger content filtering violation");
30480
30224
  }
30481
- }
30482
- }
30483
- catch (e) {
30484
- await context.checkAborted();
30485
- if (retryNum < config$1.maxRetryNum) {
30486
- await sleep(300 * (retryNum + 1) * (retryNum + 1));
30487
- if ((e + "").indexOf("is too long") > -1) {
30225
+ else if (finishReason === "other") {
30226
+ throw new Error("LLM error: terminated due to other reasons");
30227
+ }
30228
+ else if (finishReason === "length" &&
30229
+ messages.length >= 3 &&
30230
+ !noCompress &&
30231
+ retryNum < config$1.maxRetryNum) {
30488
30232
  await compressAgentMessages(agentContext, messages, tools);
30233
+ return "retry";
30489
30234
  }
30490
- return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
30491
- }
30492
- throw e;
30235
+ });
30236
+ agentChain.agentResult = result
30237
+ .filter((s) => s.type == "text")
30238
+ .map((s) => s.text)
30239
+ .join("\n\n");
30240
+ return result;
30493
30241
  }
30494
30242
  finally {
30495
- reader && reader.releaseLock();
30496
30243
  context.currentStepControllers.delete(stepController);
30497
30244
  }
30498
- agentChain.agentResult = streamText;
30499
- return streamText
30500
- ? [
30501
- { type: "text", text: streamText },
30502
- ...toolParts,
30503
- ]
30504
- : toolParts;
30505
30245
  }
30506
30246
  function estimatePromptTokens(messages, tools) {
30507
30247
  let tokens = messages.reduce((total, message) => {
@@ -31002,22 +30742,309 @@ class RetryLanguageModel {
31002
30742
  }
31003
30743
  }
31004
30744
 
30745
+ async function callWithReAct(rlm, request, toolCallCallback, streamCallback, errorHandler, finishHandler, loopControl) {
30746
+ if (!loopControl) {
30747
+ loopControl = async (request, assistantParts, loopNum) => {
30748
+ if (loopNum >= 15) {
30749
+ return false;
30750
+ }
30751
+ return assistantParts.filter((s) => s.type == "tool-call").length > 0;
30752
+ };
30753
+ }
30754
+ let loopNum = 0;
30755
+ let assistantParts = null;
30756
+ while (true) {
30757
+ assistantParts = await callLLM(rlm, request, streamCallback, errorHandler, finishHandler);
30758
+ if (assistantParts.length > 0) {
30759
+ request.messages.push({
30760
+ role: "assistant",
30761
+ content: assistantParts
30762
+ .filter((part) => part.type == "text" || part.type == "tool-call")
30763
+ .map((part) => part.type === "text"
30764
+ ? {
30765
+ type: "text",
30766
+ text: part.text,
30767
+ }
30768
+ : {
30769
+ type: "tool-call",
30770
+ toolCallId: part.toolCallId,
30771
+ toolName: part.toolName,
30772
+ input: JSON.parse((part.input || "{}")),
30773
+ }),
30774
+ });
30775
+ }
30776
+ const continueLoop = await loopControl(request, assistantParts, loopNum);
30777
+ if (!continueLoop) {
30778
+ break;
30779
+ }
30780
+ const toolUses = assistantParts.filter((s) => s.type == "tool-call");
30781
+ const toolResults = await toolCallCallback(request, toolUses);
30782
+ if (toolResults.length > 0) {
30783
+ request.messages.push({
30784
+ role: "tool",
30785
+ content: toolResults.map((result, index) => ({
30786
+ type: "tool-result",
30787
+ toolCallId: toolUses[index].toolCallId,
30788
+ toolName: toolUses[index].toolName,
30789
+ output: result,
30790
+ })),
30791
+ });
30792
+ }
30793
+ loopNum++;
30794
+ }
30795
+ return assistantParts;
30796
+ }
30797
+ async function callLLM(rlm, request, streamCallback, errorHandler, finishHandler, retryNum = 0) {
30798
+ let streamText = "";
30799
+ let thinkText = "";
30800
+ let toolArgsText = "";
30801
+ let textStreamId = uuidv4();
30802
+ let thinkStreamId = uuidv4();
30803
+ let textStreamDone = false;
30804
+ const toolParts = [];
30805
+ let reader = null;
30806
+ try {
30807
+ const result = await rlm.callStream(request);
30808
+ reader = result.stream.getReader();
30809
+ let toolPart = null;
30810
+ while (true) {
30811
+ const { done, value } = await reader.read();
30812
+ if (done) {
30813
+ break;
30814
+ }
30815
+ const chunk = value;
30816
+ switch (chunk.type) {
30817
+ case "text-start": {
30818
+ textStreamId = uuidv4();
30819
+ break;
30820
+ }
30821
+ case "text-delta": {
30822
+ if (toolPart && !chunk.delta) {
30823
+ continue;
30824
+ }
30825
+ streamText += chunk.delta || "";
30826
+ await streamCallback?.({
30827
+ type: "text",
30828
+ streamId: textStreamId,
30829
+ streamDone: false,
30830
+ text: streamText,
30831
+ });
30832
+ if (toolPart) {
30833
+ await streamCallback?.({
30834
+ type: "tool_use",
30835
+ toolCallId: toolPart.toolCallId,
30836
+ toolName: toolPart.toolName,
30837
+ params: toolPart.input || {},
30838
+ });
30839
+ toolPart = null;
30840
+ }
30841
+ break;
30842
+ }
30843
+ case "text-end": {
30844
+ textStreamDone = true;
30845
+ if (streamText) {
30846
+ await streamCallback?.({
30847
+ type: "text",
30848
+ streamId: textStreamId,
30849
+ streamDone: true,
30850
+ text: streamText,
30851
+ });
30852
+ }
30853
+ break;
30854
+ }
30855
+ case "reasoning-start": {
30856
+ thinkStreamId = uuidv4();
30857
+ break;
30858
+ }
30859
+ case "reasoning-delta": {
30860
+ thinkText += chunk.delta || "";
30861
+ await streamCallback?.({
30862
+ type: "thinking",
30863
+ streamId: thinkStreamId,
30864
+ streamDone: false,
30865
+ text: thinkText,
30866
+ });
30867
+ break;
30868
+ }
30869
+ case "reasoning-end": {
30870
+ if (thinkText) {
30871
+ await streamCallback?.({
30872
+ type: "thinking",
30873
+ streamId: thinkStreamId,
30874
+ streamDone: true,
30875
+ text: thinkText,
30876
+ });
30877
+ }
30878
+ break;
30879
+ }
30880
+ case "tool-input-start": {
30881
+ if (toolPart && toolPart.toolCallId == chunk.id) {
30882
+ toolPart.toolName = chunk.toolName;
30883
+ }
30884
+ else {
30885
+ const _toolPart = toolParts.filter((s) => s.toolCallId == chunk.id)[0];
30886
+ if (_toolPart) {
30887
+ toolPart = _toolPart;
30888
+ toolPart.toolName = _toolPart.toolName || chunk.toolName;
30889
+ toolPart.input = _toolPart.input || {};
30890
+ }
30891
+ else {
30892
+ toolPart = {
30893
+ type: "tool-call",
30894
+ toolCallId: chunk.id,
30895
+ toolName: chunk.toolName,
30896
+ input: {},
30897
+ };
30898
+ toolParts.push(toolPart);
30899
+ }
30900
+ }
30901
+ break;
30902
+ }
30903
+ case "tool-input-delta": {
30904
+ if (!textStreamDone) {
30905
+ textStreamDone = true;
30906
+ await streamCallback?.({
30907
+ type: "text",
30908
+ streamId: textStreamId,
30909
+ streamDone: true,
30910
+ text: streamText,
30911
+ });
30912
+ }
30913
+ toolArgsText += chunk.delta || "";
30914
+ await streamCallback?.({
30915
+ type: "tool_streaming",
30916
+ toolCallId: chunk.id,
30917
+ toolName: toolPart?.toolName || "",
30918
+ paramsText: toolArgsText,
30919
+ });
30920
+ break;
30921
+ }
30922
+ case "tool-call": {
30923
+ toolArgsText = "";
30924
+ const args = chunk.input ? JSON.parse(chunk.input) : {};
30925
+ const message = {
30926
+ type: "tool_use",
30927
+ toolCallId: chunk.toolCallId,
30928
+ toolName: chunk.toolName,
30929
+ params: args,
30930
+ };
30931
+ await streamCallback?.(message);
30932
+ if (toolPart == null) {
30933
+ const _toolPart = toolParts.filter((s) => s.toolCallId == chunk.toolCallId)[0];
30934
+ if (_toolPart) {
30935
+ _toolPart.input = message.params || args;
30936
+ }
30937
+ else {
30938
+ toolParts.push({
30939
+ type: "tool-call",
30940
+ toolCallId: chunk.toolCallId,
30941
+ toolName: chunk.toolName,
30942
+ input: message.params || args,
30943
+ });
30944
+ }
30945
+ }
30946
+ else {
30947
+ toolPart.input = message.params || args;
30948
+ toolPart = null;
30949
+ }
30950
+ break;
30951
+ }
30952
+ case "file": {
30953
+ await streamCallback?.({
30954
+ type: "file",
30955
+ mimeType: chunk.mediaType,
30956
+ data: chunk.data,
30957
+ });
30958
+ break;
30959
+ }
30960
+ case "error": {
30961
+ Log.error(`chatLLM error: `, chunk);
30962
+ await streamCallback?.({
30963
+ type: "error",
30964
+ error: chunk.error,
30965
+ });
30966
+ throw new Error("LLM Error: " + chunk.error);
30967
+ }
30968
+ case "finish": {
30969
+ if (!textStreamDone) {
30970
+ textStreamDone = true;
30971
+ await streamCallback?.({
30972
+ type: "text",
30973
+ streamId: textStreamId,
30974
+ streamDone: true,
30975
+ text: streamText,
30976
+ });
30977
+ }
30978
+ if (toolPart) {
30979
+ await streamCallback?.({
30980
+ type: "tool_use",
30981
+ toolCallId: toolPart.toolCallId,
30982
+ toolName: toolPart.toolName,
30983
+ params: toolPart.input || {},
30984
+ });
30985
+ toolPart = null;
30986
+ }
30987
+ if (finishHandler) {
30988
+ const type = await finishHandler(request, chunk.finishReason, chunk, retryNum);
30989
+ if (type == "retry") {
30990
+ await sleep(200 * (retryNum + 1) * (retryNum + 1));
30991
+ return callLLM(rlm, request, streamCallback, errorHandler, finishHandler, ++retryNum);
30992
+ }
30993
+ }
30994
+ await streamCallback?.({
30995
+ type: "finish",
30996
+ finishReason: chunk.finishReason,
30997
+ usage: {
30998
+ promptTokens: chunk.usage.inputTokens || 0,
30999
+ completionTokens: chunk.usage.outputTokens || 0,
31000
+ totalTokens: chunk.usage.totalTokens ||
31001
+ (chunk.usage.inputTokens || 0) +
31002
+ (chunk.usage.outputTokens || 0),
31003
+ },
31004
+ });
31005
+ break;
31006
+ }
31007
+ }
31008
+ }
31009
+ }
31010
+ catch (e) {
31011
+ if (retryNum < config$1.maxRetryNum) {
31012
+ await sleep(200 * (retryNum + 1) * (retryNum + 1));
31013
+ if (errorHandler) {
31014
+ await errorHandler(request, e, retryNum);
31015
+ }
31016
+ return callLLM(rlm, request, streamCallback, errorHandler, finishHandler, ++retryNum);
31017
+ }
31018
+ throw e;
31019
+ }
31020
+ finally {
31021
+ reader && reader.releaseLock();
31022
+ }
31023
+ return streamText
31024
+ ? [
31025
+ { type: "text", text: streamText },
31026
+ ...toolParts,
31027
+ ]
31028
+ : toolParts;
31029
+ }
31030
+
31005
31031
  const global = {
31006
31032
  chatMap: new Map(),
31007
31033
  taskMap: new Map(),
31008
31034
  prompts: new Map(),
31009
31035
  };
31010
31036
 
31011
- const GlobalPromptKey = {
31012
- planner_system: "planner_system",
31013
- planner_example: "planner_example",
31014
- planner_user: "planner_user",
31015
- agent_system: "agent_system",
31016
- chat_system: "chat_system",
31017
- webpage_qa_prompt: "webpage_qa_prompt",
31018
- deep_action_description: "deep_action_description",
31019
- deep_action_param_task_description: "deep_action_param_task_description",
31020
- };
31037
+ var GlobalPromptKey;
31038
+ (function (GlobalPromptKey) {
31039
+ GlobalPromptKey["planner_system"] = "planner_system";
31040
+ GlobalPromptKey["planner_example"] = "planner_example";
31041
+ GlobalPromptKey["planner_user"] = "planner_user";
31042
+ GlobalPromptKey["agent_system"] = "agent_system";
31043
+ GlobalPromptKey["chat_system"] = "chat_system";
31044
+ GlobalPromptKey["webpage_qa_prompt"] = "webpage_qa_prompt";
31045
+ GlobalPromptKey["deep_action_description"] = "deep_action_description";
31046
+ GlobalPromptKey["deep_action_param_task_description"] = "deep_action_param_task_description";
31047
+ })(GlobalPromptKey || (GlobalPromptKey = {}));
31021
31048
 
31022
31049
  class PromptTemplate {
31023
31050
  /**
@@ -33080,7 +33107,7 @@ class Agent {
33080
33107
  }
33081
33108
  await this.handleMessages(agentContext, messages, tools);
33082
33109
  const llm_tools = convertTools(agentTools);
33083
- const results = await callAgentLLM(agentContext, rlm, messages, llm_tools, false, undefined, 0, this.callback, this.requestHandler);
33110
+ const results = await callAgentLLM(agentContext, rlm, messages, llm_tools, false, undefined, this.callback, this.requestHandler);
33084
33111
  const forceStop = agentContext.variables.get("forceStop");
33085
33112
  if (forceStop) {
33086
33113
  return forceStop;
@@ -33352,123 +33379,344 @@ class Agent {
33352
33379
  }
33353
33380
  }
33354
33381
 
33355
- function extract_page_content(max_url_length = 200, max_content_length = 50000) {
33356
- let result = "";
33357
- max_url_length = max_url_length || 200;
33358
- try {
33359
- function traverse(node) {
33360
- if (node.nodeType === Node.ELEMENT_NODE) {
33361
- const tagName = node.tagName.toLowerCase();
33362
- if (["script", "style", "noscript"].includes(tagName)) {
33363
- return;
33382
+ function extract_page_content(params) {
33383
+ params = params || {};
33384
+ const IGNORED_TAGS = new Set(params.ignored_tags || ["script", "style", "noscript", "svg", "canvas"]);
33385
+ const FORM_TAGS = new Set(["input", "select", "textarea"]);
33386
+ const KEY_ATTRIBUTES = new Set(params.key_attributes || [
33387
+ "id",
33388
+ "title",
33389
+ "name",
33390
+ "alt",
33391
+ "src",
33392
+ "url",
33393
+ "href",
33394
+ "value",
33395
+ "checked",
33396
+ "selected",
33397
+ ]);
33398
+ const urlLimit = params.max_url_length || 200;
33399
+ const contentLimit = params.max_content_length || 50000;
33400
+ const minImageArea = params.min_image_area || 1600;
33401
+ const parts = [];
33402
+ let currentLength = 0;
33403
+ const escapeHtml = (text) => {
33404
+ const map = {
33405
+ "<": "&lt;",
33406
+ ">": "&gt;",
33407
+ };
33408
+ return text.replace(/[<>]/g, (m) => map[m] || m);
33409
+ };
33410
+ const getKeyAttributes = (element) => {
33411
+ const attrs = {};
33412
+ const attributes = element.attributes;
33413
+ for (let i = 0; i < attributes.length; i++) {
33414
+ const attr = attributes[i];
33415
+ const name = attr.name.toLowerCase();
33416
+ if (KEY_ATTRIBUTES.has(name)) {
33417
+ const value = attr.value?.trim();
33418
+ if (value) {
33419
+ attrs[name] = value;
33364
33420
  }
33365
- const style = window.getComputedStyle(node);
33366
- if (style.display == "none" ||
33367
- style.visibility == "hidden" ||
33368
- style.opacity == "0") {
33369
- return;
33421
+ }
33422
+ }
33423
+ if (element instanceof HTMLInputElement) {
33424
+ const inputType = element.type.toLowerCase();
33425
+ if (inputType === "checkbox" || inputType === "radio") {
33426
+ if (element.checked) {
33427
+ attrs.checked = "true";
33370
33428
  }
33371
33429
  }
33372
- if (node.nodeType === Node.TEXT_NODE) {
33373
- // text
33374
- const text = node.textContent.trim();
33375
- if (text) {
33376
- result += text + " ";
33377
- }
33378
- }
33379
- else if (node.nodeType === Node.ELEMENT_NODE) {
33380
- const tagName = node.tagName.toLowerCase();
33381
- if (["input", "select", "textarea"].includes(tagName)) {
33382
- // input / select / textarea
33383
- if (tagName == "input" && node.type == "checkbox") {
33384
- result += node.checked + " ";
33385
- }
33386
- else if (tagName == "input" && node.type == "radio") {
33387
- if (node.checked && node.value) {
33388
- result += node.value + " ";
33389
- }
33390
- }
33391
- else if (node.value) {
33392
- result += node.value + " ";
33430
+ if (element.value && !attrs.value) {
33431
+ attrs.value = element.value;
33432
+ }
33433
+ if (element.name && !attrs.name) {
33434
+ attrs.name = element.name;
33435
+ }
33436
+ if (attrs.value || Object.keys(attrs).length > 0) {
33437
+ attrs.type = inputType;
33438
+ }
33439
+ }
33440
+ else if (element instanceof HTMLSelectElement) {
33441
+ if (element.selectedIndex >= 0) {
33442
+ const selectedOption = element.options[element.selectedIndex];
33443
+ if (selectedOption) {
33444
+ attrs.selected = String(element.selectedIndex);
33445
+ if (selectedOption.value && !attrs.value) {
33446
+ attrs.value = selectedOption.value;
33393
33447
  }
33394
33448
  }
33395
- else if (tagName === "img") {
33396
- // image
33397
- const src = node.src ||
33398
- node.getAttribute("src") ||
33399
- node.getAttribute("data-src");
33400
- const alt = node.alt || node.title || "";
33401
- if (src &&
33402
- src.length <= max_url_length &&
33403
- node.width * node.height >= 10000 &&
33404
- src.startsWith("http")) {
33405
- result += `![${alt ? alt : "image"}](${src.trim()}) `;
33406
- }
33449
+ }
33450
+ if (element.name && !attrs.name) {
33451
+ attrs.name = element.name;
33452
+ }
33453
+ }
33454
+ else if (element instanceof HTMLTextAreaElement) {
33455
+ if (element.value && !attrs.value) {
33456
+ attrs.value = element.value;
33457
+ }
33458
+ if (element.name && !attrs.name) {
33459
+ attrs.name = element.name;
33460
+ }
33461
+ }
33462
+ else if (element instanceof HTMLImageElement) {
33463
+ const src = element.src ||
33464
+ element.getAttribute("src") ||
33465
+ element.getAttribute("data-src");
33466
+ if (src && !attrs.src) {
33467
+ attrs.src = src;
33468
+ }
33469
+ if (element.alt && !attrs.alt) {
33470
+ attrs.alt = element.alt;
33471
+ }
33472
+ }
33473
+ else if (element instanceof HTMLAnchorElement) {
33474
+ if (element.href && !attrs.href) {
33475
+ attrs.href = element.href;
33476
+ }
33477
+ if (element.title && !attrs.title) {
33478
+ attrs.title = element.title;
33479
+ }
33480
+ }
33481
+ else if (element instanceof HTMLVideoElement ||
33482
+ element instanceof HTMLAudioElement) {
33483
+ const src = element.src || element.getAttribute("src");
33484
+ if (src && !attrs.src) {
33485
+ attrs.src = src;
33486
+ }
33487
+ }
33488
+ return attrs;
33489
+ };
33490
+ const buildAttributesString = (attrs) => {
33491
+ if (Object.keys(attrs).length === 0) {
33492
+ return "";
33493
+ }
33494
+ const attrStrings = [];
33495
+ for (const [key, value] of Object.entries(attrs)) {
33496
+ if (value) {
33497
+ attrStrings.push(`${key}="${escapeHtml(value)}"`);
33498
+ }
33499
+ }
33500
+ return attrStrings.length > 0 ? " " + attrStrings.join(" ") : "";
33501
+ };
33502
+ const hasKeyAttributes = (attrs) => {
33503
+ return Object.keys(attrs).length > 0;
33504
+ };
33505
+ const addHtmlContent = (content) => {
33506
+ if (!content || currentLength >= contentLimit) {
33507
+ return false;
33508
+ }
33509
+ const contentLength = content.length;
33510
+ if (currentLength + contentLength > contentLimit) {
33511
+ const remaining = contentLimit - currentLength;
33512
+ if (remaining > 0) {
33513
+ parts.push(content.slice(0, remaining));
33514
+ }
33515
+ return false;
33516
+ }
33517
+ currentLength += contentLength;
33518
+ parts.push(content);
33519
+ return true;
33520
+ };
33521
+ const hasDirectTextChild = (node) => {
33522
+ for (const child of node.childNodes) {
33523
+ if (child.nodeType === Node.TEXT_NODE) {
33524
+ const text = child.textContent || "";
33525
+ if (text.trim()) {
33526
+ return true;
33407
33527
  }
33408
- else if (tagName === "a" && node.children.length == 0) {
33409
- // link
33410
- const href = node.href || node.getAttribute("href");
33411
- const text = node.innerText.trim() || node.title;
33412
- if (text &&
33413
- href &&
33414
- href.length <= max_url_length &&
33415
- href.startsWith("http")) {
33416
- result += `[${text}](${href.trim()}) `;
33417
- }
33418
- else {
33419
- result += text + " ";
33528
+ }
33529
+ }
33530
+ return false;
33531
+ };
33532
+ const traverse = (node) => {
33533
+ if (currentLength >= contentLimit) {
33534
+ return "";
33535
+ }
33536
+ if (node.nodeType === Node.TEXT_NODE) {
33537
+ const text = node.textContent || "";
33538
+ const trimmed = text.trim();
33539
+ if (trimmed) {
33540
+ return escapeHtml(trimmed);
33541
+ }
33542
+ return "";
33543
+ }
33544
+ if (node.nodeType !== Node.ELEMENT_NODE) {
33545
+ return "";
33546
+ }
33547
+ const element = node;
33548
+ const tagName = element.tagName.toLowerCase();
33549
+ if (IGNORED_TAGS.has(tagName)) {
33550
+ return "";
33551
+ }
33552
+ try {
33553
+ const style = window.getComputedStyle(element);
33554
+ if (style.display === "none") {
33555
+ return "";
33556
+ }
33557
+ }
33558
+ catch (e) { }
33559
+ const attrs = getKeyAttributes(element);
33560
+ const attrsString = buildAttributesString(attrs);
33561
+ const hasKeyAttrs = hasKeyAttributes(attrs);
33562
+ const hasDirectText = hasDirectTextChild(node);
33563
+ if (FORM_TAGS.has(tagName)) {
33564
+ let value = "";
33565
+ if (tagName === "input") {
33566
+ const input = element;
33567
+ const inputType = input.type.toLowerCase();
33568
+ if (inputType === "checkbox" || inputType === "radio") {
33569
+ if (!input.checked) {
33570
+ return "";
33420
33571
  }
33572
+ value = input.value || String(input.checked);
33421
33573
  }
33422
- else if (tagName === "video" || tagName == "audio") {
33423
- // video / audio
33424
- let src = node.src || node.getAttribute("src");
33425
- const sources = node.querySelectorAll("source");
33426
- if (sources.length > 0 && sources[0].src) {
33427
- src = sources[0].src;
33428
- if (src && src.startsWith("http") && sources[0].type) {
33429
- result += sources[0].type + " ";
33430
- }
33431
- }
33432
- if (src && src.startsWith("http")) {
33433
- result += src.trim() + " ";
33434
- }
33574
+ else if (inputType === "password") {
33575
+ return "";
33435
33576
  }
33436
- else if (tagName === "br") {
33437
- // br
33438
- result += "\n";
33577
+ else {
33578
+ value = input.value || "";
33439
33579
  }
33440
- else if (["p", "div", "h1", "h2", "h3", "h4", "h5", "h6"].includes(tagName)) {
33441
- // block
33442
- result += "\n";
33443
- for (let child of node.childNodes) {
33444
- traverse(child);
33445
- }
33446
- result += "\n";
33447
- return;
33580
+ }
33581
+ else if (tagName === "select") {
33582
+ const select = element;
33583
+ if (select.selectedIndex >= 0) {
33584
+ const selectedOption = select.options[select.selectedIndex];
33585
+ value = selectedOption
33586
+ ? selectedOption.text || selectedOption.value
33587
+ : "";
33448
33588
  }
33449
- else if (tagName === "hr") {
33450
- // hr
33451
- result += "\n--------\n";
33589
+ }
33590
+ else if (tagName === "textarea") {
33591
+ value = element.value || "";
33592
+ }
33593
+ if (value || hasKeyAttrs || tagName === "textarea") {
33594
+ const escapedValue = escapeHtml(value);
33595
+ return `<${tagName}${attrsString}>${escapedValue}</${tagName}>`;
33596
+ }
33597
+ return "";
33598
+ }
33599
+ if (tagName === "img") {
33600
+ const img = element;
33601
+ const src = img.src || img.getAttribute("src") || img.getAttribute("data-src");
33602
+ if (src &&
33603
+ src.length <= urlLimit &&
33604
+ img.width * img.height >= minImageArea &&
33605
+ src.startsWith("http")) {
33606
+ if (!attrs.alt && (img.alt || img.title)) {
33607
+ attrs.alt = img.alt || img.title || "";
33452
33608
  }
33453
- else {
33454
- // recursive
33455
- for (let child of node.childNodes) {
33456
- traverse(child);
33457
- }
33609
+ if (!attrs.src) {
33610
+ attrs.src = src.trim();
33458
33611
  }
33612
+ const imgAttrsString = buildAttributesString(attrs);
33613
+ return `<img${imgAttrsString} />`;
33614
+ }
33615
+ return "";
33616
+ }
33617
+ if (tagName === "a") {
33618
+ const anchor = element;
33619
+ const href = anchor.href || anchor.getAttribute("href");
33620
+ const childContent = [];
33621
+ for (const child of node.childNodes) {
33622
+ const content = traverse(child);
33623
+ if (content) {
33624
+ childContent.push(content);
33625
+ }
33626
+ }
33627
+ const innerContent = childContent.join("");
33628
+ if (!innerContent && !hasKeyAttrs) {
33629
+ return "";
33630
+ }
33631
+ if (href && href.length <= urlLimit && href.startsWith("http")) {
33632
+ if (!attrs.href) {
33633
+ attrs.href = href.trim();
33634
+ }
33635
+ const linkAttrsString = buildAttributesString(attrs);
33636
+ return `<a${linkAttrsString}>${innerContent}</a>`;
33637
+ }
33638
+ else if (hasKeyAttrs || hasDirectText) {
33639
+ return `<a${attrsString}>${innerContent}</a>`;
33640
+ }
33641
+ return innerContent;
33642
+ }
33643
+ if (tagName === "video" || tagName === "audio") {
33644
+ const media = element;
33645
+ let src = media.src || media.getAttribute("src");
33646
+ const sources = element.querySelectorAll("source");
33647
+ if (sources.length > 0 && sources[0].src) {
33648
+ src = sources[0].src;
33649
+ }
33650
+ if (src && src.startsWith("http") && src.length <= urlLimit) {
33651
+ if (!attrs.src) {
33652
+ attrs.src = src.trim();
33653
+ }
33654
+ const mediaAttrsString = buildAttributesString(attrs);
33655
+ return `<${tagName}${mediaAttrsString}></${tagName}>`;
33656
+ }
33657
+ return "";
33658
+ }
33659
+ const childContent = [];
33660
+ for (const child of node.childNodes) {
33661
+ const content = traverse(child);
33662
+ if (content) {
33663
+ childContent.push(content);
33664
+ }
33665
+ }
33666
+ const innerContent = childContent.join("");
33667
+ if (!innerContent) {
33668
+ return "";
33669
+ }
33670
+ if (hasKeyAttrs || hasDirectText) {
33671
+ return `<${tagName}${attrsString}>${innerContent}</${tagName}>`;
33672
+ }
33673
+ return innerContent;
33674
+ };
33675
+ if (!params.root_element) {
33676
+ if (params.root_selector) {
33677
+ params.root_element = document.querySelector(params.root_selector);
33678
+ if (!params.root_element) {
33679
+ return "";
33680
+ }
33681
+ }
33682
+ else {
33683
+ params.root_element = document.body;
33684
+ }
33685
+ }
33686
+ const rootTabName = params.root_element.tagName.toLowerCase();
33687
+ try {
33688
+ if (params.root_element) {
33689
+ const content = traverse(params.root_element);
33690
+ if (content) {
33691
+ addHtmlContent(content);
33459
33692
  }
33460
33693
  }
33461
- traverse(document.body);
33462
33694
  }
33463
33695
  catch (e) {
33464
- result = document.body.innerText;
33696
+ try {
33697
+ const fallbackText = params.root_element.innerText || "";
33698
+ if (fallbackText) {
33699
+ const escaped = escapeHtml(fallbackText);
33700
+ const truncated = escaped.length > contentLimit
33701
+ ? Array.from(escaped).slice(0, contentLimit).join("").trim() + "..."
33702
+ : escaped;
33703
+ return truncated.startsWith(`<${rootTabName}`)
33704
+ ? truncated
33705
+ : `<${rootTabName}>${truncated}</${rootTabName}>`;
33706
+ }
33707
+ return "";
33708
+ }
33709
+ catch {
33710
+ return "";
33711
+ }
33465
33712
  }
33466
- result = result.replace(/\s*\n/g, "\n").replace(/\n+/g, "\n").trim();
33467
- if (result.length > max_content_length) {
33468
- // result = result.slice(0, max_content_length) + "...";
33469
- result = Array.from(result).slice(0, max_content_length).join("") + "...";
33713
+ let result = parts.join("");
33714
+ if (result.length > contentLimit) {
33715
+ result = Array.from(result).slice(0, contentLimit).join("").trim() + "...";
33470
33716
  }
33471
- return result;
33717
+ return result.startsWith(`<${rootTabName}`)
33718
+ ? result
33719
+ : `<${rootTabName}>${result}</${rootTabName}>`;
33472
33720
  }
33473
33721
  function mark_screenshot_highlight_elements(screenshot, area_map, client_rect) {
33474
33722
  return new Promise(async (resolve, reject) => {
@@ -33476,8 +33724,13 @@ function mark_screenshot_highlight_elements(screenshot, area_map, client_rect) {
33476
33724
  const hasOffscreen = typeof OffscreenCanvas !== "undefined";
33477
33725
  const hasCreateImageBitmap = typeof createImageBitmap !== "undefined";
33478
33726
  const hasDOM = typeof document !== "undefined" && typeof Image !== "undefined";
33479
- // @ts-ignore
33480
- const isNode = typeof window === "undefined" && typeof process !== "undefined" && !!process.versions && !!process.versions.node;
33727
+ const isNode = typeof window === "undefined" &&
33728
+ // @ts-ignore
33729
+ typeof process !== "undefined" &&
33730
+ // @ts-ignore
33731
+ !!process.versions &&
33732
+ // @ts-ignore
33733
+ !!process.versions.node;
33481
33734
  const loadImageAny = async () => {
33482
33735
  if (hasCreateImageBitmap) {
33483
33736
  const base64Data = screenshot.imageBase64;
@@ -36307,265 +36560,24 @@ class SimpleHttpMcpClient {
36307
36560
  }
36308
36561
  }
36309
36562
 
36310
- async function callChatLLM(messageId, chatContext, rlm, messages, tools, toolChoice, retryNum = 0, callback, signal) {
36563
+ async function callChatLLM(chatId, messageId, rlm, messages, tools, toolChoice, callback, signal) {
36311
36564
  const streamCallback = callback?.chatCallback || {
36312
36565
  onMessage: async () => { },
36313
36566
  };
36314
36567
  const request = {
36315
- tools: tools,
36568
+ tools,
36569
+ messages,
36316
36570
  toolChoice,
36317
- messages: messages,
36318
36571
  abortSignal: signal,
36319
36572
  };
36320
- let streamText = "";
36321
- let thinkText = "";
36322
- let toolArgsText = "";
36323
- let textStreamId = uuidv4();
36324
- let thinkStreamId = uuidv4();
36325
- let textStreamDone = false;
36326
- const toolParts = [];
36327
- let reader = null;
36328
- try {
36329
- const result = await rlm.callStream(request);
36330
- reader = result.stream.getReader();
36331
- let toolPart = null;
36332
- while (true) {
36333
- const { done, value } = await reader.read();
36334
- if (done) {
36335
- break;
36336
- }
36337
- const chunk = value;
36338
- switch (chunk.type) {
36339
- case "text-start": {
36340
- textStreamId = uuidv4();
36341
- break;
36342
- }
36343
- case "text-delta": {
36344
- if (toolPart && !chunk.delta) {
36345
- continue;
36346
- }
36347
- streamText += chunk.delta || "";
36348
- await streamCallback.onMessage({
36349
- streamType: "chat",
36350
- chatId: chatContext.getChatId(),
36351
- messageId,
36352
- type: "text",
36353
- streamId: textStreamId,
36354
- streamDone: false,
36355
- text: streamText,
36356
- });
36357
- if (toolPart) {
36358
- await streamCallback.onMessage({
36359
- streamType: "chat",
36360
- chatId: chatContext.getChatId(),
36361
- messageId,
36362
- type: "tool_use",
36363
- toolCallId: toolPart.toolCallId,
36364
- toolName: toolPart.toolName,
36365
- params: toolPart.input || {},
36366
- });
36367
- toolPart = null;
36368
- }
36369
- break;
36370
- }
36371
- case "text-end": {
36372
- textStreamDone = true;
36373
- if (streamText) {
36374
- await streamCallback.onMessage({
36375
- streamType: "chat",
36376
- chatId: chatContext.getChatId(),
36377
- messageId,
36378
- type: "text",
36379
- streamId: textStreamId,
36380
- streamDone: true,
36381
- text: streamText,
36382
- });
36383
- }
36384
- break;
36385
- }
36386
- case "reasoning-start": {
36387
- thinkStreamId = uuidv4();
36388
- break;
36389
- }
36390
- case "reasoning-delta": {
36391
- thinkText += chunk.delta || "";
36392
- await streamCallback.onMessage({
36393
- streamType: "chat",
36394
- chatId: chatContext.getChatId(),
36395
- messageId,
36396
- type: "thinking",
36397
- streamId: thinkStreamId,
36398
- streamDone: false,
36399
- text: thinkText,
36400
- });
36401
- break;
36402
- }
36403
- case "reasoning-end": {
36404
- if (thinkText) {
36405
- await streamCallback.onMessage({
36406
- streamType: "chat",
36407
- chatId: chatContext.getChatId(),
36408
- messageId,
36409
- type: "thinking",
36410
- streamId: thinkStreamId,
36411
- streamDone: true,
36412
- text: thinkText,
36413
- });
36414
- }
36415
- break;
36416
- }
36417
- case "tool-input-start": {
36418
- if (toolPart && toolPart.toolCallId == chunk.id) {
36419
- toolPart.toolName = chunk.toolName;
36420
- }
36421
- else {
36422
- const _toolPart = toolParts.filter((s) => s.toolCallId == chunk.id)[0];
36423
- if (_toolPart) {
36424
- toolPart = _toolPart;
36425
- toolPart.toolName = _toolPart.toolName || chunk.toolName;
36426
- toolPart.input = _toolPart.input || {};
36427
- }
36428
- else {
36429
- toolPart = {
36430
- type: "tool-call",
36431
- toolCallId: chunk.id,
36432
- toolName: chunk.toolName,
36433
- input: {},
36434
- };
36435
- toolParts.push(toolPart);
36436
- }
36437
- }
36438
- break;
36439
- }
36440
- case "tool-input-delta": {
36441
- if (!textStreamDone) {
36442
- textStreamDone = true;
36443
- await streamCallback.onMessage({
36444
- streamType: "chat",
36445
- chatId: chatContext.getChatId(),
36446
- messageId,
36447
- type: "text",
36448
- streamId: textStreamId,
36449
- streamDone: true,
36450
- text: streamText,
36451
- });
36452
- }
36453
- toolArgsText += chunk.delta || "";
36454
- await streamCallback.onMessage({
36455
- streamType: "chat",
36456
- chatId: chatContext.getChatId(),
36457
- messageId,
36458
- type: "tool_streaming",
36459
- toolCallId: chunk.id,
36460
- toolName: toolPart?.toolName || "",
36461
- paramsText: toolArgsText,
36462
- });
36463
- break;
36464
- }
36465
- case "tool-call": {
36466
- toolArgsText = "";
36467
- const args = chunk.input ? JSON.parse(chunk.input) : {};
36468
- const message = {
36469
- streamType: "chat",
36470
- chatId: chatContext.getChatId(),
36471
- messageId,
36472
- type: "tool_use",
36473
- toolCallId: chunk.toolCallId,
36474
- toolName: chunk.toolName,
36475
- params: args,
36476
- };
36477
- await streamCallback.onMessage(message);
36478
- if (toolPart == null) {
36479
- const _toolPart = toolParts.filter((s) => s.toolCallId == chunk.toolCallId)[0];
36480
- if (_toolPart) {
36481
- _toolPart.input = message.params || args;
36482
- }
36483
- else {
36484
- toolParts.push({
36485
- type: "tool-call",
36486
- toolCallId: chunk.toolCallId,
36487
- toolName: chunk.toolName,
36488
- input: message.params || args,
36489
- });
36490
- }
36491
- }
36492
- else {
36493
- toolPart.input = message.params || args;
36494
- toolPart = null;
36495
- }
36496
- break;
36497
- }
36498
- case "error": {
36499
- Log.error(`chatLLM error: `, chunk);
36500
- await streamCallback.onMessage({
36501
- streamType: "chat",
36502
- chatId: chatContext.getChatId(),
36503
- messageId,
36504
- type: "error",
36505
- error: chunk.error,
36506
- });
36507
- throw new Error("LLM Error: " + chunk.error);
36508
- }
36509
- case "finish": {
36510
- if (!textStreamDone) {
36511
- textStreamDone = true;
36512
- await streamCallback.onMessage({
36513
- streamType: "chat",
36514
- chatId: chatContext.getChatId(),
36515
- messageId,
36516
- type: "text",
36517
- streamId: textStreamId,
36518
- streamDone: true,
36519
- text: streamText,
36520
- });
36521
- }
36522
- if (toolPart) {
36523
- await streamCallback.onMessage({
36524
- streamType: "chat",
36525
- chatId: chatContext.getChatId(),
36526
- messageId,
36527
- type: "tool_use",
36528
- toolCallId: toolPart.toolCallId,
36529
- toolName: toolPart.toolName,
36530
- params: toolPart.input || {},
36531
- });
36532
- toolPart = null;
36533
- }
36534
- await streamCallback.onMessage({
36535
- streamType: "chat",
36536
- chatId: chatContext.getChatId(),
36537
- messageId,
36538
- type: "finish",
36539
- finishReason: chunk.finishReason,
36540
- usage: {
36541
- promptTokens: chunk.usage.inputTokens || 0,
36542
- completionTokens: chunk.usage.outputTokens || 0,
36543
- totalTokens: chunk.usage.totalTokens ||
36544
- (chunk.usage.inputTokens || 0) +
36545
- (chunk.usage.outputTokens || 0),
36546
- },
36547
- });
36548
- break;
36549
- }
36550
- }
36551
- }
36552
- }
36553
- catch (e) {
36554
- if (retryNum < config$1.maxRetryNum) {
36555
- await sleep(200 * (retryNum + 1) * (retryNum + 1));
36556
- return callChatLLM(messageId, chatContext, rlm, messages, tools, toolChoice, ++retryNum, callback, signal);
36557
- }
36558
- throw e;
36559
- }
36560
- finally {
36561
- reader && reader.releaseLock();
36562
- }
36563
- return streamText
36564
- ? [
36565
- { type: "text", text: streamText },
36566
- ...toolParts,
36567
- ]
36568
- : toolParts;
36573
+ return await callLLM(rlm, request, async (message) => {
36574
+ await streamCallback.onMessage({
36575
+ streamType: "chat",
36576
+ chatId,
36577
+ messageId,
36578
+ ...message,
36579
+ });
36580
+ });
36569
36581
  }
36570
36582
  function convertAssistantToolResults(results) {
36571
36583
  return results.map((part) => {
@@ -36925,6 +36937,7 @@ class DeepActionTool {
36925
36937
  });
36926
36938
  const taskWebsite = await this.gettaskWebsite(tabIds);
36927
36939
  const workflow = await eko.generate(taskDescription, messageId, {
36940
+ ...(this.params.extra || {}),
36928
36941
  ...globalVariables,
36929
36942
  tabIds: tabIds,
36930
36943
  language: language,
@@ -37168,7 +37181,7 @@ class ChatAgent {
37168
37181
  const rlm = new RetryLanguageModel(config.llms, config.chatLlms);
37169
37182
  for (; reactLoopNum < 15; reactLoopNum++) {
37170
37183
  const messages = this.memory.buildMessages();
37171
- const results = await callChatLLM(params.messageId, this.chatContext, rlm, messages, convertTools(chatTools), undefined, 0, params.callback, params.signal);
37184
+ const results = await callChatLLM(this.chatContext.getChatId(), params.messageId, rlm, messages, convertTools(chatTools), undefined, params.callback, params.signal);
37172
37185
  const finalResult = await this.handleCallResult(params.messageId, chatTools, results, params.callback);
37173
37186
  if (finalResult) {
37174
37187
  return finalResult;
@@ -37358,5 +37371,5 @@ class ChatAgent {
37358
37371
  }
37359
37372
  }
37360
37373
 
37361
- export { Agent, AgentChain, AgentContext, BaseBrowserAgent, BaseBrowserLabelsAgent, BaseBrowserScreenAgent, Chain, ChatAgent, ChatContext, TaskContext as Context, DeepActionTool, Eko, EkoMemory, ForeachTaskTool, HumanInteractTool, Log, Planner, PromptTemplate, RetryLanguageModel, SimpleHttpMcpClient, SimpleSseMcpClient, TaskContext, TaskNodeStatusTool, TaskVariableStorageTool, VariableStorageTool, WatchTriggerTool, WebSearchTool, WebpageQaTool, buildAgentTree, buildSimpleAgentWorkflow, call_timeout, compressImageData, config$1 as config, convertToolSchema, Eko as default, extract_page_content, global, mergeTools, parseWorkflow, resetWorkflowXml, sub, toFile, toImage, uuidv4 };
37374
+ export { Agent, AgentChain, AgentContext, BaseBrowserAgent, BaseBrowserLabelsAgent, BaseBrowserScreenAgent, Chain, ChatAgent, ChatContext, TaskContext as Context, DeepActionTool, Eko, EkoMemory, ForeachTaskTool, HumanInteractTool, Log, Planner, PromptTemplate, RetryLanguageModel, SimpleHttpMcpClient, SimpleSseMcpClient, TaskContext, TaskNodeStatusTool, TaskVariableStorageTool, VariableStorageTool, WatchTriggerTool, WebSearchTool, WebpageQaTool, buildAgentTree, buildSimpleAgentWorkflow, callLLM, callWithReAct, call_timeout, compressImageData, config$1 as config, convertToolSchema, Eko as default, extract_page_content, global, mergeTools, parseWorkflow, resetWorkflowXml, sub, toFile, toImage, uuidv4 };
37362
37375
  //# sourceMappingURL=index.esm.js.map