@eyeclaw/eyeclaw 2.4.4 → 2.4.6

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eyeclaw/eyeclaw",
3
- "version": "2.4.4",
3
+ "version": "2.4.6",
4
4
  "description": "EyeClaw plugin for OpenClaw - HTTP SSE streaming + WebSocket client",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -63,6 +63,23 @@ export class EyeClawWebSocketClient {
63
63
  return
64
64
  }
65
65
 
66
+ // 如果已经有活跃的 WebSocket,不重复创建
67
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
68
+ this.api.logger?.debug?.('[EyeClaw] WebSocket already connected, skipping')
69
+ return
70
+ }
71
+
72
+ // 清理旧的 WebSocket 实例
73
+ if (this.ws) {
74
+ this.api.logger?.debug?.('[EyeClaw] Cleaning up old WebSocket instance')
75
+ try {
76
+ this.ws.close()
77
+ } catch (e) {
78
+ // 忽略关闭错误
79
+ }
80
+ this.ws = null
81
+ }
82
+
66
83
  // 启动网络状态监控
67
84
  this.startNetworkMonitoring()
68
85
 
@@ -79,6 +96,7 @@ export class EyeClawWebSocketClient {
79
96
  this.consecutiveFailures = 0 // 重置连续失败计数
80
97
  this.lastConnectedAt = Date.now()
81
98
  this.wasConnected = true
99
+ this.lastCloseCode = 0 // 重置关闭码
82
100
 
83
101
  // 如果检测到部署重启(之前已连接过),立即触发一次快速心跳
84
102
  if (this.deploymentDetected) {
@@ -189,19 +207,20 @@ export class EyeClawWebSocketClient {
189
207
  * 检测网络状态并在需要时触发重连
190
208
  */
191
209
  private async checkNetworkAndReconnectIfNeeded() {
192
- // 如果 WebSocket 已经连接,跳过(不需要重连)
193
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
210
+ // 如果正在重连中,跳过(防止重复调度)
211
+ if (this.reconnecting) {
194
212
  return
195
213
  }
196
214
 
197
- // 如果正在重连中,跳过
198
- if (this.reconnecting) {
215
+ // 如果 WebSocket 已经连接,跳过(不需要重连)
216
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
199
217
  return
200
218
  }
201
219
 
202
220
  try {
203
221
  // 尝试一个简单的 HTTP 请求来检测网络是否可用
204
- const serverUrl = this.config.serverUrl.replace(/^ws/, 'http').replace(/^wss/, 'https')
222
+ // 直接使用配置的 serverUrl,不需要转换
223
+ const serverUrl = this.config.serverUrl
205
224
  const controller = new AbortController()
206
225
  const timeoutId = setTimeout(() => controller.abort(), 3000)
207
226
 
@@ -716,6 +735,11 @@ export class EyeClawWebSocketClient {
716
735
  * 如果连接异常,自动触发重连
717
736
  */
718
737
  private checkConnectionHealth() {
738
+ // 如果已经在重连中,跳过
739
+ if (this.reconnecting) {
740
+ return
741
+ }
742
+
719
743
  if (!this.ws) {
720
744
  this.api.logger?.warn?.('[EyeClaw] ⚠️ No WebSocket instance')
721
745
  this.scheduleReconnect()
@@ -779,9 +803,12 @@ export class EyeClawWebSocketClient {
779
803
  this.reconnectTimer = null
780
804
  }
781
805
 
806
+ // 如果已经在重连中,不要重复调度
782
807
  if (this.reconnecting) {
808
+ this.api.logger?.debug?.('[EyeClaw] Already reconnecting, skipping duplicate schedule')
783
809
  return
784
810
  }
811
+
785
812
  this.reconnecting = true
786
813
 
787
814
  // 如果超过最大重试次数,继续重试
@@ -852,7 +879,8 @@ export class EyeClawWebSocketClient {
852
879
 
853
880
  try {
854
881
  // 尝试 HTTP 健康检查
855
- const serverUrl = this.config.serverUrl.replace(/^ws/, 'http').replace(/^wss/, 'https')
882
+ // 直接使用配置的 serverUrl,不需要转换
883
+ const serverUrl = this.config.serverUrl
856
884
  const healthUrl = `${serverUrl}/api/v1/health`
857
885
 
858
886
  const controller = new AbortController()