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
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ClaudeSessionFileAdapter } from './core/session/adapters/claude-session-file-adapter.js';
|
|
2
2
|
import { CodexSessionFileAdapter } from './core/session/adapters/codex-session-file-adapter.js';
|
|
3
3
|
import { GeminiSessionFileAdapter } from './core/session/adapters/gemini-session-file-adapter.js';
|
|
4
|
-
import { ensureDataDirs, resolvePaths,
|
|
4
|
+
import { ensureDataDirs, resolvePaths, getPackageRoot } from './paths.js';
|
|
5
5
|
import { resolveAnthropicConfig } from './agents/resolve.js';
|
|
6
|
-
import { loadDefaults, autoMigrateIfNeeded } from './config-store.js';
|
|
6
|
+
import { loadDefaults, autoMigrateIfNeeded, migrateIdentitiesIfNeeded } from './config-store.js';
|
|
7
7
|
import { CONFIG_SCHEMA_VERSION } from './types.js';
|
|
8
8
|
import { SessionManager } from './core/session/session-manager.js';
|
|
9
9
|
import { ClaudeAgentPlugin } from './agents/claude-runner.js';
|
|
@@ -33,14 +33,53 @@ import { IpcServer } from './ipc.js';
|
|
|
33
33
|
import { logger, setLogLevel } from './utils/logger.js';
|
|
34
34
|
import { writeMain, removeAll, isMainWinner, scanInstances } from './utils/instance-registry.js';
|
|
35
35
|
import { detectDuplicates } from './core/evolagent-registry.js';
|
|
36
|
-
import {
|
|
36
|
+
import { loadKitManifest, cleanEckDebug, invalidateKitCache } from './agents/kit-renderer.js';
|
|
37
|
+
import { initEck } from './eck/init.js';
|
|
37
38
|
import { TriggerManager } from './core/trigger/manager.js';
|
|
38
|
-
import { TriggerScheduler } from './core/trigger/scheduler.js';
|
|
39
|
+
import { TriggerScheduler, calcNextFireAt } from './core/trigger/scheduler.js';
|
|
39
40
|
import { agentTriggersDir } from './paths.js';
|
|
41
|
+
import { isLinkedInstall } from './utils/npm-ops.js';
|
|
40
42
|
import path from 'path';
|
|
41
43
|
import fs from 'fs';
|
|
42
44
|
import os from 'os';
|
|
43
45
|
import crypto from 'crypto';
|
|
46
|
+
import { fileURLToPath } from 'url';
|
|
47
|
+
/** 出站 payload 摘要(用于 channel-out.log) */
|
|
48
|
+
function summarizeOutboundPayload(payload) {
|
|
49
|
+
if (!payload)
|
|
50
|
+
return { kind: 'unknown' };
|
|
51
|
+
const s = { kind: payload.kind };
|
|
52
|
+
switch (payload.kind) {
|
|
53
|
+
case 'activity.batch':
|
|
54
|
+
s.itemCount = payload.items?.length ?? 0;
|
|
55
|
+
s.items = payload.items;
|
|
56
|
+
break;
|
|
57
|
+
case 'result.text':
|
|
58
|
+
s.isFinal = payload.isFinal;
|
|
59
|
+
s.text = payload.text;
|
|
60
|
+
break;
|
|
61
|
+
case 'result.file':
|
|
62
|
+
s.filePath = payload.filePath;
|
|
63
|
+
break;
|
|
64
|
+
case 'system.notice':
|
|
65
|
+
case 'system.error':
|
|
66
|
+
s.subtype = payload.subtype;
|
|
67
|
+
s.text = payload.text;
|
|
68
|
+
break;
|
|
69
|
+
case 'interaction':
|
|
70
|
+
s.interactionId = payload.interaction?.id;
|
|
71
|
+
s.interactionKind = payload.interaction?.kind?.kind;
|
|
72
|
+
break;
|
|
73
|
+
case 'status.started':
|
|
74
|
+
case 'status.completed':
|
|
75
|
+
case 'status.interrupted':
|
|
76
|
+
case 'status.error':
|
|
77
|
+
case 'status.timeout':
|
|
78
|
+
s.metadata = payload.metadata;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
return s;
|
|
82
|
+
}
|
|
44
83
|
/**
|
|
45
84
|
* 通过 adapter.send 发送系统类 payload(system.notice / system.error / 等)。
|
|
46
85
|
*
|
|
@@ -54,6 +93,36 @@ import crypto from 'crypto';
|
|
|
54
93
|
export async function sendSystemPayload(adapter, envelope, payload) {
|
|
55
94
|
await adapter.send(envelope, payload);
|
|
56
95
|
}
|
|
96
|
+
function readEvolclawVersion() {
|
|
97
|
+
try {
|
|
98
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(getPackageRoot(), 'package.json'), 'utf-8'));
|
|
99
|
+
return pkg.version || 'unknown';
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return 'unknown';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function readFastaunVersion() {
|
|
106
|
+
try {
|
|
107
|
+
const url = import.meta.resolve?.('@agentunion/fastaun');
|
|
108
|
+
if (!url)
|
|
109
|
+
return 'unknown';
|
|
110
|
+
let dir = path.dirname(fileURLToPath(url));
|
|
111
|
+
while (dir !== path.dirname(dir)) {
|
|
112
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
113
|
+
if (fs.existsSync(pkgPath)) {
|
|
114
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
115
|
+
if (pkg.name === '@agentunion/fastaun')
|
|
116
|
+
return pkg.version || 'unknown';
|
|
117
|
+
}
|
|
118
|
+
dir = path.dirname(dir);
|
|
119
|
+
}
|
|
120
|
+
return 'unknown';
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return 'unknown';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
57
126
|
async function main() {
|
|
58
127
|
// 过滤飞书 SDK 的 info 日志
|
|
59
128
|
const originalLog = console.log;
|
|
@@ -72,11 +141,9 @@ async function main() {
|
|
|
72
141
|
return;
|
|
73
142
|
originalInfo(...args);
|
|
74
143
|
};
|
|
75
|
-
logger.info(
|
|
144
|
+
logger.info(`EvolClaw v${readEvolclawVersion()} starting... (fastaun v${readFastaunVersion()})`);
|
|
76
145
|
// 确保数据目录存在
|
|
77
146
|
ensureDataDirs();
|
|
78
|
-
// 同步包内 kits/ 到 EVOLCLAW_HOME/kits/(首次启动或升级时)
|
|
79
|
-
syncKitsFromPackage();
|
|
80
147
|
// ── 单实例保护(pre-check + post-write self-check)──
|
|
81
148
|
// pre-check:发现已有活 main 直接退出,避免起任何副作用
|
|
82
149
|
{
|
|
@@ -104,16 +171,20 @@ async function main() {
|
|
|
104
171
|
process.exit(0);
|
|
105
172
|
}
|
|
106
173
|
}
|
|
107
|
-
//
|
|
108
|
-
|
|
174
|
+
// ── 自动迁移 ──
|
|
175
|
+
migrateIdentitiesIfNeeded();
|
|
176
|
+
autoMigrateIfNeeded();
|
|
177
|
+
// ── ECK 运行时初始化 ──
|
|
178
|
+
initEck();
|
|
179
|
+
// 加载 ECK manifest + 清理旧调试文件
|
|
180
|
+
cleanEckDebug();
|
|
181
|
+
loadKitManifest();
|
|
109
182
|
// 加载配置(新结构:defaults.json + per-agent config.json)
|
|
110
183
|
const defaults = loadDefaults() ?? { $schema_version: CONFIG_SCHEMA_VERSION };
|
|
111
184
|
// 应用配置中的日志级别(优先于环境变量)
|
|
112
185
|
// logLevel 现在不在新结构中——若要保留,将来可加 defaults.debug.logLevel
|
|
113
186
|
// 阶段 2c 暂跳过
|
|
114
187
|
const paths = resolvePaths();
|
|
115
|
-
// ── 自动迁移:旧 data/evolclaw.json → 新结构 ──
|
|
116
|
-
autoMigrateIfNeeded();
|
|
117
188
|
// ── EvolAgent Registry:加载 agents/<aid>/config.json ──
|
|
118
189
|
const agentRegistry = new EvolAgentRegistry(paths.agentsDir);
|
|
119
190
|
agentRegistry.loadAll();
|
|
@@ -361,6 +432,49 @@ async function main() {
|
|
|
361
432
|
if (primaryAgentForTrigger?.triggerScheduler && primaryAgentForTrigger?.triggerManager) {
|
|
362
433
|
cmdHandler.setTriggerScheduler(primaryAgentForTrigger.triggerScheduler, primaryAgentForTrigger.triggerManager);
|
|
363
434
|
}
|
|
435
|
+
// Seed default __upgrade-check trigger (daily at random time 3:00~3:59)
|
|
436
|
+
// 用户可通过 /trigger cancel __upgrade-check 永久禁用(不会再自动重建)
|
|
437
|
+
if (!isLinkedInstall() && primaryAgentForTrigger?.triggerManager && primaryAgentForTrigger?.triggerScheduler) {
|
|
438
|
+
const mgr = primaryAgentForTrigger.triggerManager;
|
|
439
|
+
const sched = primaryAgentForTrigger.triggerScheduler;
|
|
440
|
+
const UPGRADE_TRIGGER_NAME = '__upgrade-check';
|
|
441
|
+
if (!mgr.getByName(UPGRADE_TRIGGER_NAME)) {
|
|
442
|
+
// Check history: if user cancelled it before, respect that decision
|
|
443
|
+
const { history } = mgr.listAll();
|
|
444
|
+
const wasCancelled = history.some(h => h.name === UPGRADE_TRIGGER_NAME && h.doneReason === 'cancelled');
|
|
445
|
+
if (!wasCancelled) {
|
|
446
|
+
// Random minute in 3:00~3:59 to avoid all instances hitting registry simultaneously
|
|
447
|
+
const randomMinute = Math.floor(Math.random() * 60);
|
|
448
|
+
const cronExpr = `${randomMinute} 3 * * *`;
|
|
449
|
+
// Use first channel instance as target (command doesn't need real channelId)
|
|
450
|
+
const firstChannel = channelInstances[0]?.adapter?.channelName || 'system';
|
|
451
|
+
const trigger = {
|
|
452
|
+
id: crypto.randomUUID(),
|
|
453
|
+
name: UPGRADE_TRIGGER_NAME,
|
|
454
|
+
scheduleType: 'cron',
|
|
455
|
+
scheduleValue: cronExpr,
|
|
456
|
+
nextFireAt: calcNextFireAt('cron', cronExpr),
|
|
457
|
+
targetChannel: firstChannel,
|
|
458
|
+
targetChannelId: '__system__',
|
|
459
|
+
targetSessionStrategy: 'silent',
|
|
460
|
+
prompt: '检查 evolclaw 是否有新版本可用。执行 `npm view evolclaw version` 获取最新版本,与当前版本(执行 `evolclaw --version`)对比。如果有新版本,执行 /restart 进行升级。如果已是最新版本,无需任何操作。',
|
|
461
|
+
createdByPeerId: '__system__',
|
|
462
|
+
createdByChannel: '__system__',
|
|
463
|
+
fireCount: 0,
|
|
464
|
+
createdAt: Date.now(),
|
|
465
|
+
updatedAt: Date.now(),
|
|
466
|
+
};
|
|
467
|
+
try {
|
|
468
|
+
mgr.register(trigger);
|
|
469
|
+
sched.register(trigger);
|
|
470
|
+
logger.info(`[Trigger] Seeded default trigger: ${UPGRADE_TRIGGER_NAME} (cron ${cronExpr})`);
|
|
471
|
+
}
|
|
472
|
+
catch (e) {
|
|
473
|
+
logger.warn(`[Trigger] Failed to seed ${UPGRADE_TRIGGER_NAME}: ${e}`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
364
478
|
// 默认策略
|
|
365
479
|
const defaultPolicy = {
|
|
366
480
|
canSwitchProject: (chatType, role) => chatType === 'private' ? (role === 'owner' || role === 'admin') : role === 'owner',
|
|
@@ -378,6 +492,12 @@ async function main() {
|
|
|
378
492
|
msgBridge.setAgentRegistry(agentRegistry);
|
|
379
493
|
// ── Channel instance registration (shared by startup and hot-load) ──
|
|
380
494
|
function registerChannelInstance(inst) {
|
|
495
|
+
// 0. 包装 adapter.send,记录所有出站到 channel-out.log
|
|
496
|
+
const originalSend = inst.adapter.send.bind(inst.adapter);
|
|
497
|
+
inst.adapter.send = async (envelope, payload) => {
|
|
498
|
+
logger.channelOut({ channel: inst.adapter.channelName, channelId: envelope.channelId, taskId: envelope.taskId, payload: summarizeOutboundPayload(payload) });
|
|
499
|
+
return originalSend(envelope, payload);
|
|
500
|
+
};
|
|
381
501
|
// 1. 项目路径提供器
|
|
382
502
|
if (inst.onProjectPathRequest && inst.channel.onProjectPathRequest) {
|
|
383
503
|
inst.channel.onProjectPathRequest(async (channelId) => {
|
|
@@ -435,6 +555,10 @@ async function main() {
|
|
|
435
555
|
agent.status = 'running';
|
|
436
556
|
}
|
|
437
557
|
}
|
|
558
|
+
// 写入 ready 信号(核心服务已就绪,channel 连接不阻塞启动判定)
|
|
559
|
+
const readySignalPath = resolvePaths().readySignal;
|
|
560
|
+
fs.writeFileSync(readySignalPath, String(Date.now()));
|
|
561
|
+
logger.info(`✓ Ready signal written: ${readySignalPath}`);
|
|
438
562
|
// ── 连接所有渠道(异步,AUN 等 WebSocket 渠道在后台重连)──
|
|
439
563
|
const connected = await channelLoader.connectAll(channelInstances);
|
|
440
564
|
// 预填充 Feishu 已知 thread_id(重启后避免误判话题创建)
|
|
@@ -631,10 +755,6 @@ async function main() {
|
|
|
631
755
|
logger.error('[Restart] Failed to send restart notification:', e);
|
|
632
756
|
}
|
|
633
757
|
}
|
|
634
|
-
// 写入 ready 信号,供 restart-monitor 检测启动成功
|
|
635
|
-
const readySignalPath = resolvePaths().readySignal;
|
|
636
|
-
fs.writeFileSync(readySignalPath, String(Date.now()));
|
|
637
|
-
logger.info(`✓ Ready signal written: ${readySignalPath}`);
|
|
638
758
|
// IPC server — 供 CLI 查询实时状态 + Agent ctl 指令执行
|
|
639
759
|
const ipcServer = new IpcServer(resolvePaths().socket, () => {
|
|
640
760
|
const channels = {};
|
|
@@ -784,7 +904,8 @@ async function main() {
|
|
|
784
904
|
results.push(`⚠ ${cfg.aid}: ${e?.message || e}`);
|
|
785
905
|
}
|
|
786
906
|
}
|
|
787
|
-
// 重建 channel index
|
|
907
|
+
// 重建 channel index + 清除 kit 缓存
|
|
908
|
+
invalidateKitCache();
|
|
788
909
|
agentRegistry.channelIndex.clear();
|
|
789
910
|
agentRegistry.buildChannelIndex();
|
|
790
911
|
logger.info(`[Resync] Done: ${results.length} agent(s) processed`);
|