evolclaw 2.3.0 → 2.5.0
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 +33 -14
- package/dist/agents/claude-runner.js +224 -23
- package/dist/agents/codex-runner.js +2 -8
- package/dist/agents/gemini-runner.js +1 -8
- package/dist/channels/aun.js +492 -82
- package/dist/channels/dingtalk.js +506 -0
- package/dist/channels/feishu.js +31 -231
- package/dist/channels/qqbot.js +391 -0
- package/dist/channels/wechat.js +36 -38
- package/dist/channels/wecom.js +549 -0
- package/dist/cli.js +170 -17
- package/dist/config.js +98 -2
- package/dist/core/command-handler.js +511 -146
- package/dist/core/message/message-bridge.js +10 -6
- package/dist/core/message/message-processor.js +176 -78
- package/dist/core/message/message-queue.js +48 -0
- package/dist/core/message/stream-flusher.js +2 -2
- package/dist/core/session/session-manager.js +25 -3
- package/dist/index.js +55 -21
- package/dist/ipc.js +14 -4
- package/dist/templates/skills.md +64 -0
- package/dist/utils/error-dict.js +63 -0
- package/dist/utils/error-utils.js +156 -56
- package/dist/utils/format.js +32 -0
- package/dist/utils/init-channel.js +734 -8
- package/dist/utils/init.js +33 -2
- package/dist/utils/media-cache.js +2 -0
- package/dist/utils/stats-collector.js +0 -8
- package/package.json +9 -3
package/dist/utils/init.js
CHANGED
|
@@ -434,6 +434,8 @@ export async function cmdInit() {
|
|
|
434
434
|
console.log(' 1. 飞书 (Feishu)');
|
|
435
435
|
console.log(' 2. 微信 (WeChat)');
|
|
436
436
|
console.log(' 3. AUN (AgentUnin.Network)');
|
|
437
|
+
console.log(' 4. 钉钉 (DingTalk)');
|
|
438
|
+
console.log(' 5. QQ 机器人 (QQBot)');
|
|
437
439
|
const channelChoice = (await ask(rl, '请选择 [1]: ')).trim() || '1';
|
|
438
440
|
if (channelChoice === '1') {
|
|
439
441
|
console.log('\n飞书配置方式:');
|
|
@@ -488,11 +490,40 @@ export async function cmdInit() {
|
|
|
488
490
|
config.channels.aun = {
|
|
489
491
|
enabled: true,
|
|
490
492
|
aid: result.aid,
|
|
491
|
-
...(result.gatewayPort && { gatewayPort: result.gatewayPort }),
|
|
492
493
|
};
|
|
493
494
|
channelConfigured = true;
|
|
494
495
|
config.channels.defaultChannel = 'aun';
|
|
495
496
|
}
|
|
497
|
+
else if (channelChoice === '4') {
|
|
498
|
+
const { runDingtalkQrFlowSimple } = await import('./init-channel.js');
|
|
499
|
+
const result = await runDingtalkQrFlowSimple();
|
|
500
|
+
if (!result) {
|
|
501
|
+
console.log('已取消');
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
config.channels.dingtalk = {
|
|
505
|
+
enabled: true,
|
|
506
|
+
clientId: result.clientId,
|
|
507
|
+
clientSecret: result.clientSecret,
|
|
508
|
+
};
|
|
509
|
+
channelConfigured = true;
|
|
510
|
+
config.channels.defaultChannel = 'dingtalk';
|
|
511
|
+
}
|
|
512
|
+
else if (channelChoice === '5') {
|
|
513
|
+
const { runQQBotBindFlowSimple } = await import('./init-channel.js');
|
|
514
|
+
const result = await runQQBotBindFlowSimple();
|
|
515
|
+
if (!result) {
|
|
516
|
+
console.log('已取消');
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
config.channels.qqbot = {
|
|
520
|
+
enabled: true,
|
|
521
|
+
appId: result.appId,
|
|
522
|
+
clientSecret: result.clientSecret,
|
|
523
|
+
};
|
|
524
|
+
channelConfigured = true;
|
|
525
|
+
config.channels.defaultChannel = 'qqbot';
|
|
526
|
+
}
|
|
496
527
|
else {
|
|
497
528
|
console.log(' 无效选择,请重新输入');
|
|
498
529
|
}
|
|
@@ -514,7 +545,7 @@ export async function cmdInit() {
|
|
|
514
545
|
* Returns the user's choice, or null if cancelled.
|
|
515
546
|
*/
|
|
516
547
|
export async function selectInstance(rl, channelType, instances) {
|
|
517
|
-
const typeLabel = channelType === 'feishu' ? '飞书' : channelType === 'wechat' ? '微信' : 'AUN';
|
|
548
|
+
const typeLabel = channelType === 'feishu' ? '飞书' : channelType === 'wechat' ? '微信' : channelType === 'dingtalk' ? '钉钉' : channelType === 'qqbot' ? 'QQ机器人' : 'AUN';
|
|
518
549
|
console.log(`\n发现已有 ${typeLabel} 机器人:`);
|
|
519
550
|
const letters = 'abcdefghijklmnopqrstuvwxyz';
|
|
520
551
|
for (let i = 0; i < instances.length; i++) {
|
|
@@ -24,6 +24,8 @@ const ALLOWED_CDN_HOSTS = new Set([
|
|
|
24
24
|
'novac2c.cdn.weixin.qq.com',
|
|
25
25
|
'open.feishu.cn',
|
|
26
26
|
'internal-api-lark-file.feishu.cn',
|
|
27
|
+
'oapi.dingtalk.com',
|
|
28
|
+
'api.dingtalk.com',
|
|
27
29
|
]);
|
|
28
30
|
/** 私有 IP 段正则(IPv4) */
|
|
29
31
|
const PRIVATE_IP_RE = /^(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.|127\.|0\.|169\.254\.|::1|fc|fd|fe80)/;
|
|
@@ -20,9 +20,6 @@ export class StatsCollector {
|
|
|
20
20
|
eventBus.subscribe('message:interrupted', (_event) => {
|
|
21
21
|
this.recordEvent({ type: 'interrupted', timestamp: Date.now() });
|
|
22
22
|
});
|
|
23
|
-
eventBus.subscribe('session:safe-mode-entered', (_event) => {
|
|
24
|
-
this.recordEvent({ type: 'safe-mode-entered', timestamp: Date.now() });
|
|
25
|
-
});
|
|
26
23
|
eventBus.subscribe('tool:result', (event) => {
|
|
27
24
|
const e = event;
|
|
28
25
|
if (e.isError) {
|
|
@@ -49,7 +46,6 @@ export class StatsCollector {
|
|
|
49
46
|
let toolErrors = 0;
|
|
50
47
|
const toolErrorsByName = {};
|
|
51
48
|
let interrupts = 0;
|
|
52
|
-
let safeModeEntries = 0;
|
|
53
49
|
let totalDuration = 0;
|
|
54
50
|
let durationCount = 0;
|
|
55
51
|
for (const event of this.events) {
|
|
@@ -79,9 +75,6 @@ export class StatsCollector {
|
|
|
79
75
|
case 'interrupted':
|
|
80
76
|
interrupts++;
|
|
81
77
|
break;
|
|
82
|
-
case 'safe-mode-entered':
|
|
83
|
-
safeModeEntries++;
|
|
84
|
-
break;
|
|
85
78
|
}
|
|
86
79
|
}
|
|
87
80
|
return {
|
|
@@ -94,7 +87,6 @@ export class StatsCollector {
|
|
|
94
87
|
toolErrors,
|
|
95
88
|
toolErrorsByName,
|
|
96
89
|
interrupts,
|
|
97
|
-
safeModeEntries,
|
|
98
90
|
avgResponseMs: durationCount > 0 ? totalDuration / durationCount : 0
|
|
99
91
|
}
|
|
100
92
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "evolclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Lightweight AI Agent gateway connecting Claude Agent SDK to messaging channels (Feishu, ACP) with multi-project session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
16
|
"dev": "tsx watch src/index.ts",
|
|
17
|
-
"build": "tsc && node -e \"const f='dist/cli.js',c=require('fs').readFileSync(f,'utf8');if(!c.startsWith('#!'))require('fs').writeFileSync(f,'#!/usr/bin/env node\\n'+c)\" && node -e \"try{require('child_process').execFileSync('chmod',['+x','dist/cli.js'])}catch{}\"",
|
|
17
|
+
"build": "tsc && node -e \"const f='dist/cli.js',c=require('fs').readFileSync(f,'utf8');if(!c.startsWith('#!'))require('fs').writeFileSync(f,'#!/usr/bin/env node\\n'+c)\" && node -e \"try{require('child_process').execFileSync('chmod',['+x','dist/cli.js'])}catch{}\" && node -e \"require('fs').cpSync('src/templates','dist/templates',{recursive:true,force:true})\"",
|
|
18
18
|
"start": "node dist/index.js",
|
|
19
19
|
"test": "vitest run",
|
|
20
20
|
"test:watch": "vitest",
|
|
@@ -23,10 +23,16 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@anthropic-ai/claude-agent-sdk": "^0.2.100",
|
|
26
|
-
"@eleans/aun-core-
|
|
26
|
+
"@eleans/aun-core-sdk": "^0.2.9",
|
|
27
27
|
"@larksuiteoapi/node-sdk": "^1.59.0",
|
|
28
28
|
"@openai/codex-sdk": "^0.118.0",
|
|
29
|
+
"@types/form-data": "^2.2.1",
|
|
30
|
+
"@wecom/aibot-node-sdk": "^1.0.6",
|
|
31
|
+
"dingtalk-stream": "^2.1.6-beta.1",
|
|
32
|
+
"fast-xml-parser": "^5.7.2",
|
|
33
|
+
"form-data": "^4.0.5",
|
|
29
34
|
"image-type": "^6.0.0",
|
|
35
|
+
"pure-qqbot": "^2.0.0",
|
|
30
36
|
"qrcode-terminal": "^0.12.0"
|
|
31
37
|
},
|
|
32
38
|
"devDependencies": {
|