evolclaw 2.1.2 → 2.3.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 (54) hide show
  1. package/README.md +59 -30
  2. package/data/evolclaw.sample.json +15 -4
  3. package/dist/agents/claude-runner.js +685 -0
  4. package/dist/agents/codex-runner.js +315 -0
  5. package/dist/agents/gemini-runner.js +425 -0
  6. package/dist/channels/aun.js +580 -10
  7. package/dist/channels/feishu.js +888 -135
  8. package/dist/channels/wechat.js +127 -21
  9. package/dist/cli.js +519 -136
  10. package/dist/config.js +277 -25
  11. package/dist/core/agent-loader.js +39 -0
  12. package/dist/core/channel-loader.js +67 -0
  13. package/dist/core/command-handler.js +1537 -392
  14. package/dist/core/event-bus.js +32 -0
  15. package/dist/core/interaction-router.js +68 -0
  16. package/dist/core/message/message-bridge.js +216 -0
  17. package/dist/core/message/message-processor.js +1028 -0
  18. package/dist/core/message/message-queue.js +240 -0
  19. package/dist/core/message/stream-debouncer.js +122 -0
  20. package/dist/{utils → core/message}/stream-flusher.js +73 -13
  21. package/dist/{utils → core/message}/stream-idle-monitor.js +1 -1
  22. package/dist/core/permission.js +259 -0
  23. package/dist/core/session/adapters/claude-session-file-adapter.js +144 -0
  24. package/dist/core/session/adapters/codex-session-file-adapter.js +261 -0
  25. package/dist/core/session/adapters/gemini-session-file-adapter.js +177 -0
  26. package/dist/core/session/session-file-adapter.js +7 -0
  27. package/dist/core/session/session-file-health.js +45 -0
  28. package/dist/core/session/session-manager.js +1072 -0
  29. package/dist/index.js +402 -252
  30. package/dist/ipc.js +106 -0
  31. package/dist/paths.js +1 -0
  32. package/dist/types.js +3 -0
  33. package/dist/utils/{platform.js → cross-platform.js} +38 -1
  34. package/dist/utils/error-utils.js +130 -5
  35. package/dist/utils/init-channel.js +649 -0
  36. package/dist/utils/init.js +190 -53
  37. package/dist/utils/logger.js +8 -3
  38. package/dist/utils/media-cache.js +207 -0
  39. package/dist/utils/migrate-project.js +122 -0
  40. package/dist/utils/rich-content-renderer.js +228 -0
  41. package/dist/utils/stats-collector.js +102 -0
  42. package/package.json +4 -2
  43. package/dist/core/agent-runner.js +0 -348
  44. package/dist/core/message-processor.js +0 -604
  45. package/dist/core/message-queue.js +0 -116
  46. package/dist/core/message-stream.js +0 -59
  47. package/dist/core/session-manager.js +0 -664
  48. package/dist/index.js.bak +0 -340
  49. package/dist/utils/init-feishu.js +0 -261
  50. package/dist/utils/init-wechat.js +0 -170
  51. package/dist/utils/markdown-to-feishu.js +0 -94
  52. package/dist/utils/permission.js +0 -43
  53. package/dist/utils/session-file-health.js +0 -68
  54. /package/dist/core/{message-cache.js → message/message-cache.js} +0 -0
@@ -1,116 +0,0 @@
1
- import path from 'path';
2
- import { logger } from '../utils/logger.js';
3
- export class MessageQueue {
4
- queues = new Map();
5
- processing = new Set();
6
- handler;
7
- currentSessionKey;
8
- currentProjectPath;
9
- interruptCallback;
10
- constructor(handler) {
11
- this.handler = handler;
12
- }
13
- setInterruptCallback(callback) {
14
- this.interruptCallback = callback;
15
- }
16
- /**
17
- * 检查队列 key 是否属于指定 sessionKey
18
- */
19
- matchesSession(key, sessionKey) {
20
- return key.startsWith(sessionKey + '-');
21
- }
22
- /**
23
- * 生成项目级别的队列 key
24
- */
25
- getQueueKey(sessionKey, projectPath) {
26
- const projectName = path.basename(projectPath);
27
- return `${sessionKey}-${projectName}`;
28
- }
29
- async enqueue(sessionKey, message, projectPath) {
30
- const queueKey = this.getQueueKey(sessionKey, projectPath);
31
- logger.debug(`[Queue] Enqueuing message for ${queueKey}`);
32
- return new Promise((resolve, reject) => {
33
- if (!this.queues.has(queueKey)) {
34
- this.queues.set(queueKey, []);
35
- }
36
- this.queues.get(queueKey).push({ message, projectPath, resolve, reject });
37
- // 如果正在处理,触发中断
38
- if (this.processing.has(queueKey)) {
39
- logger.debug(`[Queue] ${queueKey} is processing, triggering interrupt`);
40
- if (this.interruptCallback) {
41
- this.interruptCallback(sessionKey).catch(() => { });
42
- }
43
- }
44
- else {
45
- logger.debug(`[Queue] Starting to process ${queueKey}`);
46
- this.processNext(queueKey);
47
- }
48
- });
49
- }
50
- async processNext(queueKey) {
51
- this.processing.add(queueKey);
52
- logger.debug(`[Queue] Processing queue ${queueKey}`);
53
- while (true) {
54
- const queue = this.queues.get(queueKey);
55
- if (!queue || queue.length === 0) {
56
- logger.debug(`[Queue] Queue ${queueKey} is empty, stopping`);
57
- this.processing.delete(queueKey);
58
- this.currentSessionKey = undefined;
59
- this.currentProjectPath = undefined;
60
- return;
61
- }
62
- const { message, projectPath, resolve, reject } = queue.shift();
63
- this.currentSessionKey = queueKey;
64
- this.currentProjectPath = projectPath;
65
- logger.debug(`[Queue] Processing message from ${message.channel}:${message.channelId}`);
66
- try {
67
- await this.handler(message);
68
- logger.debug(`[Queue] Message processed successfully`);
69
- resolve();
70
- }
71
- catch (error) {
72
- logger.error(`[Queue] Message processing failed:`, error);
73
- reject(error);
74
- }
75
- }
76
- }
77
- getQueueLength(sessionKey) {
78
- // 计算该 sessionKey 下所有项目队列的总长度
79
- let total = 0;
80
- for (const [key, queue] of this.queues.entries()) {
81
- if (this.matchesSession(key, sessionKey)) {
82
- total += queue.length;
83
- }
84
- }
85
- return total;
86
- }
87
- isProcessing(sessionKey) {
88
- // 检查该 sessionKey 下是否有任何项目队列在处理
89
- for (const key of this.processing.keys()) {
90
- if (this.matchesSession(key, sessionKey)) {
91
- return true;
92
- }
93
- }
94
- return false;
95
- }
96
- /**
97
- * 获取正在处理的项目路径
98
- */
99
- getProcessingProject(sessionKey) {
100
- // 查找该 sessionKey 下正在处理的项目
101
- for (const key of this.processing.keys()) {
102
- if (this.matchesSession(key, sessionKey)) {
103
- // 从 processing 中找到对应的队列,获取 projectPath
104
- const queue = this.queues.get(key);
105
- if (queue && queue.length > 0) {
106
- return queue[0].projectPath;
107
- }
108
- // 如果队列为空但仍在处理,返回当前正在处理的项目路径
109
- if (this.currentSessionKey === key) {
110
- return this.currentProjectPath;
111
- }
112
- }
113
- }
114
- return undefined;
115
- }
116
- }
@@ -1,59 +0,0 @@
1
- /**
2
- * MessageStream - Push-based async iterable for streaming user messages to the SDK.
3
- * Based on HappyClaw's implementation.
4
- */
5
- import { logger } from '../utils/logger.js';
6
- export class MessageStream {
7
- queue = [];
8
- waiting = null;
9
- done = false;
10
- push(text, images) {
11
- let content;
12
- if (images && images.length > 0) {
13
- logger.debug('[MessageStream] Creating multimodal message with', images.length, 'images');
14
- logger.debug('[MessageStream] Image sizes:', images.map(img => img.data.length).join(', '));
15
- // 多模态消息:text + images
16
- content = [
17
- { type: 'text', text },
18
- ...images.map((img) => ({
19
- type: 'image',
20
- source: {
21
- type: 'base64',
22
- media_type: img.mimeType || 'image/png',
23
- data: img.data,
24
- },
25
- })),
26
- ];
27
- }
28
- else {
29
- // 纯文本消息
30
- content = text;
31
- }
32
- const message = {
33
- type: 'user',
34
- message: { role: 'user', content },
35
- parent_tool_use_id: null,
36
- session_id: '',
37
- };
38
- logger.debug('[MessageStream] Pushing message, content type:', Array.isArray(content) ? 'array' : 'string');
39
- this.queue.push(message);
40
- this.waiting?.();
41
- }
42
- end() {
43
- this.done = true;
44
- this.waiting?.();
45
- }
46
- async *[Symbol.asyncIterator]() {
47
- while (true) {
48
- while (this.queue.length > 0) {
49
- yield this.queue.shift();
50
- }
51
- if (this.done)
52
- return;
53
- await new Promise((r) => {
54
- this.waiting = r;
55
- });
56
- this.waiting = null;
57
- }
58
- }
59
- }