evolclaw 3.1.4 → 3.1.5
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/CHANGELOG.md +10 -0
- package/dist/agents/claude-runner.js +348 -156
- package/dist/agents/kit-renderer.js +176 -21
- package/dist/aun/aid/agentmd.js +68 -103
- package/dist/aun/aid/client.js +1 -29
- package/dist/aun/aid/identity.js +105 -64
- package/dist/aun/aid/index.js +2 -1
- package/dist/aun/aid/store.js +74 -0
- package/dist/aun/msg/p2p.js +26 -2
- package/dist/aun/rpc/connection.js +23 -30
- package/dist/channels/aun.js +77 -88
- package/dist/channels/dingtalk.js +1 -0
- package/dist/channels/feishu.js +270 -190
- package/dist/channels/qqbot.js +1 -0
- package/dist/channels/wechat.js +1 -0
- package/dist/channels/wecom.js +1 -0
- package/dist/cli/agent.js +11 -5
- package/dist/cli/bench.js +40 -23
- package/dist/cli/index.js +170 -44
- package/dist/cli/init-channel.js +5 -1
- package/dist/cli/model.js +324 -0
- package/dist/cli/net-check.js +133 -50
- package/dist/cli/watch-msg.js +7 -7
- package/dist/cli/watch-web/debug-log.js +18 -0
- package/dist/cli/watch-web/server.js +306 -0
- package/dist/cli/watch-web/sources/aid.js +63 -0
- package/dist/cli/watch-web/sources/msg.js +70 -0
- package/dist/cli/watch-web/sources/session.js +638 -0
- package/dist/cli/watch-web/sources/types.js +10 -0
- package/dist/cli/watch-web/static/app.js +546 -0
- package/dist/cli/watch-web/static/index.html +54 -0
- package/dist/cli/watch-web/static/style.css +247 -0
- package/dist/core/channel-loader.js +7 -4
- package/dist/core/command-handler.js +81 -86
- package/dist/core/evolagent-registry.js +1 -1
- package/dist/core/evolagent.js +4 -4
- package/dist/core/interaction-router.js +59 -0
- package/dist/core/message/message-bridge.js +6 -6
- package/dist/core/message/message-log.js +2 -2
- package/dist/core/message/message-processor.js +86 -101
- package/dist/core/message/stream-idle-monitor.js +21 -0
- package/dist/core/model/model-catalog.js +215 -0
- package/dist/core/model/model-scope.js +250 -0
- package/dist/core/relation/peer-identity.js +40 -49
- package/dist/core/relation/peer-key.js +16 -0
- package/dist/core/session/session-fs-store.js +34 -55
- package/dist/core/session/session-key.js +24 -0
- package/dist/core/session/session-manager.js +308 -251
- package/dist/core/session/session-mapper.js +9 -4
- package/dist/core/trigger/manager.js +3 -3
- package/dist/core/trigger/scheduler.js +2 -1
- package/dist/index.js +6 -2
- package/dist/ipc.js +22 -0
- package/kits/docs/GUIDE.md +2 -2
- package/kits/docs/INDEX.md +11 -7
- package/kits/docs/channels/aun.md +56 -17
- package/kits/docs/channels/feishu.md +41 -12
- package/kits/docs/context-assembly.md +181 -0
- package/kits/docs/evolclaw/agent.md +49 -0
- package/kits/docs/evolclaw/aid.md +49 -0
- package/kits/docs/evolclaw/ctl.md +46 -0
- package/kits/docs/evolclaw/group.md +82 -0
- package/kits/docs/evolclaw/msg.md +86 -0
- package/kits/docs/evolclaw/rpc.md +35 -0
- package/kits/docs/evolclaw/storage.md +49 -0
- package/kits/docs/venues/aun-group.md +10 -0
- package/kits/docs/venues/aun-private.md +10 -0
- package/kits/docs/venues/client-desktop.md +10 -0
- package/kits/docs/venues/client-mobile.md +10 -0
- package/kits/docs/venues/feishu-group.md +13 -0
- package/kits/docs/venues/feishu-private.md +9 -0
- package/kits/docs/venues/group.md +11 -0
- package/kits/docs/venues/private.md +10 -0
- package/kits/eck_manifest.json +72 -36
- package/kits/rules/01-overview.md +20 -10
- package/kits/rules/06-channel.md +30 -27
- package/kits/templates/system-fragments/session.md +10 -3
- package/kits/templates/system-fragments/venue.md +9 -0
- package/package.json +11 -6
- package/dist/aun/aid/lifecycle-log.js +0 -33
- package/dist/utils/aid-lifecycle-log.js +0 -33
- package/kits/docs/evolclaw/AGENT_CMD.md +0 -31
- package/kits/docs/evolclaw/MSG_GROUP.md +0 -30
- package/kits/docs/evolclaw/MSG_PRIVATE.md +0 -72
- package/kits/docs/evolclaw/tools.md +0 -25
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peerKey: 关系层路由键,格式 `<channelType>#<urlEncode(channelId)>`。
|
|
3
|
+
* 群聊场景下 channelId = groupId,所有发言者共用同一个 peerKey。
|
|
4
|
+
*/
|
|
5
|
+
export function formatPeerKey(channelType, channelId) {
|
|
6
|
+
return `${channelType}#${encodeURIComponent(channelId)}`;
|
|
7
|
+
}
|
|
8
|
+
export function parsePeerKey(key) {
|
|
9
|
+
const idx = key.indexOf('#');
|
|
10
|
+
if (idx <= 0)
|
|
11
|
+
throw new Error(`Invalid peer key: ${key}`);
|
|
12
|
+
return {
|
|
13
|
+
channelType: key.slice(0, idx),
|
|
14
|
+
channelId: decodeURIComponent(key.slice(idx + 1)),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -12,19 +12,16 @@ function decodeSegment(s) {
|
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* 计算 chat 目录的完整路径。
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
17
|
-
*
|
|
18
|
-
* 注:channelType 自身不编码(限定枚举值,不含非法字符)。
|
|
15
|
+
* - aun: sessionsDir/aun/<urlEncode(selfAID|'_unknown')>/<urlEncode(channelId)>/
|
|
16
|
+
* - 其它: sessionsDir/<channelType>/<urlEncode(channelId)>/
|
|
19
17
|
*/
|
|
20
|
-
export function chatDirPath(sessionsDir, channelType, channelId,
|
|
18
|
+
export function chatDirPath(sessionsDir, channelType, channelId, selfAID) {
|
|
21
19
|
if (channelType === 'aun') {
|
|
22
|
-
|
|
23
|
-
return path.join(sessionsDir, 'aun', encodeSegment(self), encodeSegment(channelId));
|
|
20
|
+
return path.join(sessionsDir, channelType, encodeSegment(selfAID || '_unknown'), encodeSegment(channelId));
|
|
24
21
|
}
|
|
25
22
|
return path.join(sessionsDir, channelType, encodeSegment(channelId));
|
|
26
23
|
}
|
|
27
|
-
/** 解码目录段(用于扫描时把目录名还原为原始 channelId/
|
|
24
|
+
/** 解码目录段(用于扫描时把目录名还原为原始 channelId/selfAID) */
|
|
28
25
|
export function decodeDirSegment(seg) {
|
|
29
26
|
return decodeSegment(seg);
|
|
30
27
|
}
|
|
@@ -128,8 +125,8 @@ export function readAllJsonlLines(filePath) {
|
|
|
128
125
|
}
|
|
129
126
|
/**
|
|
130
127
|
* 扫描所有 chat 目录。
|
|
131
|
-
*
|
|
132
|
-
*
|
|
128
|
+
* - aun: channelType / selfAID / channelId (3层)
|
|
129
|
+
* - 其它: channelType / channelId (2层)
|
|
133
130
|
*/
|
|
134
131
|
export function scanChatDirs(sessionsDir) {
|
|
135
132
|
const results = [];
|
|
@@ -146,40 +143,17 @@ export function scanChatDirs(sessionsDir) {
|
|
|
146
143
|
if (!typeEntry.isDirectory())
|
|
147
144
|
continue;
|
|
148
145
|
const channelType = typeEntry.name;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
chatEntries = fs.readdirSync(typeDir, { withFileTypes: true });
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
for (const chatEntry of chatEntries) {
|
|
161
|
-
if (!chatEntry.isDirectory())
|
|
162
|
-
continue;
|
|
163
|
-
results.push({
|
|
164
|
-
channelType,
|
|
165
|
-
selfId: null,
|
|
166
|
-
channelId: decodeSegment(chatEntry.name),
|
|
167
|
-
dirPath: path.join(typeDir, chatEntry.name),
|
|
168
|
-
});
|
|
169
|
-
}
|
|
146
|
+
const typeDir = path.join(sessionsDir, channelType);
|
|
147
|
+
let level2Entries;
|
|
148
|
+
try {
|
|
149
|
+
level2Entries = fs.readdirSync(typeDir, { withFileTypes: true });
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
170
152
|
continue;
|
|
171
153
|
}
|
|
172
|
-
const typeDir = path.join(sessionsDir, channelType);
|
|
173
154
|
if (channelType === 'aun') {
|
|
174
|
-
// aun
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
selfEntries = fs.readdirSync(typeDir, { withFileTypes: true });
|
|
178
|
-
}
|
|
179
|
-
catch {
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
for (const selfEntry of selfEntries) {
|
|
155
|
+
// 3-layer: aun/selfAID/channelId
|
|
156
|
+
for (const selfEntry of level2Entries) {
|
|
183
157
|
if (!selfEntry.isDirectory())
|
|
184
158
|
continue;
|
|
185
159
|
const selfDir = path.join(typeDir, selfEntry.name);
|
|
@@ -195,7 +169,7 @@ export function scanChatDirs(sessionsDir) {
|
|
|
195
169
|
continue;
|
|
196
170
|
results.push({
|
|
197
171
|
channelType,
|
|
198
|
-
|
|
172
|
+
selfAID: decodeSegment(selfEntry.name),
|
|
199
173
|
channelId: decodeSegment(chatEntry.name),
|
|
200
174
|
dirPath: path.join(selfDir, chatEntry.name),
|
|
201
175
|
});
|
|
@@ -203,20 +177,13 @@ export function scanChatDirs(sessionsDir) {
|
|
|
203
177
|
}
|
|
204
178
|
}
|
|
205
179
|
else {
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
try {
|
|
209
|
-
chatEntries = fs.readdirSync(typeDir, { withFileTypes: true });
|
|
210
|
-
}
|
|
211
|
-
catch {
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
for (const chatEntry of chatEntries) {
|
|
180
|
+
// 2-layer: channelType/channelId
|
|
181
|
+
for (const chatEntry of level2Entries) {
|
|
215
182
|
if (!chatEntry.isDirectory())
|
|
216
183
|
continue;
|
|
217
184
|
results.push({
|
|
218
185
|
channelType,
|
|
219
|
-
|
|
186
|
+
selfAID: '',
|
|
220
187
|
channelId: decodeSegment(chatEntry.name),
|
|
221
188
|
dirPath: path.join(typeDir, chatEntry.name),
|
|
222
189
|
});
|
|
@@ -238,15 +205,27 @@ export function scanMetaFiles(chatDir) {
|
|
|
238
205
|
throw e;
|
|
239
206
|
}
|
|
240
207
|
}
|
|
241
|
-
export function ensureChatDir(sessionsDir, channelType, channelId,
|
|
242
|
-
const dir = chatDirPath(sessionsDir, channelType, channelId,
|
|
208
|
+
export function ensureChatDir(sessionsDir, channelType, channelId, selfAID) {
|
|
209
|
+
const dir = chatDirPath(sessionsDir, channelType, channelId, selfAID);
|
|
243
210
|
fs.mkdirSync(dir, { recursive: true });
|
|
244
211
|
fs.mkdirSync(path.join(dir, '_threads'), { recursive: true });
|
|
245
212
|
fs.mkdirSync(path.join(dir, '_trash'), { recursive: true });
|
|
246
213
|
return dir;
|
|
247
214
|
}
|
|
248
215
|
export function readThreadIndex(chatDir) {
|
|
249
|
-
|
|
216
|
+
const raw = readJsonFile(path.join(chatDir, '_threads', 'thread-index.json')) || {};
|
|
217
|
+
// Migrate legacy format: { threadId: sessionId } → { threadId: { sessionId, sessionKey, metaFile } }
|
|
218
|
+
const result = {};
|
|
219
|
+
for (const [tid, val] of Object.entries(raw)) {
|
|
220
|
+
if (typeof val === 'string') {
|
|
221
|
+
// Legacy: val is sessionId
|
|
222
|
+
result[tid] = { sessionId: val, sessionKey: '', metaFile: `${val}.jsonl` };
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
result[tid] = val;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return result;
|
|
250
229
|
}
|
|
251
230
|
export function writeThreadIndex(chatDir, index) {
|
|
252
231
|
atomicWriteJson(path.join(chatDir, '_threads', 'thread-index.json'), index);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sessionKey: agent 内部会话路由键。
|
|
3
|
+
* 格式: channelType#urlEncode(channelId)#urlEncode(threadId)
|
|
4
|
+
* 无话题时 threadId 固定为 'main'。
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_THREAD_ID = 'main';
|
|
7
|
+
export function formatSessionKey(channelType, channelId, threadId) {
|
|
8
|
+
const tid = threadId || DEFAULT_THREAD_ID;
|
|
9
|
+
return `${channelType}#${encodeURIComponent(channelId)}#${encodeURIComponent(tid)}`;
|
|
10
|
+
}
|
|
11
|
+
export function parseSessionKey(key) {
|
|
12
|
+
const first = key.indexOf('#');
|
|
13
|
+
if (first <= 0)
|
|
14
|
+
throw new Error(`Invalid session key: ${key}`);
|
|
15
|
+
const rest = key.slice(first + 1);
|
|
16
|
+
const second = rest.indexOf('#');
|
|
17
|
+
if (second <= 0)
|
|
18
|
+
throw new Error(`Invalid session key (missing threadId): ${key}`);
|
|
19
|
+
return {
|
|
20
|
+
channelType: key.slice(0, first),
|
|
21
|
+
channelId: decodeURIComponent(rest.slice(0, second)),
|
|
22
|
+
threadId: decodeURIComponent(rest.slice(second + 1)),
|
|
23
|
+
};
|
|
24
|
+
}
|