@eko-ai/eko 3.0.8 → 3.0.9-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -1
- package/dist/agent/base.d.ts.map +1 -1
- package/dist/agent/browser/utils.d.ts +1 -1
- package/dist/agent/browser/utils.d.ts.map +1 -1
- package/dist/agent/llm.d.ts.map +1 -1
- package/dist/index.cjs.js +106 -20
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +106 -20
- package/dist/index.esm.js.map +1 -1
- package/dist/mcp/http.d.ts.map +1 -1
- package/dist/mcp/sse.d.ts.map +1 -1
- package/dist/memory/index.d.ts +2 -3
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/types/core.types.d.ts +1 -0
- package/dist/types/core.types.d.ts.map +1 -1
- package/dist/types/tools.types.d.ts +1 -0
- package/dist/types/tools.types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,22 @@
|
|
|
15
15
|
|
|
16
16
|
Eko (pronounced like 'echo') is a production-ready JavaScript framework that enables developers to create reliable agents, **from simple commands to complex workflows**. It provides a unified interface for running agents in both **computer and browser environments**.
|
|
17
17
|
|
|
18
|
+
## News
|
|
19
|
+
|
|
20
|
+
- **2025-09:** Eko 3.0 introduces dependency-aware parallel agent execution.
|
|
21
|
+
- **2025-09:** New pause, resume, and interrupt controls with `task_snapshot` workflow recovery.
|
|
22
|
+
- **2025-09:** Monorepo tooling migrated to pnpm for consistent workspace management.
|
|
23
|
+
|
|
24
|
+
## Upgrading to Eko 3.0
|
|
25
|
+
|
|
26
|
+
Follow these steps when moving an existing Eko 2.x project to 3.0:
|
|
27
|
+
|
|
28
|
+
1. Update dependencies with `pnpm up @eko-ai/eko @eko-ai/eko-nodejs @eko-ai/eko-web @eko-ai/eko-extension`.
|
|
29
|
+
2. Regenerate saved workflows or exported plans so they use the v3 schema and dependency graph format.
|
|
30
|
+
3. Clean and reinstall using pnpm (`rm -rf node_modules && pnpm install`), then rebuild any browser or desktop bundles.
|
|
31
|
+
4. Re-run automated demos and update documentation to reflect the new pause/interrupt APIs and parallel agent behavior.
|
|
32
|
+
|
|
33
|
+
|
|
18
34
|
## Framework Comparison
|
|
19
35
|
|
|
20
36
|
| Feature | Eko | Langchain | Browser-use | Dify.ai | Coze |
|
|
@@ -83,6 +99,41 @@ let result = await eko.run("Search for the latest news about Musk, summarize and
|
|
|
83
99
|
$ pnpm install @eko-ai/eko
|
|
84
100
|
```
|
|
85
101
|
|
|
102
|
+
## Example Projects
|
|
103
|
+
|
|
104
|
+
The repository ships with three workspace examples under the `example/` folder. After running the
|
|
105
|
+
core install (`pnpm install`) you can launch any of them with the commands below. Each example
|
|
106
|
+
consumes the local 3.0 packages, so rebuilding the main workspace automatically refreshes them.
|
|
107
|
+
|
|
108
|
+
### Browser Extension (`example/extension`)
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pnpm --filter @eko-ai/eko-extension build
|
|
112
|
+
pnpm --filter @eko-ai/eko-extension-example run build
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Load the generated `example/extension/dist` directory via `chrome://extensions` → Developer Mode →
|
|
116
|
+
Load unpacked. Configure your API key in the extension options before running the automation task.
|
|
117
|
+
|
|
118
|
+
### Node.js Automation (`example/nodejs`)
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pnpm --filter @eko-ai/eko-nodejs-example run build
|
|
122
|
+
pnpm --filter @eko-ai/eko-nodejs-example run playwright # first time only, installs browsers
|
|
123
|
+
OPENAI_API_KEY=... ANTHROPIC_API_KEY=... pnpm --filter @eko-ai/eko-nodejs-example run start
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The Node.js demo drives Playwright through Eko; provide at least one model API key before running it.
|
|
127
|
+
|
|
128
|
+
### Web Login Demo (`example/web`)
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pnpm --filter @eko-ai/eko-web-example run start
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
This starts a React dev server on the default port with a simple login flow that you can automate
|
|
135
|
+
with the browser or web agents.
|
|
136
|
+
|
|
86
137
|
## Use Cases
|
|
87
138
|
|
|
88
139
|
- Browser automation and web scraping
|
|
@@ -116,7 +167,19 @@ Eko can be used in multiple environments:
|
|
|
116
167
|
|
|
117
168
|
[](https://star-history.com/#FellouAI/eko&Date)
|
|
118
169
|
|
|
170
|
+
|
|
171
|
+
## Community Spotlight
|
|
172
|
+
|
|
173
|
+
- **Career Co-Pilot**: https://github.com/wangwangbobo/career_skill_learnig.git
|
|
174
|
+
- **Slides Agent by Eko**: https://github.com/MICAHFANG/slides-agent-by-eko
|
|
175
|
+
- **Universal Sidebar Assistant**: https://github.com/San12341/eko-broser-extension.git
|
|
176
|
+
- **48 Hour Browser Challenge**: https://github.com/MoonIRL/eko
|
|
177
|
+
- **Orbit X Smart Terminal**: https://github.com/Skywang16/OrbitX/tree/main
|
|
178
|
+
- **EkoMeet Recommender**: https://github.com/JasonRobertDestiny/EkoMeet
|
|
179
|
+
- **Vision-Eko Plugin**: https://github.com/dcpwilliam/vision-eko/tree/main/serviceNowPlugin
|
|
180
|
+
- **IC Cafe Platform**: https://cnb.cool/giggle_giraffe/ic-info-wxapp
|
|
181
|
+
- **AI Monitoring Assistant**: https://github.com/yuhoudecheqiancao/eko-ai-monitoring
|
|
182
|
+
|
|
119
183
|
## License
|
|
120
184
|
|
|
121
185
|
Eko is released under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
122
|
-
|
package/dist/agent/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/agent/base.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAa,MAAM,eAAe,CAAC;AACtD,OAAO,OAAO,EAAE,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAOxD,OAAO,EACL,IAAI,EACJ,UAAU,EACV,UAAU,EACV,UAAU,EAEV,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,kBAAkB,CAAC;AAY1B,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF,qBAAa,KAAK;IAChB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,WAAW,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAM;IAC7B,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC;IACjC,SAAS,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IACnC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IACzD,SAAS,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC;IACpD,SAAS,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;gBAE1B,MAAM,EAAE,WAAW;IAUlB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAkB9D,cAAc,CACzB,YAAY,EAAE,YAAY,EAC1B,SAAS,CAAC,EAAE,UAAU,EACtB,WAAW,GAAE,MAAY,EACzB,eAAe,GAAE,qBAA0B,GAC1C,OAAO,CAAC,MAAM,CAAC;cA4FF,gBAAgB,CAC9B,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,qBAAqB,EAC/B,UAAU,EAAE,IAAI,EAAE,EAClB,OAAO,EAAE,KAAK,CAAC,uBAAuB,GAAG,2BAA2B,CAAC,GACpE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/agent/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function extract_page_content(max_url_length?: number): string;
|
|
1
|
+
export declare function extract_page_content(max_url_length?: number, max_content_length?: number): string;
|
|
2
2
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browser/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,cAAc,SAAM,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browser/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,cAAc,SAAM,EAAE,kBAAkB,SAAQ,UAkHpF"}
|
package/dist/agent/llm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/agent/llm.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EACL,IAAI,EACJ,UAAU,EACV,UAAU,EACV,YAAY,EAEZ,aAAa,EACb,cAAc,EAEf,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,yBAAyB,EAEzB,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAE9B,MAAM,kBAAkB,CAAC;AAE1B,wBAAgB,yBAAyB,IAAI,uBAAuB,CAanE;AAED,wBAAgB,6BAA6B,IAAI,uBAAuB,CAYvE;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,IAAI,EAAE,GAAG,YAAY,EAAE,GAC7B,2BAA2B,EAAE,CAQ/B;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,YAAY,EACnD,KAAK,EAAE,CAAC,EAAE,EACV,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,IAAI,CAOV;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,2BAA2B,EACpC,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,qBAAqB,GACnC,6BAA6B,CA8F/B;AAED,wBAAsB,YAAY,CAChC,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,EAAE,2BAA2B,EAAE,EACpC,UAAU,CAAC,EAAE,OAAO,EACpB,UAAU,CAAC,EAAE,yBAAyB,EACtC,QAAQ,GAAE,MAAU,EACpB,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,EACzC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,GAC7C,OAAO,CAAC,KAAK,CAAC,uBAAuB,GAAG,2BAA2B,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/agent/llm.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EACL,IAAI,EACJ,UAAU,EACV,UAAU,EACV,YAAY,EAEZ,aAAa,EACb,cAAc,EAEf,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,yBAAyB,EAEzB,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAE9B,MAAM,kBAAkB,CAAC;AAE1B,wBAAgB,yBAAyB,IAAI,uBAAuB,CAanE;AAED,wBAAgB,6BAA6B,IAAI,uBAAuB,CAYvE;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,IAAI,EAAE,GAAG,YAAY,EAAE,GAC7B,2BAA2B,EAAE,CAQ/B;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,YAAY,EACnD,KAAK,EAAE,CAAC,EAAE,EACV,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,IAAI,CAOV;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,2BAA2B,EACpC,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,qBAAqB,GACnC,6BAA6B,CA8F/B;AAED,wBAAsB,YAAY,CAChC,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,EAAE,2BAA2B,EAAE,EACpC,UAAU,CAAC,EAAE,OAAO,EACpB,UAAU,CAAC,EAAE,yBAAyB,EACtC,QAAQ,GAAE,MAAU,EACpB,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,EACzC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,GAC7C,OAAO,CAAC,KAAK,CAAC,uBAAuB,GAAG,2BAA2B,CAAC,CAAC,CA+VvE;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,CAAC,EAAE,2BAA2B,EAAE,UAqDtC;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,UA2C1C"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -12,8 +12,8 @@ const config$1 = {
|
|
|
12
12
|
maxRetryNum: 3,
|
|
13
13
|
agentParallel: false,
|
|
14
14
|
compressThreshold: 80,
|
|
15
|
-
compressTokensThreshold:
|
|
16
|
-
largeTextLength:
|
|
15
|
+
compressTokensThreshold: 80000,
|
|
16
|
+
largeTextLength: 8000,
|
|
17
17
|
fileTextMaxLength: 20000,
|
|
18
18
|
maxDialogueImgFileNum: 1,
|
|
19
19
|
toolResultMultimodal: true,
|
|
@@ -31398,18 +31398,20 @@ function extractUsedTool(messages, agentTools) {
|
|
|
31398
31398
|
}
|
|
31399
31399
|
return tools;
|
|
31400
31400
|
}
|
|
31401
|
-
async function compressAgentMessages(agentContext,
|
|
31401
|
+
async function compressAgentMessages(agentContext, messages, tools) {
|
|
31402
31402
|
if (messages.length < 5) {
|
|
31403
31403
|
return;
|
|
31404
31404
|
}
|
|
31405
31405
|
try {
|
|
31406
|
-
await doCompressAgentMessages(agentContext,
|
|
31406
|
+
await doCompressAgentMessages(agentContext, messages, tools);
|
|
31407
31407
|
}
|
|
31408
31408
|
catch (e) {
|
|
31409
31409
|
Log.error("Error compressing agent messages:", e);
|
|
31410
31410
|
}
|
|
31411
31411
|
}
|
|
31412
|
-
async function doCompressAgentMessages(agentContext,
|
|
31412
|
+
async function doCompressAgentMessages(agentContext, messages, tools) {
|
|
31413
|
+
const ekoConfig = agentContext.context.config;
|
|
31414
|
+
const rlm = new RetryLanguageModel(ekoConfig.llms, ekoConfig.compressLlms);
|
|
31413
31415
|
// extract used tool
|
|
31414
31416
|
const usedTools = extractUsedTool(messages, tools);
|
|
31415
31417
|
const snapshotTool = new TaskSnapshotTool();
|
|
@@ -31431,6 +31433,7 @@ async function doCompressAgentMessages(agentContext, rlm, messages, tools) {
|
|
|
31431
31433
|
break;
|
|
31432
31434
|
}
|
|
31433
31435
|
}
|
|
31436
|
+
compressLargeContextMessages(newMessages);
|
|
31434
31437
|
newMessages.push({
|
|
31435
31438
|
role: "user",
|
|
31436
31439
|
content: [
|
|
@@ -31477,6 +31480,61 @@ async function doCompressAgentMessages(agentContext, rlm, messages, tools) {
|
|
|
31477
31480
|
content: toolResult.content.filter((s) => s.type == "text"),
|
|
31478
31481
|
});
|
|
31479
31482
|
}
|
|
31483
|
+
function compressLargeContextMessages(messages) {
|
|
31484
|
+
for (let r = 2; r < messages.length; r++) {
|
|
31485
|
+
const message = messages[r];
|
|
31486
|
+
if (message.role == "assistant") {
|
|
31487
|
+
message.content = message.content.map((c) => {
|
|
31488
|
+
if (c.type == "text" && c.text.length > config$1.largeTextLength) {
|
|
31489
|
+
return {
|
|
31490
|
+
...c,
|
|
31491
|
+
text: c.text.substring(0, config$1.largeTextLength) + "...",
|
|
31492
|
+
};
|
|
31493
|
+
}
|
|
31494
|
+
return c;
|
|
31495
|
+
});
|
|
31496
|
+
}
|
|
31497
|
+
else if (message.role == "user") {
|
|
31498
|
+
message.content = message.content.map((c) => {
|
|
31499
|
+
if (c.type == "text" && c.text.length > config$1.largeTextLength) {
|
|
31500
|
+
return {
|
|
31501
|
+
...c,
|
|
31502
|
+
text: c.text.substring(0, config$1.largeTextLength) + "...",
|
|
31503
|
+
};
|
|
31504
|
+
}
|
|
31505
|
+
return c;
|
|
31506
|
+
});
|
|
31507
|
+
}
|
|
31508
|
+
else if (message.role == "tool") {
|
|
31509
|
+
message.content = message.content.map((c) => {
|
|
31510
|
+
if (c.type == "tool-result" && c.output) {
|
|
31511
|
+
const output = c.output;
|
|
31512
|
+
if ((output.type == "text" || output.type == "error-text") &&
|
|
31513
|
+
output.value.length > config$1.largeTextLength) {
|
|
31514
|
+
return {
|
|
31515
|
+
...c,
|
|
31516
|
+
output: {
|
|
31517
|
+
...output,
|
|
31518
|
+
value: output.value.substring(0, config$1.largeTextLength) + "...",
|
|
31519
|
+
},
|
|
31520
|
+
};
|
|
31521
|
+
}
|
|
31522
|
+
else if (output.type == "content") {
|
|
31523
|
+
for (let i = 0; i < output.value.length; i++) {
|
|
31524
|
+
const content = output.value[i];
|
|
31525
|
+
if (content.type == "text" &&
|
|
31526
|
+
content.text.length > config$1.largeTextLength) {
|
|
31527
|
+
content.text =
|
|
31528
|
+
content.text.substring(0, config$1.largeTextLength) + "...";
|
|
31529
|
+
}
|
|
31530
|
+
}
|
|
31531
|
+
}
|
|
31532
|
+
}
|
|
31533
|
+
return c;
|
|
31534
|
+
});
|
|
31535
|
+
}
|
|
31536
|
+
}
|
|
31537
|
+
}
|
|
31480
31538
|
function handleLargeContextMessages(messages) {
|
|
31481
31539
|
let imageNum = 0;
|
|
31482
31540
|
let fileNum = 0;
|
|
@@ -31699,7 +31757,7 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
|
|
|
31699
31757
|
if (!noCompress &&
|
|
31700
31758
|
(messages.length >= config$1.compressThreshold || (messages.length >= 10 && estimatePromptTokens(messages, tools) >= config$1.compressTokensThreshold))) {
|
|
31701
31759
|
// Compress messages
|
|
31702
|
-
await compressAgentMessages(agentContext,
|
|
31760
|
+
await compressAgentMessages(agentContext, messages, tools);
|
|
31703
31761
|
}
|
|
31704
31762
|
if (!toolChoice) {
|
|
31705
31763
|
// Append user dialogue
|
|
@@ -31956,7 +32014,7 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
|
|
|
31956
32014
|
messages.length >= 5 &&
|
|
31957
32015
|
!noCompress &&
|
|
31958
32016
|
retryNum < config$1.maxRetryNum) {
|
|
31959
|
-
await compressAgentMessages(agentContext,
|
|
32017
|
+
await compressAgentMessages(agentContext, messages, tools);
|
|
31960
32018
|
return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
|
|
31961
32019
|
}
|
|
31962
32020
|
break;
|
|
@@ -31969,7 +32027,7 @@ async function callAgentLLM(agentContext, rlm, messages, tools, noCompress, tool
|
|
|
31969
32027
|
if (retryNum < config$1.maxRetryNum) {
|
|
31970
32028
|
await sleep(300 * (retryNum + 1) * (retryNum + 1));
|
|
31971
32029
|
if ((e + "").indexOf("is too long") > -1) {
|
|
31972
|
-
await compressAgentMessages(agentContext,
|
|
32030
|
+
await compressAgentMessages(agentContext, messages, tools);
|
|
31973
32031
|
}
|
|
31974
32032
|
return callAgentLLM(agentContext, rlm, messages, tools, noCompress, toolChoice, ++retryNum, streamCallback);
|
|
31975
32033
|
}
|
|
@@ -34261,7 +34319,10 @@ class SimpleSseMcpClient {
|
|
|
34261
34319
|
version: "1.0.0",
|
|
34262
34320
|
},
|
|
34263
34321
|
});
|
|
34264
|
-
|
|
34322
|
+
try {
|
|
34323
|
+
await this.request("notifications/initialized", {});
|
|
34324
|
+
}
|
|
34325
|
+
catch (ignored) { }
|
|
34265
34326
|
}
|
|
34266
34327
|
ping() {
|
|
34267
34328
|
this.request("ping", {});
|
|
@@ -34279,7 +34340,7 @@ class SimpleSseMcpClient {
|
|
|
34279
34340
|
return message.result;
|
|
34280
34341
|
}
|
|
34281
34342
|
async request(method, params, signal) {
|
|
34282
|
-
const id = uuidv4();
|
|
34343
|
+
const id = method.startsWith("notifications/") ? undefined : uuidv4();
|
|
34283
34344
|
try {
|
|
34284
34345
|
const callback = new Promise((resolve, reject) => {
|
|
34285
34346
|
if (signal) {
|
|
@@ -34289,7 +34350,7 @@ class SimpleSseMcpClient {
|
|
|
34289
34350
|
reject(error);
|
|
34290
34351
|
});
|
|
34291
34352
|
}
|
|
34292
|
-
this.requestMap.set(id, resolve);
|
|
34353
|
+
id && this.requestMap.set(id, resolve);
|
|
34293
34354
|
});
|
|
34294
34355
|
Log.debug(`MCP Client, ${method}`, id, params);
|
|
34295
34356
|
const response = await fetch(this.msgUrl, {
|
|
@@ -34336,7 +34397,7 @@ class SimpleSseMcpClient {
|
|
|
34336
34397
|
}
|
|
34337
34398
|
}
|
|
34338
34399
|
finally {
|
|
34339
|
-
this.requestMap.delete(id);
|
|
34400
|
+
id && this.requestMap.delete(id);
|
|
34340
34401
|
}
|
|
34341
34402
|
}
|
|
34342
34403
|
isConnected() {
|
|
@@ -34346,6 +34407,13 @@ class SimpleSseMcpClient {
|
|
|
34346
34407
|
return false;
|
|
34347
34408
|
}
|
|
34348
34409
|
async close() {
|
|
34410
|
+
try {
|
|
34411
|
+
await this.request("notifications/cancelled", {
|
|
34412
|
+
requestId: uuidv4(),
|
|
34413
|
+
reason: "User requested cancellation",
|
|
34414
|
+
});
|
|
34415
|
+
}
|
|
34416
|
+
catch (ignored) { }
|
|
34349
34417
|
this.pingTimer && clearInterval(this.pingTimer);
|
|
34350
34418
|
this.reconnectTimer && clearTimeout(this.reconnectTimer);
|
|
34351
34419
|
this.sseHandler && this.sseHandler.close && this.sseHandler.close();
|
|
@@ -34458,6 +34526,12 @@ class SimpleHttpMcpClient {
|
|
|
34458
34526
|
version: "1.0.0",
|
|
34459
34527
|
},
|
|
34460
34528
|
}, signal);
|
|
34529
|
+
if (this.mcpSessionId) {
|
|
34530
|
+
try {
|
|
34531
|
+
await this.request("notifications/initialized", {});
|
|
34532
|
+
}
|
|
34533
|
+
catch (ignored) { }
|
|
34534
|
+
}
|
|
34461
34535
|
this.connected = true;
|
|
34462
34536
|
}
|
|
34463
34537
|
async listTools(param, signal) {
|
|
@@ -34478,16 +34552,19 @@ class SimpleHttpMcpClient {
|
|
|
34478
34552
|
async close() {
|
|
34479
34553
|
this.connected = false;
|
|
34480
34554
|
if (this.mcpSessionId) {
|
|
34481
|
-
|
|
34482
|
-
|
|
34483
|
-
|
|
34484
|
-
|
|
34555
|
+
try {
|
|
34556
|
+
await this.request("notifications/cancelled", {
|
|
34557
|
+
requestId: uuidv4(),
|
|
34558
|
+
reason: "User requested cancellation",
|
|
34559
|
+
});
|
|
34560
|
+
}
|
|
34561
|
+
catch (ignored) { }
|
|
34485
34562
|
this.mcpSessionId = null;
|
|
34486
34563
|
}
|
|
34487
34564
|
}
|
|
34488
34565
|
async request(method, params, signal) {
|
|
34489
34566
|
try {
|
|
34490
|
-
const id = uuidv4();
|
|
34567
|
+
const id = method.startsWith("notifications/") ? undefined : uuidv4();
|
|
34491
34568
|
const extHeaders = {};
|
|
34492
34569
|
if (this.mcpSessionId && method !== "initialize") {
|
|
34493
34570
|
extHeaders["Mcp-Session-Id"] = this.mcpSessionId;
|
|
@@ -34513,6 +34590,9 @@ class SimpleHttpMcpClient {
|
|
|
34513
34590
|
keepalive: true,
|
|
34514
34591
|
signal: signal,
|
|
34515
34592
|
});
|
|
34593
|
+
if (method.startsWith("notifications/")) {
|
|
34594
|
+
return;
|
|
34595
|
+
}
|
|
34516
34596
|
if (method == "initialize") {
|
|
34517
34597
|
this.mcpSessionId =
|
|
34518
34598
|
response.headers.get("Mcp-Session-Id") ||
|
|
@@ -35631,7 +35711,9 @@ class Agent {
|
|
|
35631
35711
|
return results.map((s) => s.text).join("\n\n");
|
|
35632
35712
|
}
|
|
35633
35713
|
const toolCalls = results.filter((s) => s.type == "tool-call");
|
|
35634
|
-
if (toolCalls.length > 1 &&
|
|
35714
|
+
if (toolCalls.length > 1 &&
|
|
35715
|
+
this.canParallelToolCalls(toolCalls) &&
|
|
35716
|
+
toolCalls.every((s) => agentTools.find((t) => t.name == s.toolName)?.supportParallelCalls)) {
|
|
35635
35717
|
const results = await Promise.all(toolCalls.map((toolCall) => this.callToolCall(agentContext, agentTools, toolCall, user_messages)));
|
|
35636
35718
|
for (let i = 0; i < results.length; i++) {
|
|
35637
35719
|
toolResults.push(results[i]);
|
|
@@ -36381,7 +36463,7 @@ This is a computer GUI interface, observe the execution through screenshots, and
|
|
|
36381
36463
|
}
|
|
36382
36464
|
}
|
|
36383
36465
|
|
|
36384
|
-
function extract_page_content(max_url_length = 200) {
|
|
36466
|
+
function extract_page_content(max_url_length = 200, max_content_length = 50000) {
|
|
36385
36467
|
let result = "";
|
|
36386
36468
|
max_url_length = max_url_length || 200;
|
|
36387
36469
|
try {
|
|
@@ -36492,7 +36574,11 @@ function extract_page_content(max_url_length = 200) {
|
|
|
36492
36574
|
catch (e) {
|
|
36493
36575
|
result = document.body.innerText;
|
|
36494
36576
|
}
|
|
36495
|
-
|
|
36577
|
+
result = result.replace(/\s*\n/g, "\n").replace(/\n+/g, "\n").trim();
|
|
36578
|
+
if (result.length > max_content_length) {
|
|
36579
|
+
result = result.slice(0, max_content_length) + "...";
|
|
36580
|
+
}
|
|
36581
|
+
return result;
|
|
36496
36582
|
}
|
|
36497
36583
|
|
|
36498
36584
|
const AGENT_NAME = "Browser";
|