evolclaw 2.1.2 → 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 (42) 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 +567 -205
  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/init-feishu.js +2 -0
  27. package/dist/utils/init-wechat.js +2 -0
  28. package/dist/utils/init.js +285 -53
  29. package/dist/utils/ipc-client.js +36 -0
  30. package/dist/utils/migrate-project.js +122 -0
  31. package/dist/utils/{permission.js → permission-utils.js} +31 -3
  32. package/dist/utils/rich-content-renderer.js +228 -0
  33. package/dist/utils/session-file-health.js +11 -34
  34. package/dist/utils/stream-debouncer.js +122 -0
  35. package/dist/utils/stream-idle-monitor.js +1 -1
  36. package/package.json +3 -1
  37. package/dist/core/agent-runner.js +0 -348
  38. package/dist/core/message-stream.js +0 -59
  39. package/dist/index.js.bak +0 -340
  40. package/dist/utils/markdown-to-feishu.js +0 -94
  41. /package/dist/utils/{platform.js → cross-platform.js} +0 -0
  42. /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
+ }