evolclaw 2.8.3 → 3.0.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 +21 -12
- package/dist/agents/claude-runner.js +102 -38
- package/dist/agents/codex-runner.js +11 -14
- package/dist/agents/gemini-runner.js +10 -12
- package/dist/agents/resolve.js +134 -0
- package/dist/agents/templates.js +3 -3
- package/dist/aun/aid/agentmd.js +186 -0
- package/dist/aun/aid/client.js +134 -0
- package/dist/aun/aid/identity.js +131 -0
- package/dist/aun/aid/index.js +3 -0
- package/dist/aun/aid/types.js +1 -0
- package/dist/aun/aid/validation.js +21 -0
- package/dist/aun/msg/group.js +291 -0
- package/dist/aun/msg/index.js +4 -0
- package/dist/aun/msg/p2p.js +144 -0
- package/dist/aun/msg/payload-type.js +27 -0
- package/dist/aun/msg/upload.js +98 -0
- package/dist/aun/outbox.js +138 -0
- package/dist/aun/rpc/caller.js +42 -0
- package/dist/aun/rpc/connection.js +34 -0
- package/dist/aun/rpc/index.js +2 -0
- package/dist/aun/storage/download.js +29 -0
- package/dist/aun/storage/index.js +3 -0
- package/dist/aun/storage/manage.js +10 -0
- package/dist/aun/storage/upload.js +35 -0
- package/dist/channels/aun.js +1051 -288
- package/dist/channels/dingtalk.js +58 -5
- package/dist/channels/feishu.js +266 -30
- package/dist/channels/qqbot.js +67 -12
- package/dist/channels/wechat.js +61 -4
- package/dist/channels/wecom.js +58 -5
- package/dist/cli/agent.js +800 -0
- package/dist/cli/index.js +4253 -0
- package/dist/{utils → cli}/init-channel.js +211 -621
- package/dist/cli/init.js +178 -0
- package/dist/config-store.js +613 -0
- package/dist/core/{agent-loader.js → baseagent-loader.js} +6 -12
- package/dist/core/channel-loader.js +162 -11
- package/dist/core/command-handler.js +858 -847
- package/dist/core/evolagent-registry.js +191 -371
- package/dist/core/evolagent.js +203 -234
- package/dist/core/interaction-router.js +52 -5
- package/dist/core/message/im-renderer.js +480 -0
- package/dist/core/message/items-formatter.js +61 -0
- package/dist/core/message/message-bridge.js +104 -56
- package/dist/core/message/message-log.js +91 -0
- package/dist/core/message/message-processor.js +309 -142
- package/dist/core/message/message-queue.js +3 -3
- package/dist/core/permission.js +21 -8
- package/dist/core/session/adapters/codex-session-file-adapter.js +24 -2
- package/dist/core/session/session-fs-store.js +230 -0
- package/dist/core/session/session-manager.js +704 -775
- package/dist/core/session/session-mapper.js +87 -0
- package/dist/core/trigger/manager.js +122 -0
- package/dist/core/trigger/parser.js +128 -0
- package/dist/core/trigger/scheduler.js +224 -0
- package/dist/{templates → data}/prompts.md +34 -1
- package/dist/index.js +431 -275
- package/dist/ipc.js +49 -0
- package/dist/paths.js +82 -9
- package/dist/types.js +8 -2
- package/dist/utils/atomic-write.js +79 -0
- package/dist/utils/channel-helpers.js +46 -0
- package/dist/utils/cross-platform.js +0 -18
- package/dist/utils/instance-registry.js +433 -0
- package/dist/utils/log-writer.js +216 -0
- package/dist/utils/logger.js +24 -77
- package/dist/utils/media-cache.js +23 -0
- package/dist/utils/{upgrade.js → npm-ops.js} +52 -21
- package/dist/utils/process-introspect.js +144 -0
- package/dist/utils/stats.js +192 -0
- package/dist/watch-msg.js +529 -0
- package/evolclaw-install-aun.md +114 -46
- package/kits/aun/meta.md +25 -0
- package/kits/aun/role.md +25 -0
- package/kits/channels/aun.md +25 -0
- package/kits/evolclaw/commands.md +31 -0
- package/kits/evolclaw/identity-tools.md +26 -0
- package/kits/evolclaw/self-summary.md +29 -0
- package/kits/evolclaw/tools.md +25 -0
- package/kits/templates/group.md +20 -0
- package/kits/templates/private.md +9 -0
- package/kits/templates/system-fragments/personal-context.md +3 -0
- package/kits/templates/system-fragments/self-intro.md +5 -0
- package/kits/templates/system-fragments/speaker-intro.md +5 -0
- package/kits/templates/system-fragments/venue-intro.md +5 -0
- package/package.json +7 -5
- package/data/evolclaw.sample.json +0 -60
- package/dist/channels/aun-ops.js +0 -275
- package/dist/cli.js +0 -2178
- package/dist/config.js +0 -591
- package/dist/core/agent-registry.js +0 -450
- package/dist/core/evolagent-schema.js +0 -72
- package/dist/core/message/stream-flusher.js +0 -238
- package/dist/core/message/thought-emitter.js +0 -162
- package/dist/core/reload-hooks.js +0 -87
- package/dist/prompts/templates.js +0 -122
- package/dist/templates/skills.md +0 -66
- package/dist/utils/channel-fingerprint.js +0 -59
- package/dist/utils/error-dict.js +0 -63
- package/dist/utils/format.js +0 -32
- package/dist/utils/init.js +0 -645
- package/dist/utils/migrate-project.js +0 -122
- package/dist/utils/reload-hooks.js +0 -87
- package/dist/utils/stats-collector.js +0 -99
|
@@ -20,6 +20,50 @@ export class ChannelLoader {
|
|
|
20
20
|
this.plugins.set(plugin.name, plugin);
|
|
21
21
|
logger.debug(`Registered channel plugin: ${plugin.name}`);
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* 新结构入口:从 EvolAgent 的 channels[] 列表创建 channel 实例。
|
|
25
|
+
*
|
|
26
|
+
* 内部把 ChannelInstance[] 翻成各 plugin 期望的 dict 形态(`{ type: [instances...] }`),
|
|
27
|
+
* 然后调用现有 plugin.createChannels / createChannel。
|
|
28
|
+
*
|
|
29
|
+
* 当所有 channel plugin 重写为直接吃 ChannelInstance[] 后,本方法可简化。
|
|
30
|
+
*/
|
|
31
|
+
async createForAgent(agent) {
|
|
32
|
+
const rewrittenChannels = {};
|
|
33
|
+
// AUN channel 从 agent.aid 隐式创建——不需要在 channels[] 里显式声明
|
|
34
|
+
const aunEffName = agent.effectiveChannelName('aun', 'main');
|
|
35
|
+
rewrittenChannels['aun'] = [{
|
|
36
|
+
type: 'aun',
|
|
37
|
+
name: aunEffName,
|
|
38
|
+
aid: agent.aid,
|
|
39
|
+
enabled: true,
|
|
40
|
+
agentName: agent.aid,
|
|
41
|
+
// agent 顶层 owners[0] 透传给 AUN channel.owner(用于首次连接发欢迎消息)
|
|
42
|
+
owner: agent.config.owners?.[0],
|
|
43
|
+
}];
|
|
44
|
+
// 其它 channels(非 AUN)从 config.channels[] 取
|
|
45
|
+
for (const inst of agent.config.channels) {
|
|
46
|
+
if (inst.type === 'aun')
|
|
47
|
+
continue; // 跳过显式声明的 AUN(已隐式处理)
|
|
48
|
+
const effName = agent.effectiveChannelName(inst.type, inst.name);
|
|
49
|
+
const rewritten = { ...inst, name: effName, agentName: agent.aid };
|
|
50
|
+
(rewrittenChannels[inst.type] ??= []).push(rewritten);
|
|
51
|
+
}
|
|
52
|
+
// syntheticConfig 是老 Config schema(channel plugin 沿用旧接口),
|
|
53
|
+
// 新 schema 字段命名为 snake_case,这里转 camelCase 透传。
|
|
54
|
+
const syntheticConfig = {
|
|
55
|
+
agents: agent.config.baseagents,
|
|
56
|
+
channels: rewrittenChannels,
|
|
57
|
+
projects: agent.config.projects,
|
|
58
|
+
chatmode: agent.config.chatmode,
|
|
59
|
+
debug: agent.config.debug,
|
|
60
|
+
showActivities: agent.config.show_activities,
|
|
61
|
+
flushDelay: agent.config.flush_delay,
|
|
62
|
+
debounce: agent.config.debounce,
|
|
63
|
+
enableRichContent: agent.config.enable_rich_content,
|
|
64
|
+
};
|
|
65
|
+
return this.createAll(syntheticConfig);
|
|
66
|
+
}
|
|
23
67
|
async createAll(config) {
|
|
24
68
|
const instances = [];
|
|
25
69
|
for (const [name, plugin] of this.plugins) {
|
|
@@ -45,17 +89,21 @@ export class ChannelLoader {
|
|
|
45
89
|
}
|
|
46
90
|
return instances;
|
|
47
91
|
}
|
|
48
|
-
async connectAll(instances) {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
92
|
+
async connectAll(instances, delayMs = 150) {
|
|
93
|
+
const connected = [];
|
|
94
|
+
const failed = [];
|
|
95
|
+
for (const inst of instances) {
|
|
96
|
+
try {
|
|
97
|
+
await inst.connect();
|
|
98
|
+
connected.push(inst.adapter.channelName);
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
failed.push(e);
|
|
102
|
+
}
|
|
103
|
+
if (delayMs > 0 && inst !== instances[instances.length - 1]) {
|
|
104
|
+
await new Promise(r => setTimeout(r, delayMs));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
59
107
|
if (failed.length > 0) {
|
|
60
108
|
logger.warn(`Some channels failed to connect:`, failed);
|
|
61
109
|
}
|
|
@@ -65,3 +113,106 @@ export class ChannelLoader {
|
|
|
65
113
|
await Promise.allSettled(instances.map((inst) => inst.disconnect()));
|
|
66
114
|
}
|
|
67
115
|
}
|
|
116
|
+
const SEP = '#';
|
|
117
|
+
export function formatChannelKey(k) {
|
|
118
|
+
return `${k.aid}${SEP}${k.type}${SEP}${k.name}`;
|
|
119
|
+
}
|
|
120
|
+
export function parseChannelKey(key) {
|
|
121
|
+
const parts = key.split(SEP);
|
|
122
|
+
if (parts.length !== 3) {
|
|
123
|
+
throw new Error(`Invalid channel key (expected 3 segments separated by '#'): ${key}`);
|
|
124
|
+
}
|
|
125
|
+
const [aid, type, name] = parts;
|
|
126
|
+
if (!aid || !type || !name) {
|
|
127
|
+
throw new Error(`Invalid channel key (empty segment): ${key}`);
|
|
128
|
+
}
|
|
129
|
+
return { aid, type, name };
|
|
130
|
+
}
|
|
131
|
+
export function tryParseChannelKey(key) {
|
|
132
|
+
try {
|
|
133
|
+
return parseChannelKey(key);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export function isValidChannelName(name) {
|
|
140
|
+
return typeof name === 'string' && name.length > 0 && !name.includes(SEP);
|
|
141
|
+
}
|
|
142
|
+
export function buildReloadHooks(deps) {
|
|
143
|
+
const { channelLoader, channelInstances, registerChannelInstance, messageQueue } = deps;
|
|
144
|
+
const drainDelayMs = deps.drainDelayMs ?? 500;
|
|
145
|
+
const drainTimeoutMs = deps.drainTimeoutMs ?? 30000;
|
|
146
|
+
return {
|
|
147
|
+
async drainChannel(channelName) {
|
|
148
|
+
logger.info(`[Reload] Draining channel: ${channelName}`);
|
|
149
|
+
if (messageQueue) {
|
|
150
|
+
const pollMs = 100;
|
|
151
|
+
const start = Date.now();
|
|
152
|
+
while (messageQueue.isChannelProcessing(channelName)) {
|
|
153
|
+
if (Date.now() - start > drainTimeoutMs) {
|
|
154
|
+
logger.warn(`[Reload] Drain timeout (${drainTimeoutMs}ms) for channel: ${channelName}, proceeding anyway`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
await new Promise(r => setTimeout(r, pollMs));
|
|
158
|
+
}
|
|
159
|
+
logger.info(`[Reload] Drain complete: ${channelName}`);
|
|
160
|
+
}
|
|
161
|
+
else if (drainDelayMs > 0) {
|
|
162
|
+
await new Promise(r => setTimeout(r, drainDelayMs));
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
async disconnectChannel(channelName) {
|
|
166
|
+
const inst = channelInstances.find(i => i.adapter.channelName === channelName);
|
|
167
|
+
if (!inst) {
|
|
168
|
+
logger.warn(`[Reload] Channel ${channelName} not found, skipping disconnect`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
await inst.disconnect();
|
|
173
|
+
const idx = channelInstances.indexOf(inst);
|
|
174
|
+
if (idx >= 0)
|
|
175
|
+
channelInstances.splice(idx, 1);
|
|
176
|
+
logger.info(`[Reload] Disconnected channel: ${channelName}`);
|
|
177
|
+
}
|
|
178
|
+
catch (e) {
|
|
179
|
+
logger.error(`[Reload] Failed to disconnect ${channelName}: ${e}`);
|
|
180
|
+
throw e;
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
async startChannel(agent, channelName) {
|
|
184
|
+
const channels = agent.config.channels;
|
|
185
|
+
let channelType = null;
|
|
186
|
+
for (const [type, raw] of Object.entries(channels)) {
|
|
187
|
+
const instances = Array.isArray(raw) ? raw : [raw];
|
|
188
|
+
for (const inst of instances) {
|
|
189
|
+
const name = inst.name ?? type;
|
|
190
|
+
if (name === channelName) {
|
|
191
|
+
channelType = type;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (channelType)
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
if (!channelType) {
|
|
199
|
+
const msg = `[Reload] Channel ${channelName} not found in agent ${agent.name} config`;
|
|
200
|
+
logger.error(msg);
|
|
201
|
+
throw new Error(msg);
|
|
202
|
+
}
|
|
203
|
+
const partialConfig = {
|
|
204
|
+
agents: agent.config.agents,
|
|
205
|
+
channels: { [channelType]: channels[channelType] },
|
|
206
|
+
projects: agent.config.projects,
|
|
207
|
+
};
|
|
208
|
+
const newInstances = await channelLoader.createAll(partialConfig);
|
|
209
|
+
const newInst = newInstances.find(i => i.adapter.channelName === channelName);
|
|
210
|
+
if (!newInst)
|
|
211
|
+
throw new Error(`[Reload] Failed to create instance ${channelName}`);
|
|
212
|
+
registerChannelInstance(newInst);
|
|
213
|
+
await newInst.connect();
|
|
214
|
+
channelInstances.push(newInst);
|
|
215
|
+
logger.info(`[Reload] Started channel: ${channelName}`);
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
}
|