@yeaft/webchat-agent 0.0.16 → 0.0.17

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 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
- console.warn(`[WS] Cannot send message, WebSocket not open (state: ${ctx.ws?.readyState})`);
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 注册的配置保存函数
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.0.16",
3
+ "version": "0.0.17",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",