@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 +2 -2
- package/package.json +1 -1
- package/src/websocket-client.ts +25 -14
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
package/src/websocket-client.ts
CHANGED
|
@@ -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(':'))
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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.
|
|
285
|
-
type: 'stream_chunk',
|
|
296
|
+
this.sendMessage('stream_chunk', {
|
|
286
297
|
content,
|
|
287
298
|
session_id: sessionId,
|
|
288
299
|
})
|