claw-subagent-service 0.0.116 → 0.0.117
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
|
@@ -257,6 +257,8 @@ class OpenClawClient {
|
|
|
257
257
|
static maxHistoryRounds = 50;
|
|
258
258
|
// 单条消息最大长度(超过则截断)
|
|
259
259
|
static maxMessageLength = 2000;
|
|
260
|
+
// 活跃请求管理:为每个用户跟踪当前正在进行的请求
|
|
261
|
+
static activeRequests = new Map();
|
|
260
262
|
|
|
261
263
|
static async acquireSlot() {
|
|
262
264
|
if (OpenClawClient.runningCount < OpenClawClient.maxConcurrency) {
|
|
@@ -414,6 +416,21 @@ class OpenClawClient {
|
|
|
414
416
|
* @param {Function} onError - 出错时的回调 (error: Error) => void
|
|
415
417
|
* @returns {Promise<void>}
|
|
416
418
|
*/
|
|
419
|
+
/**
|
|
420
|
+
* 取消用户的活跃请求
|
|
421
|
+
* @param {string} fromUser - 用户ID
|
|
422
|
+
*/
|
|
423
|
+
cancelActiveRequest(fromUser) {
|
|
424
|
+
const activeRequest = OpenClawClient.activeRequests.get(fromUser);
|
|
425
|
+
if (activeRequest) {
|
|
426
|
+
this.log?.info(`[OpenClawClient] 取消用户 ${fromUser} 的活跃请求`);
|
|
427
|
+
activeRequest.abort();
|
|
428
|
+
OpenClawClient.activeRequests.delete(fromUser);
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
|
|
417
434
|
async chatStream(message, fromUser, onDelta, onDone, onError) {
|
|
418
435
|
if (!message || !message.trim()) {
|
|
419
436
|
onError?.(new Error('消息内容为空'));
|
|
@@ -428,6 +445,12 @@ class OpenClawClient {
|
|
|
428
445
|
return;
|
|
429
446
|
}
|
|
430
447
|
|
|
448
|
+
// 取消该用户之前的活跃请求(如果存在)
|
|
449
|
+
const hasCancelled = this.cancelActiveRequest(fromUser);
|
|
450
|
+
if (hasCancelled) {
|
|
451
|
+
this.log?.info(`[OpenClawClient] 用户 ${fromUser} 的新消息到达,已取消前一条消息的回复`);
|
|
452
|
+
}
|
|
453
|
+
|
|
431
454
|
this.log?.info(`[OpenClawClient] 准备 SSE 流式调用 OpenClaw,from=${fromUser}`);
|
|
432
455
|
|
|
433
456
|
const gatewayToken = getGatewayToken();
|
|
@@ -445,7 +468,7 @@ class OpenClawClient {
|
|
|
445
468
|
for (let i = 0; i < endpoints.length; i++) {
|
|
446
469
|
const apiUrl = endpoints[i];
|
|
447
470
|
try {
|
|
448
|
-
const fullText = await this._doChatStream(apiUrl, gatewayToken, sessionId, messagesWithHistory, onDelta, onDone);
|
|
471
|
+
const fullText = await this._doChatStream(apiUrl, gatewayToken, sessionId, fromUser, messagesWithHistory, onDelta, onDone);
|
|
449
472
|
|
|
450
473
|
// 成功响应后,保存当前对话到历史记录
|
|
451
474
|
this._addToHistory(fromUser, 'user', message);
|
|
@@ -453,6 +476,12 @@ class OpenClawClient {
|
|
|
453
476
|
|
|
454
477
|
return; // 成功则直接返回
|
|
455
478
|
} catch (err) {
|
|
479
|
+
// 检查是否是取消错误
|
|
480
|
+
if (err.name === 'AbortError' || err.message?.includes('aborted')) {
|
|
481
|
+
this.log?.info(`[OpenClawClient] 请求被用户取消: ${fromUser}`);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
|
|
456
485
|
const is404 = err.response?.status === 404;
|
|
457
486
|
const isLast = i === endpoints.length - 1;
|
|
458
487
|
|
|
@@ -531,7 +560,7 @@ class OpenClawClient {
|
|
|
531
560
|
}
|
|
532
561
|
}
|
|
533
562
|
|
|
534
|
-
async _doChatStream(apiUrl, gatewayToken, sessionId, messages, onDelta, onDone) {
|
|
563
|
+
async _doChatStream(apiUrl, gatewayToken, sessionId, fromUser, messages, onDelta, onDone) {
|
|
535
564
|
const headers = {
|
|
536
565
|
'Content-Type': 'application/json',
|
|
537
566
|
'Accept': 'text/event-stream'
|
|
@@ -605,10 +634,17 @@ class OpenClawClient {
|
|
|
605
634
|
let hasError = false;
|
|
606
635
|
let errorMsg = '';
|
|
607
636
|
|
|
637
|
+
// 创建 AbortController 用于取消请求
|
|
638
|
+
const abortController = new AbortController();
|
|
639
|
+
|
|
640
|
+
// 注册活跃请求
|
|
641
|
+
OpenClawClient.activeRequests.set(fromUser, abortController);
|
|
642
|
+
|
|
608
643
|
const response = await axios.post(apiUrl, payload, {
|
|
609
644
|
headers,
|
|
610
645
|
responseType: 'stream',
|
|
611
|
-
timeout: 600000 // 10 分钟
|
|
646
|
+
timeout: 600000, // 10 分钟
|
|
647
|
+
signal: abortController.signal
|
|
612
648
|
});
|
|
613
649
|
|
|
614
650
|
return new Promise((resolve, reject) => {
|
|
@@ -677,6 +713,9 @@ class OpenClawClient {
|
|
|
677
713
|
});
|
|
678
714
|
|
|
679
715
|
response.data.on('end', async () => {
|
|
716
|
+
// 清理活跃请求
|
|
717
|
+
OpenClawClient.activeRequests.delete(fromUser);
|
|
718
|
+
|
|
680
719
|
this.log?.info(`[OpenClawClient] SSE 流结束,总长度: ${fullText.length}`);
|
|
681
720
|
|
|
682
721
|
if (hasError) {
|
|
@@ -706,6 +745,9 @@ class OpenClawClient {
|
|
|
706
745
|
});
|
|
707
746
|
|
|
708
747
|
response.data.on('error', (err) => {
|
|
748
|
+
// 清理活跃请求
|
|
749
|
+
OpenClawClient.activeRequests.delete(fromUser);
|
|
750
|
+
|
|
709
751
|
this.log?.error(`[OpenClawClient] SSE 流错误: ${err.message}`);
|
|
710
752
|
reject(err);
|
|
711
753
|
});
|