evolclaw 3.0.0 → 3.1.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 +1 -1
- package/bin/ec.js +29 -0
- package/dist/agents/baseagent-normalize.js +19 -0
- package/dist/agents/claude-runner.js +7 -9
- package/dist/agents/codex-runner.js +2 -0
- package/dist/agents/gemini-runner.js +9 -9
- package/dist/agents/kit-renderer.js +281 -0
- package/dist/aun/aid/identity.js +28 -0
- package/dist/aun/aid/index.js +1 -1
- package/dist/aun/aid/lifecycle-log.js +33 -0
- package/dist/aun/msg/group.js +3 -1
- package/dist/aun/msg/p2p.js +4 -1
- package/dist/channels/aun.js +353 -125
- package/dist/channels/dingtalk.js +2 -1
- package/dist/channels/feishu.js +118 -5
- package/dist/channels/qqbot.js +2 -1
- package/dist/channels/wechat.js +3 -1
- package/dist/channels/wecom.js +2 -1
- package/dist/cli/bench.js +1219 -0
- package/dist/cli/index.js +279 -19
- package/dist/cli/link-rules.js +245 -0
- package/dist/cli/net-check.js +640 -0
- package/dist/cli/watch-msg.js +589 -0
- package/dist/config-store.js +37 -5
- package/dist/core/channel-loader.js +23 -10
- package/dist/core/command-handler.js +46 -22
- package/dist/core/evolagent.js +5 -10
- package/dist/core/message/im-renderer.js +50 -44
- package/dist/core/message/items-formatter.js +11 -4
- package/dist/core/message/message-bridge.js +7 -2
- package/dist/core/message/message-log.js +2 -0
- package/dist/core/message/message-processor.js +150 -99
- package/dist/core/message/message-queue.js +10 -3
- package/dist/core/permission.js +95 -3
- package/dist/core/session/session-manager.js +98 -64
- package/dist/core/trigger/scheduler.js +1 -1
- package/dist/data/error-dict.json +118 -0
- package/dist/eck/baseagent-caps.js +18 -0
- package/dist/eck/detect.js +47 -0
- package/dist/eck/init.js +77 -0
- package/dist/eck/rules-loader.js +28 -0
- package/dist/index.js +137 -16
- package/dist/net-check.js +640 -0
- package/dist/paths.js +31 -40
- package/dist/utils/aid-lifecycle-log.js +33 -0
- package/dist/utils/atomic-write.js +10 -0
- package/dist/utils/cross-platform.js +17 -8
- package/dist/utils/error-utils.js +10 -2
- package/dist/utils/instance-registry.js +6 -5
- package/dist/utils/log-writer.js +2 -1
- package/dist/utils/logger.js +10 -0
- package/dist/utils/npm-ops.js +35 -3
- package/dist/utils/process-introspect.js +16 -38
- package/dist/watch-msg.js +26 -11
- package/evolclaw-install-aun.md +14 -2
- package/kits/docs/GUIDE.md +20 -0
- package/kits/docs/INDEX.md +52 -0
- package/kits/docs/aun/CHEATSHEET.md +17 -0
- package/kits/docs/aun/SYNC_PROTOCOL.md +15 -0
- package/kits/docs/channels/feishu.md +27 -0
- package/kits/docs/eck_templates/GUIDE.template.md +22 -0
- package/kits/docs/eck_templates/INDEX.template.md +28 -0
- package/kits/docs/eck_templates/path-registry.template.md +33 -0
- package/kits/docs/eck_templates/runtime.template.md +19 -0
- package/kits/docs/evolclaw/MSG_GROUP.md +30 -0
- package/kits/docs/evolclaw/MSG_PRIVATE.md +25 -0
- package/kits/docs/identity/AID_PROFILE_SPEC.md +27 -0
- package/kits/docs/identity/PATH_OPS.md +16 -0
- package/kits/docs/identity/ROLE_DETAIL.md +20 -0
- package/kits/docs/path-registry.md +43 -0
- package/kits/eck_manifest.json +95 -0
- package/kits/rules/01-overview.md +120 -0
- package/kits/rules/02-navigation.md +75 -0
- package/kits/rules/03-identity.md +34 -0
- package/kits/rules/04-relation.md +49 -0
- package/kits/rules/05-venue.md +45 -0
- package/kits/rules/06-channel.md +43 -0
- package/kits/templates/system-fragments/baseagent.md +2 -0
- package/kits/templates/system-fragments/channel.md +10 -0
- package/kits/templates/system-fragments/identity.md +12 -0
- package/kits/templates/system-fragments/relation.md +9 -0
- package/kits/templates/system-fragments/runtime.md +19 -0
- package/kits/templates/system-fragments/venue.md +5 -0
- package/package.json +7 -5
- package/dist/agents/templates.js +0 -122
- package/dist/data/prompts.md +0 -137
- package/kits/aun/meta.md +0 -25
- package/kits/aun/role.md +0 -25
- package/kits/templates/group.md +0 -20
- package/kits/templates/private.md +0 -9
- package/kits/templates/system-fragments/personal-context.md +0 -3
- package/kits/templates/system-fragments/self-intro.md +0 -5
- package/kits/templates/system-fragments/speaker-intro.md +0 -5
- package/kits/templates/system-fragments/venue-intro.md +0 -5
- /package/kits/{channels → docs/channels}/aun.md +0 -0
- /package/kits/{evolclaw/commands.md → docs/evolclaw/AGENT_CMD.md} +0 -0
- /package/kits/{evolclaw → docs/evolclaw}/self-summary.md +0 -0
- /package/kits/{evolclaw → docs/evolclaw}/tools.md +0 -0
- /package/kits/{evolclaw → docs/identity}/identity-tools.md +0 -0
|
@@ -467,7 +467,8 @@ export class DingtalkChannelPlugin {
|
|
|
467
467
|
await channel.sendImage(channelId, payload.data);
|
|
468
468
|
return;
|
|
469
469
|
case 'activity.batch': {
|
|
470
|
-
const
|
|
470
|
+
const filtered = payload.items.filter((i) => !(i.kind === 'tool_result' && i.ok));
|
|
471
|
+
const text = formatItemsAsText(filtered);
|
|
471
472
|
if (text)
|
|
472
473
|
await channel.sendMessage(channelId, text);
|
|
473
474
|
return;
|
package/dist/channels/feishu.js
CHANGED
|
@@ -82,8 +82,6 @@ export class FeishuChannel {
|
|
|
82
82
|
if (msg.thread_id) {
|
|
83
83
|
logger.info('[Feishu] Thread message, thread_id:', msg.thread_id, 'root_id:', msg.root_id);
|
|
84
84
|
}
|
|
85
|
-
// [DEBUG] 临时:记录所有消息的 root_id/thread_id,用于排查图片回复带引用问题
|
|
86
|
-
logger.info('[Feishu][DEBUG] msg_type:', msg.message_type, 'root_id:', msg.root_id ?? '(empty)', 'thread_id:', msg.thread_id ?? '(empty)', 'parent_id:', msg.parent_id ?? '(empty)');
|
|
87
85
|
// 提取 @ 提及列表(排除机器人自身)
|
|
88
86
|
const mentions = (msg.mentions || []).map((m) => ({
|
|
89
87
|
userId: m.id?.open_id || '',
|
|
@@ -181,6 +179,16 @@ export class FeishuChannel {
|
|
|
181
179
|
quotedText = `> 以下是引用的原消息\n> ================\n> [文件消息]\n> ================\n\n`;
|
|
182
180
|
}
|
|
183
181
|
}
|
|
182
|
+
else if (quotedMsgType === 'merge_forward') {
|
|
183
|
+
const { text: mergedText, images: mergedImages } = await this.extractMergeForwardContent(msg.parent_id, msg.chat_id);
|
|
184
|
+
if (mergedText) {
|
|
185
|
+
quotedText = `> 以下是引用的原消息\n> ================\n> [合并转发消息]\n> ================\n\n${mergedText}\n\n`;
|
|
186
|
+
quotedImages.push(...mergedImages);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
quotedText = `> 以下是引用的原消息\n> ================\n> [合并转发消息]\n> ================\n\n`;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
184
192
|
else {
|
|
185
193
|
quotedText = `> 以下是引用的原消息\n> ================\n> [${quotedMsgType}消息]\n> ================\n\n`;
|
|
186
194
|
}
|
|
@@ -189,6 +197,7 @@ export class FeishuChannel {
|
|
|
189
197
|
logger.warn({ err }, '[Feishu] Failed to fetch quoted message');
|
|
190
198
|
}
|
|
191
199
|
}
|
|
200
|
+
logger.info(`[Feishu] Incoming message_type=${msg.message_type} content=${msg.content?.substring(0, 200)}`);
|
|
192
201
|
// 处理文本消息
|
|
193
202
|
if (msg.message_type === 'text') {
|
|
194
203
|
const parsed = JSON.parse(msg.content);
|
|
@@ -269,6 +278,19 @@ export class FeishuChannel {
|
|
|
269
278
|
const allImages = [...quotedImages, ...postImages];
|
|
270
279
|
await this.messageHandler({ channelId: msg.chat_id, content: finalContent, images: allImages.length > 0 ? allImages : undefined, peerId, peerName, messageId: msg.message_id, threadId, rootId, chatType });
|
|
271
280
|
}
|
|
281
|
+
// 处理合并转发消息
|
|
282
|
+
else if (msg.message_type === 'merge_forward') {
|
|
283
|
+
const { text: mergedText, images: mergedImages } = await this.extractMergeForwardContent(msg.message_id, msg.chat_id);
|
|
284
|
+
if (mergedText) {
|
|
285
|
+
const finalContent = quotedText + mergedText;
|
|
286
|
+
const allImages = [...quotedImages, ...mergedImages];
|
|
287
|
+
await this.messageHandler({ channelId: msg.chat_id, content: finalContent, images: allImages.length > 0 ? allImages : undefined, peerId, peerName, messageId: msg.message_id, threadId, rootId, chatType });
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
const prompt = quotedText + '[合并转发消息解析失败]';
|
|
291
|
+
await this.messageHandler({ channelId: msg.chat_id, content: prompt, images: quotedImages.length > 0 ? quotedImages : undefined, peerId, peerName, messageId: msg.message_id, threadId, rootId, chatType });
|
|
292
|
+
}
|
|
293
|
+
}
|
|
272
294
|
// 处理其他类型消息
|
|
273
295
|
else {
|
|
274
296
|
logger.debug('[Feishu] Unsupported message type:', msg.message_type);
|
|
@@ -802,6 +824,94 @@ export class FeishuChannel {
|
|
|
802
824
|
return null;
|
|
803
825
|
}
|
|
804
826
|
}
|
|
827
|
+
/**
|
|
828
|
+
* 提取合并转发消息的子消息内容。
|
|
829
|
+
* 调用 im.message.get 获取子消息列表,逐条解析 text/image/post/file 类型。
|
|
830
|
+
*/
|
|
831
|
+
async extractMergeForwardContent(messageId, chatId) {
|
|
832
|
+
const empty = { text: '', images: [] };
|
|
833
|
+
if (!this.client)
|
|
834
|
+
return empty;
|
|
835
|
+
try {
|
|
836
|
+
const res = await this.client.im.message.get({
|
|
837
|
+
path: { message_id: messageId }
|
|
838
|
+
});
|
|
839
|
+
const items = res.data?.items;
|
|
840
|
+
if (!items || items.length === 0) {
|
|
841
|
+
logger.warn('[Feishu] merge_forward: no sub-messages found');
|
|
842
|
+
return empty;
|
|
843
|
+
}
|
|
844
|
+
logger.info(`[Feishu] merge_forward: ${items.length} sub-messages`);
|
|
845
|
+
const projectPath = this.projectPathProvider
|
|
846
|
+
? await this.projectPathProvider(chatId)
|
|
847
|
+
: process.cwd();
|
|
848
|
+
const textParts = [];
|
|
849
|
+
const images = [];
|
|
850
|
+
const MAX_IMAGES = 10;
|
|
851
|
+
textParts.push('以下是用户转发的合并消息:\n---');
|
|
852
|
+
for (const item of items) {
|
|
853
|
+
const msgType = item.msg_type;
|
|
854
|
+
const content = item.body?.content;
|
|
855
|
+
if (!content)
|
|
856
|
+
continue;
|
|
857
|
+
try {
|
|
858
|
+
if (msgType === 'text') {
|
|
859
|
+
const parsed = JSON.parse(content);
|
|
860
|
+
textParts.push(parsed.text || '');
|
|
861
|
+
}
|
|
862
|
+
else if (msgType === 'post') {
|
|
863
|
+
const parsed = JSON.parse(content);
|
|
864
|
+
let text = '';
|
|
865
|
+
const postContent = parsed.zh_cn?.content || parsed.en_us?.content || parsed.content;
|
|
866
|
+
if (postContent) {
|
|
867
|
+
for (const line of postContent) {
|
|
868
|
+
for (const elem of line) {
|
|
869
|
+
if (elem.tag === 'img' && elem.image_key && item.message_id && images.length < MAX_IMAGES) {
|
|
870
|
+
const imageData = await this.downloadAndSaveImage(elem.image_key, chatId, item.message_id, projectPath);
|
|
871
|
+
if (imageData)
|
|
872
|
+
images.push(imageData);
|
|
873
|
+
}
|
|
874
|
+
else if (elem.text) {
|
|
875
|
+
text += elem.text;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
text += '\n';
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
const title = parsed.zh_cn?.title || parsed.en_us?.title || parsed.title;
|
|
882
|
+
textParts.push(title ? `${title}\n${text.trim()}` : text.trim());
|
|
883
|
+
}
|
|
884
|
+
else if (msgType === 'image' && item.message_id) {
|
|
885
|
+
const parsed = JSON.parse(content);
|
|
886
|
+
if (parsed.image_key && images.length < MAX_IMAGES) {
|
|
887
|
+
const imageData = await this.downloadAndSaveImage(parsed.image_key, chatId, item.message_id, projectPath);
|
|
888
|
+
if (imageData) {
|
|
889
|
+
images.push(imageData);
|
|
890
|
+
textParts.push('[图片]');
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
else if (msgType === 'file') {
|
|
895
|
+
const parsed = JSON.parse(content);
|
|
896
|
+
textParts.push(`[文件: ${parsed.file_name || 'unknown'}]`);
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
textParts.push(`[${msgType}]`);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
catch (parseErr) {
|
|
903
|
+
logger.debug('[Feishu] merge_forward: failed to parse sub-message:', parseErr);
|
|
904
|
+
textParts.push(`[${msgType}: 解析失败]`);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
textParts.push('---');
|
|
908
|
+
return { text: textParts.join('\n'), images };
|
|
909
|
+
}
|
|
910
|
+
catch (error) {
|
|
911
|
+
logger.error('[Feishu] Failed to extract merge_forward content:', error);
|
|
912
|
+
return empty;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
805
915
|
async downloadFile(fileKey, fileName, messageId, projectPath) {
|
|
806
916
|
if (!this.client)
|
|
807
917
|
return null;
|
|
@@ -1223,7 +1333,7 @@ export class FeishuChannelPlugin {
|
|
|
1223
1333
|
case 'result.error': {
|
|
1224
1334
|
const sendCtx = { ...(ctx ?? {}) };
|
|
1225
1335
|
if (payload.kind === 'result.text' && payload.isFinal)
|
|
1226
|
-
sendCtx.title = '
|
|
1336
|
+
sendCtx.title = '✅ 最终回复:';
|
|
1227
1337
|
await channel.sendMessage(channelId, payload.text, sendCtx);
|
|
1228
1338
|
return;
|
|
1229
1339
|
}
|
|
@@ -1234,9 +1344,12 @@ export class FeishuChannelPlugin {
|
|
|
1234
1344
|
await channel.sendImage(channelId, payload.data, ctx);
|
|
1235
1345
|
return;
|
|
1236
1346
|
case 'activity.batch': {
|
|
1237
|
-
|
|
1238
|
-
|
|
1347
|
+
// Feishu 不发送成功的 tool_result(信息密度低,刷屏)
|
|
1348
|
+
const filtered = payload.items.filter((i) => !(i.kind === 'tool_result' && i.ok));
|
|
1349
|
+
const text = formatItemsAsText(filtered);
|
|
1350
|
+
if (text) {
|
|
1239
1351
|
await channel.sendMessage(channelId, text, ctx);
|
|
1352
|
+
}
|
|
1240
1353
|
return;
|
|
1241
1354
|
}
|
|
1242
1355
|
case 'status.started':
|
package/dist/channels/qqbot.js
CHANGED
|
@@ -354,7 +354,8 @@ export class QQBotChannelPlugin {
|
|
|
354
354
|
await channel.sendImage(channelId, payload.data);
|
|
355
355
|
return;
|
|
356
356
|
case 'activity.batch': {
|
|
357
|
-
const
|
|
357
|
+
const filtered = payload.items.filter((i) => !(i.kind === 'tool_result' && i.ok));
|
|
358
|
+
const text = formatItemsAsText(filtered);
|
|
358
359
|
if (text)
|
|
359
360
|
await channel.sendMessage(channelId, text);
|
|
360
361
|
return;
|
package/dist/channels/wechat.js
CHANGED
|
@@ -750,7 +750,9 @@ export class WechatChannelPlugin {
|
|
|
750
750
|
case 'result.image':
|
|
751
751
|
return;
|
|
752
752
|
case 'activity.batch': {
|
|
753
|
-
|
|
753
|
+
// WeChat 不发送成功的 tool_result
|
|
754
|
+
const filtered = payload.items.filter((i) => !(i.kind === 'tool_result' && i.ok));
|
|
755
|
+
const text = formatItemsAsText(filtered);
|
|
754
756
|
if (text)
|
|
755
757
|
await channel.sendMessage(channelId, text);
|
|
756
758
|
return;
|
package/dist/channels/wecom.js
CHANGED
|
@@ -510,7 +510,8 @@ export class WecomChannelPlugin {
|
|
|
510
510
|
await channel.sendImage(channelId, payload.data);
|
|
511
511
|
return;
|
|
512
512
|
case 'activity.batch': {
|
|
513
|
-
const
|
|
513
|
+
const filtered = payload.items.filter((i) => !(i.kind === 'tool_result' && i.ok));
|
|
514
|
+
const text = formatItemsAsText(filtered);
|
|
514
515
|
if (text)
|
|
515
516
|
await channel.sendMessage(channelId, text);
|
|
516
517
|
return;
|