@eyeclaw/eyeclaw 2.0.5 → 2.0.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/channel.ts +70 -52
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eyeclaw/eyeclaw",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "description": "EyeClaw channel plugin for OpenClaw - Connect your local OpenClaw instance to EyeClaw platform",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
package/src/channel.ts CHANGED
@@ -180,29 +180,28 @@ export const eyeclawPlugin: ChannelPlugin<ResolvedEyeClawAccount> = {
180
180
 
181
181
  // Register OpenClaw Agent callback for chat messages
182
182
  client.setSendAgentCallback(async (message: string) => {
183
+ const { spawn } = await import('child_process')
184
+ const streamId = Date.now().toString()
185
+
183
186
  try {
184
187
  ctx.log?.info(`🤖 Sending message to OpenClaw Agent: ${message}`)
185
188
 
186
- // Call OpenClaw Agent via spawn for streaming output
187
- const { spawn } = await import('child_process')
189
+ // Spawn openclaw agent process for streaming output
190
+ const agentProcess = spawn('openclaw', [
191
+ 'agent',
192
+ '--session-id', 'eyeclaw-web-chat',
193
+ '--message', message,
194
+ '--json'
195
+ ])
188
196
 
189
- try {
190
- // Spawn openclaw agent process for streaming output
191
- const agentProcess = spawn('openclaw', [
192
- 'agent',
193
- '--session-id', 'eyeclaw-web-chat',
194
- '--message', message,
195
- '--json'
196
- ])
197
-
198
- let outputBuffer = ''
199
- let streamId = Date.now().toString()
200
-
201
- // Send stream_start event
202
- client.sendStreamChunk('stream_start', streamId, '')
203
-
204
- // Handle stdout (streaming response)
205
- agentProcess.stdout?.on('data', (data: Buffer) => {
197
+ let outputBuffer = ''
198
+
199
+ // Send stream_start event
200
+ client.sendStreamChunk('stream_start', streamId, '')
201
+
202
+ // Handle stdout (streaming response)
203
+ agentProcess.stdout?.on('data', (data: Buffer) => {
204
+ try {
206
205
  const text = data.toString()
207
206
  outputBuffer += text
208
207
 
@@ -234,35 +233,51 @@ export const eyeclawPlugin: ChannelPlugin<ResolvedEyeClawAccount> = {
234
233
  outputBuffer = lines[lines.length - 1]
235
234
  }
236
235
  }
237
- })
238
-
239
- // Handle stderr (errors)
240
- agentProcess.stderr?.on('data', (data: Buffer) => {
241
- const errorText = data.toString()
242
- ctx.log?.error(`Agent stderr: ${errorText}`)
243
- })
244
-
236
+ } catch (error) {
237
+ // Catch any errors in data processing to prevent WebSocket disconnect
238
+ const errorMsg = error instanceof Error ? error.message : String(error)
239
+ ctx.log?.error(`Error processing stdout data: ${errorMsg}`)
240
+ }
241
+ })
242
+
243
+ // Handle stderr (errors)
244
+ agentProcess.stderr?.on('data', (data: Buffer) => {
245
+ const errorText = data.toString()
246
+ ctx.log?.error(`Agent stderr: ${errorText}`)
247
+ })
248
+
249
+ // Wait for process to complete
250
+ await new Promise<void>((resolve, reject) => {
245
251
  // Handle process completion
246
252
  agentProcess.on('close', (code: number) => {
247
- // Send any remaining buffered content
248
- if (outputBuffer.trim()) {
249
- try {
250
- const parsed = JSON.parse(outputBuffer)
251
- const response = parsed.result?.payloads?.[0]?.text || outputBuffer.trim()
252
- client.sendStreamChunk('stream_chunk', streamId, response)
253
- } catch (e) {
254
- client.sendStreamChunk('stream_chunk', streamId, outputBuffer.trim())
253
+ try {
254
+ // Send any remaining buffered content
255
+ if (outputBuffer.trim()) {
256
+ try {
257
+ const parsed = JSON.parse(outputBuffer)
258
+ const response = parsed.result?.payloads?.[0]?.text || outputBuffer.trim()
259
+ client.sendStreamChunk('stream_chunk', streamId, response)
260
+ } catch (e) {
261
+ client.sendStreamChunk('stream_chunk', streamId, outputBuffer.trim())
262
+ }
255
263
  }
256
- }
257
-
258
- // Send stream_end event
259
- client.sendStreamChunk('stream_end', streamId, '')
260
-
261
- if (code === 0) {
262
- ctx.log?.info(`✅ Agent completed successfully`)
263
- } else {
264
- ctx.log?.error(`Agent exited with code ${code}`)
265
- client.sendLog('error', `❌ Agent error: process exited with code ${code}`)
264
+
265
+ // Send stream_end event
266
+ client.sendStreamChunk('stream_end', streamId, '')
267
+
268
+ if (code === 0) {
269
+ ctx.log?.info(`✅ Agent completed successfully`)
270
+ resolve()
271
+ } else {
272
+ ctx.log?.error(`Agent exited with code ${code}`)
273
+ client.sendLog('error', `❌ Agent error: process exited with code ${code}`)
274
+ reject(new Error(`Agent exited with code ${code}`))
275
+ }
276
+ } catch (error) {
277
+ // Prevent errors in close handler from crashing
278
+ const errorMsg = error instanceof Error ? error.message : String(error)
279
+ ctx.log?.error(`Error in close handler: ${errorMsg}`)
280
+ reject(error)
266
281
  }
267
282
  })
268
283
 
@@ -271,17 +286,20 @@ export const eyeclawPlugin: ChannelPlugin<ResolvedEyeClawAccount> = {
271
286
  ctx.log?.error(`Failed to start agent process: ${error.message}`)
272
287
  client.sendStreamChunk('stream_error', streamId, error.message)
273
288
  client.sendLog('error', `❌ Failed to start agent: ${error.message}`)
289
+ reject(error)
274
290
  })
275
-
276
- } catch (error) {
277
- const errorMsg = error instanceof Error ? error.message : String(error)
278
- ctx.log?.error(`Failed to execute openclaw agent: ${errorMsg}`)
279
- client.sendLog('error', `❌ Agent error: ${errorMsg}`)
280
- }
291
+ })
292
+
281
293
  } catch (error) {
282
294
  const errorMsg = error instanceof Error ? error.message : String(error)
283
295
  ctx.log?.error(`Failed to call OpenClaw Agent: ${errorMsg}`)
284
- client.sendLog('error', `❌ Failed to call agent: ${errorMsg}`)
296
+ // Send error notification but don't crash the WebSocket connection
297
+ try {
298
+ client.sendStreamChunk('stream_error', streamId, errorMsg)
299
+ client.sendLog('error', `❌ Agent error: ${errorMsg}`)
300
+ } catch (sendError) {
301
+ ctx.log?.error(`Failed to send error notification: ${sendError}`)
302
+ }
285
303
  }
286
304
  })
287
305