evolclaw 2.1.1 → 2.2.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.
Files changed (43) hide show
  1. package/README.md +10 -3
  2. package/data/evolclaw.sample.json +9 -1
  3. package/dist/agents/claude-runner.js +612 -0
  4. package/dist/agents/codex-runner.js +310 -0
  5. package/dist/channels/aun.js +416 -9
  6. package/dist/channels/feishu.js +397 -104
  7. package/dist/channels/wechat.js +84 -2
  8. package/dist/cli.js +427 -126
  9. package/dist/config.js +102 -4
  10. package/dist/core/adapters/claude-session-file-adapter.js +144 -0
  11. package/dist/core/adapters/codex-session-file-adapter.js +196 -0
  12. package/dist/core/agent-loader.js +39 -0
  13. package/dist/core/channel-loader.js +60 -0
  14. package/dist/core/command-handler.js +908 -304
  15. package/dist/core/event-bus.js +32 -0
  16. package/dist/core/ipc-server.js +71 -0
  17. package/dist/core/message-bridge.js +187 -0
  18. package/dist/core/message-processor.js +370 -227
  19. package/dist/core/message-queue.js +153 -29
  20. package/dist/core/permission.js +58 -0
  21. package/dist/core/session-file-adapter.js +7 -0
  22. package/dist/core/session-manager.js +571 -223
  23. package/dist/core/stats-collector.js +86 -0
  24. package/dist/index.js +309 -243
  25. package/dist/paths.js +1 -0
  26. package/dist/utils/error-utils.js +4 -2
  27. package/dist/utils/init-feishu.js +2 -0
  28. package/dist/utils/init-wechat.js +2 -0
  29. package/dist/utils/init.js +285 -53
  30. package/dist/utils/ipc-client.js +36 -0
  31. package/dist/utils/migrate-project.js +122 -0
  32. package/dist/utils/{permission.js → permission-utils.js} +31 -3
  33. package/dist/utils/rich-content-renderer.js +228 -0
  34. package/dist/utils/session-file-health.js +11 -34
  35. package/dist/utils/stream-debouncer.js +122 -0
  36. package/dist/utils/stream-idle-monitor.js +1 -1
  37. package/package.json +3 -1
  38. package/dist/core/agent-runner.js +0 -348
  39. package/dist/core/message-stream.js +0 -59
  40. package/dist/index.js.bak +0 -340
  41. package/dist/utils/markdown-to-feishu.js +0 -94
  42. /package/dist/utils/{platform.js → cross-platform.js} +0 -0
  43. /package/dist/{core → utils}/message-cache.js +0 -0
@@ -0,0 +1,86 @@
1
+ export class StatsCollector {
2
+ events = [];
3
+ startTime;
4
+ HOUR_MS = 3_600_000;
5
+ constructor(eventBus) {
6
+ this.startTime = Date.now();
7
+ // 订阅相关事件
8
+ eventBus.subscribe('message:received', (event) => {
9
+ const e = event;
10
+ this.recordEvent({ type: 'received', timestamp: e.timestamp || Date.now() });
11
+ });
12
+ eventBus.subscribe('message:completed', (event) => {
13
+ const e = event;
14
+ this.recordEvent({ type: 'completed', timestamp: e.timestamp || Date.now(), durationMs: e.durationMs });
15
+ });
16
+ eventBus.subscribe('message:error', (event) => {
17
+ const e = event;
18
+ this.recordEvent({ type: 'error', timestamp: Date.now(), errorType: e.errorType });
19
+ });
20
+ eventBus.subscribe('message:interrupted', (_event) => {
21
+ this.recordEvent({ type: 'interrupted', timestamp: Date.now() });
22
+ });
23
+ eventBus.subscribe('session:safe-mode-entered', (_event) => {
24
+ this.recordEvent({ type: 'safe-mode-entered', timestamp: Date.now() });
25
+ });
26
+ }
27
+ recordEvent(record) {
28
+ this.events.push(record);
29
+ }
30
+ /**
31
+ * 获取统计快照(自动裁剪 >1h 的事件)
32
+ */
33
+ getSnapshot() {
34
+ const now = Date.now();
35
+ const cutoff = now - this.HOUR_MS;
36
+ // 裁剪过期事件
37
+ this.events = this.events.filter(e => e.timestamp >= cutoff);
38
+ // 聚合统计
39
+ let received = 0;
40
+ let completed = 0;
41
+ let errors = 0;
42
+ const errorsByType = {};
43
+ let interrupts = 0;
44
+ let safeModeEntries = 0;
45
+ let totalDuration = 0;
46
+ let durationCount = 0;
47
+ for (const event of this.events) {
48
+ switch (event.type) {
49
+ case 'received':
50
+ received++;
51
+ break;
52
+ case 'completed':
53
+ completed++;
54
+ if (event.durationMs !== undefined) {
55
+ totalDuration += event.durationMs;
56
+ durationCount++;
57
+ }
58
+ break;
59
+ case 'error':
60
+ errors++;
61
+ if (event.errorType) {
62
+ errorsByType[event.errorType] = (errorsByType[event.errorType] || 0) + 1;
63
+ }
64
+ break;
65
+ case 'interrupted':
66
+ interrupts++;
67
+ break;
68
+ case 'safe-mode-entered':
69
+ safeModeEntries++;
70
+ break;
71
+ }
72
+ }
73
+ return {
74
+ uptimeMs: now - this.startTime,
75
+ lastHour: {
76
+ received,
77
+ completed,
78
+ errors,
79
+ errorsByType,
80
+ interrupts,
81
+ safeModeEntries,
82
+ avgResponseMs: durationCount > 0 ? totalDuration / durationCount : 0
83
+ }
84
+ };
85
+ }
86
+ }