claw-subagent-service 0.0.115 → 0.0.116
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/package.json
CHANGED
|
@@ -29,6 +29,10 @@ class MessageHandler {
|
|
|
29
29
|
this._groupConfigCache = new Map();
|
|
30
30
|
this._defaultMaxRounds = 10;
|
|
31
31
|
this._groupConfigCacheTTL = config.groupConfigCacheTTL || 60000; // 默认缓存 60 秒
|
|
32
|
+
|
|
33
|
+
// 消息合并相关
|
|
34
|
+
this._pendingMessages = new Map(); // 待合并的消息
|
|
35
|
+
this._messageMergeTimeout = 500; // 合并等待时间(毫秒)
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
/**
|
|
@@ -215,42 +219,102 @@ class MessageHandler {
|
|
|
215
219
|
});
|
|
216
220
|
}
|
|
217
221
|
|
|
218
|
-
//
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
222
|
+
// 消息合并逻辑:如果是图片消息,等待一段时间看是否有文字消息跟随
|
|
223
|
+
if (msg.messageType === 'RC:ImgMsg') {
|
|
224
|
+
await this._handleImageMessageWithMerge(msg, maxRounds);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// 普通消息直接处理
|
|
229
|
+
await this._processMessage(msg, maxRounds);
|
|
230
|
+
} catch (err) {
|
|
231
|
+
this.log?.error(`[MessageHandler] 处理消息异常: ${err.message}`);
|
|
232
|
+
const targetId = msg.conversationType === 3 ? msg.targetId : msg.senderUserId;
|
|
233
|
+
await this.sendFn(targetId, `处理失败: ${err.message}`, msg.conversationType);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* 处理图片消息,支持合并后续文字消息
|
|
239
|
+
*/
|
|
240
|
+
async _handleImageMessageWithMerge(msg, maxRounds) {
|
|
241
|
+
const userId = msg.senderUserId;
|
|
242
|
+
const conversationKey = `${msg.conversationType}-${msg.targetId}-${userId}`;
|
|
243
|
+
|
|
244
|
+
// 设置待处理图片消息
|
|
245
|
+
this._pendingMessages.set(conversationKey, {
|
|
246
|
+
imageMsg: msg,
|
|
247
|
+
timestamp: Date.now(),
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// 等待一段时间,看是否有文字消息跟随
|
|
251
|
+
await new Promise(resolve => setTimeout(resolve, this._messageMergeTimeout));
|
|
252
|
+
|
|
253
|
+
// 获取待处理消息
|
|
254
|
+
const pending = this._pendingMessages.get(conversationKey);
|
|
255
|
+
this._pendingMessages.delete(conversationKey);
|
|
256
|
+
|
|
257
|
+
if (!pending) {
|
|
258
|
+
return; // 消息已被处理
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// 构建合并后的消息内容
|
|
262
|
+
const imageContent = this._extractMessageContent(pending.imageMsg);
|
|
263
|
+
let mergedContent = imageContent;
|
|
264
|
+
|
|
265
|
+
if (pending.textMsg) {
|
|
266
|
+
const textContent = typeof pending.textMsg.content === 'string'
|
|
267
|
+
? pending.textMsg.content
|
|
268
|
+
: (pending.textMsg.content?.content || '');
|
|
269
|
+
mergedContent = `${textContent}\n${imageContent}`;
|
|
270
|
+
this.log?.info(`[MessageHandler] 合并消息: 图片+文字`);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// 创建合并后的消息对象
|
|
274
|
+
const mergedMsg = {
|
|
275
|
+
...pending.imageMsg,
|
|
276
|
+
content: mergedContent,
|
|
277
|
+
messageType: 'RC:TxtMsg', // 转为文本消息处理
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
await this._processMessage(mergedMsg, maxRounds);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* 处理普通消息(包括合并后的消息)
|
|
285
|
+
*/
|
|
286
|
+
async _processMessage(msg, maxRounds) {
|
|
287
|
+
// 如果配置了代理地址,使用流式处理
|
|
288
|
+
if (this.isStreamingEnabled) {
|
|
289
|
+
try {
|
|
290
|
+
await this.handleNormalMessageStream(msg);
|
|
291
|
+
// 流式处理成功,群聊轮数 +1
|
|
292
|
+
if (msg.conversationType === 3) {
|
|
293
|
+
this._incrementGroupRoundCount(msg.targetId, maxRounds);
|
|
237
294
|
}
|
|
238
|
-
}
|
|
239
|
-
|
|
295
|
+
} catch (err) {
|
|
296
|
+
this.log?.error(`[MessageHandler] 流式处理失败,回退到非流式: ${err.message}`);
|
|
240
297
|
const reply = await this.handleNormalMessage(msg);
|
|
241
298
|
if (reply) {
|
|
242
299
|
const targetId = this.getReplyTarget(msg);
|
|
243
300
|
await this.sendFn(targetId, reply, msg.conversationType);
|
|
244
|
-
//
|
|
301
|
+
// 非流式回退成功,群聊轮数 +1
|
|
245
302
|
if (msg.conversationType === 3) {
|
|
246
303
|
this._incrementGroupRoundCount(msg.targetId, maxRounds);
|
|
247
304
|
}
|
|
248
305
|
}
|
|
249
306
|
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const
|
|
253
|
-
|
|
307
|
+
} else {
|
|
308
|
+
// 降级到非流式处理
|
|
309
|
+
const reply = await this.handleNormalMessage(msg);
|
|
310
|
+
if (reply) {
|
|
311
|
+
const targetId = this.getReplyTarget(msg);
|
|
312
|
+
await this.sendFn(targetId, reply, msg.conversationType);
|
|
313
|
+
// 非流式处理成功,群聊轮数 +1
|
|
314
|
+
if (msg.conversationType === 3) {
|
|
315
|
+
this._incrementGroupRoundCount(msg.targetId, maxRounds);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
254
318
|
}
|
|
255
319
|
}
|
|
256
320
|
|