@yeaft/webchat-agent 0.0.16 → 0.0.18
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/connection.js +41 -3
- package/context.js +3 -0
- package/package.json +1 -1
package/connection.js
CHANGED
|
@@ -17,10 +17,28 @@ import {
|
|
|
17
17
|
sendConversationList
|
|
18
18
|
} from './conversation.js';
|
|
19
19
|
|
|
20
|
+
// 需要在断连期间缓冲的消息类型(Claude 输出相关的关键消息)
|
|
21
|
+
const BUFFERABLE_TYPES = new Set([
|
|
22
|
+
'claude_output', 'turn_completed', 'conversation_closed',
|
|
23
|
+
'session_id_update', 'compact_status', 'slash_commands_update',
|
|
24
|
+
'background_task_started', 'background_task_output'
|
|
25
|
+
]);
|
|
26
|
+
|
|
20
27
|
// Send message to server (with encryption if available)
|
|
28
|
+
// 断连时对关键消息类型进行缓冲,重连后自动 flush
|
|
21
29
|
async function sendToServer(msg) {
|
|
22
30
|
if (!ctx.ws || ctx.ws.readyState !== WebSocket.OPEN) {
|
|
23
|
-
|
|
31
|
+
// 缓冲关键消息
|
|
32
|
+
if (BUFFERABLE_TYPES.has(msg.type)) {
|
|
33
|
+
if (ctx.messageBuffer.length < ctx.messageBufferMaxSize) {
|
|
34
|
+
ctx.messageBuffer.push(msg);
|
|
35
|
+
console.log(`[WS] Buffered message: ${msg.type} (queue: ${ctx.messageBuffer.length})`);
|
|
36
|
+
} else {
|
|
37
|
+
console.warn(`[WS] Buffer full (${ctx.messageBufferMaxSize}), dropping: ${msg.type}`);
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
console.warn(`[WS] Cannot send message, WebSocket not open: ${msg.type}`);
|
|
41
|
+
}
|
|
24
42
|
return;
|
|
25
43
|
}
|
|
26
44
|
|
|
@@ -28,14 +46,31 @@ async function sendToServer(msg) {
|
|
|
28
46
|
if (ctx.sessionKey) {
|
|
29
47
|
const encrypted = await encrypt(msg, ctx.sessionKey);
|
|
30
48
|
ctx.ws.send(JSON.stringify(encrypted));
|
|
31
|
-
console.log(`[WS] Sent encrypted message: ${msg.type}`);
|
|
32
49
|
} else {
|
|
33
50
|
ctx.ws.send(JSON.stringify(msg));
|
|
34
|
-
console.log(`[WS] Sent plain message: ${msg.type}`);
|
|
35
51
|
}
|
|
36
52
|
} catch (e) {
|
|
37
53
|
console.error(`[WS] Error sending message ${msg.type}:`, e.message);
|
|
54
|
+
// 发送失败也缓冲
|
|
55
|
+
if (BUFFERABLE_TYPES.has(msg.type) && ctx.messageBuffer.length < ctx.messageBufferMaxSize) {
|
|
56
|
+
ctx.messageBuffer.push(msg);
|
|
57
|
+
console.log(`[WS] Send failed, buffered: ${msg.type}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Flush 断连期间缓冲的消息
|
|
63
|
+
async function flushMessageBuffer() {
|
|
64
|
+
if (ctx.messageBuffer.length === 0) return;
|
|
65
|
+
|
|
66
|
+
const buffered = ctx.messageBuffer.splice(0);
|
|
67
|
+
console.log(`[WS] Flushing ${buffered.length} buffered messages...`);
|
|
68
|
+
|
|
69
|
+
for (const msg of buffered) {
|
|
70
|
+
await sendToServer(msg);
|
|
38
71
|
}
|
|
72
|
+
|
|
73
|
+
console.log(`[WS] Flush complete`);
|
|
39
74
|
}
|
|
40
75
|
|
|
41
76
|
// Parse incoming message (decrypt if encrypted)
|
|
@@ -80,6 +115,9 @@ async function handleMessage(msg) {
|
|
|
80
115
|
|
|
81
116
|
sendConversationList();
|
|
82
117
|
|
|
118
|
+
// ★ Flush 断连期间缓冲的消息
|
|
119
|
+
await flushMessageBuffer();
|
|
120
|
+
|
|
83
121
|
// ★ Phase 1: 通知 server 同步完成
|
|
84
122
|
sendToServer({ type: 'agent_sync_complete' });
|
|
85
123
|
break;
|
package/context.js
CHANGED
|
@@ -19,6 +19,9 @@ export default {
|
|
|
19
19
|
pendingAuthTempId: null,
|
|
20
20
|
agentHeartbeatTimer: null,
|
|
21
21
|
lastPongAt: 0,
|
|
22
|
+
// 断连期间的消息缓冲队列(重连后 flush)
|
|
23
|
+
messageBuffer: [],
|
|
24
|
+
messageBufferMaxSize: 5000, // 防止内存无限增长
|
|
22
25
|
// 由 connection.js 注册的通信函数
|
|
23
26
|
sendToServer: null,
|
|
24
27
|
// 由 index.js 注册的配置保存函数
|