@eyeclaw/eyeclaw 2.3.0 → 2.3.2

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/index.ts CHANGED
@@ -25,9 +25,9 @@ const eyeclawPlugin = {
25
25
  // 解析配置
26
26
  const rawConfig = api.config?.plugins?.entries?.eyeclaw?.config
27
27
  const config: EyeClawConfig = {
28
- sdkToken: rawConfig?.sdkToken || '',
28
+ sdkToken: rawConfig?.sdkToken as string || '',
29
29
  botId: rawConfig?.botId ? String(rawConfig.botId) : '',
30
- serverUrl: rawConfig?.serverUrl || '',
30
+ serverUrl: rawConfig?.serverUrl as string || '',
31
31
  }
32
32
 
33
33
  // 获取 Gateway 端口
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eyeclaw/eyeclaw",
3
- "version": "2.3.0",
3
+ "version": "2.3.2",
4
4
  "description": "EyeClaw plugin for OpenClaw - HTTP SSE streaming + WebSocket client",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -215,6 +215,7 @@ export class EyeClawWebSocketClient {
215
215
 
216
216
  const decoder = new TextDecoder()
217
217
  let buffer = ''
218
+ let currentEvent = ''
218
219
 
219
220
  // 解析 SSE 流式响应
220
221
  while (true) {
@@ -229,38 +230,49 @@ export class EyeClawWebSocketClient {
229
230
  const trimmed = line.trim()
230
231
 
231
232
  // 跳过空行和注释
232
- if (!trimmed || trimmed.startsWith(':')) continue
233
+ if (!trimmed || trimmed.startsWith(':')) {
234
+ // 空行表示事件结束,重置 currentEvent
235
+ if (!trimmed) {
236
+ currentEvent = ''
237
+ }
238
+ continue
239
+ }
233
240
 
234
- // 解析 SSE 事件
241
+ // 解析 SSE 事件类型
235
242
  if (trimmed.startsWith('event: ')) {
236
- const eventType = trimmed.slice(7).trim()
243
+ currentEvent = trimmed.slice(7).trim()
237
244
  continue
238
245
  }
239
246
 
247
+ // 解析 SSE 数据
240
248
  if (trimmed.startsWith('data: ')) {
241
249
  const data = trimmed.slice(6)
242
250
 
243
251
  try {
244
252
  const eventData = JSON.parse(data)
245
253
 
246
- // stream_chunk 事件:包含内容
247
- if (eventData.content) {
254
+ // stream_chunk 事件:发送内容
255
+ if (currentEvent === 'stream_chunk' && eventData.content) {
248
256
  this.sendChunk(eventData.content, sessionId)
249
257
  }
250
258
 
251
- // stream_end 事件:结束
252
- if (eventData.stream_id && !eventData.content) {
253
- // 流结束
259
+ // stream_end 事件:流结束(由 HTTP handler 发送)
260
+ if (currentEvent === 'stream_end') {
261
+ this.api.logger.info(`[EyeClaw] Stream ended: ${eventData.stream_id}`)
254
262
  }
255
- } catch {
256
- // 忽略无法解析的数据
263
+
264
+ // stream_error 事件:错误
265
+ if (currentEvent === 'stream_error') {
266
+ this.api.logger.error(`[EyeClaw] Stream error: ${eventData.error}`)
267
+ }
268
+ } catch (e) {
269
+ this.api.logger.warn(`[EyeClaw] Failed to parse SSE data: ${data}`)
257
270
  }
258
271
  }
259
272
  }
260
273
  }
261
274
 
262
- // 发送完成信号
263
- this.sendMessage('stream_end', { session_id: sessionId })
275
+ this.api.logger.info(`[EyeClaw] Stream processing completed for session: ${sessionId}`)
264
276
 
265
277
  } catch (error) {
266
278
  const errorMsg = error instanceof Error ? error.message : String(error)
@@ -281,8 +293,7 @@ export class EyeClawWebSocketClient {
281
293
  * 发送流式内容块到 Rails
282
294
  */
283
295
  private sendChunk(content: string, sessionId?: string) {
284
- this.send({
285
- type: 'stream_chunk',
296
+ this.sendMessage('stream_chunk', {
286
297
  content,
287
298
  session_id: sessionId,
288
299
  })