@eyeclaw/eyeclaw 2.0.14 → 2.0.15

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.0.14",
3
+ "version": "2.0.15",
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
@@ -202,7 +202,7 @@ export const eyeclawPlugin: ChannelPlugin<ResolvedEyeClawAccount> = {
202
202
  // Use runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher for true streaming
203
203
  client.setSendAgentCallback(async (message: string) => {
204
204
  const streamId = Date.now().toString()
205
- const streamKey = 'eyeclaw-web-chat'
205
+ const streamKey = `eyeclaw-${ctx.accountId}`
206
206
 
207
207
  try {
208
208
  ctx.log?.info(`🤖 Processing message via OpenClaw dispatchReply: ${message}`)
@@ -210,21 +210,51 @@ export const eyeclawPlugin: ChannelPlugin<ResolvedEyeClawAccount> = {
210
210
  // 发送 stream_start
211
211
  client.sendStreamChunk('stream_start', streamId, '')
212
212
 
213
+ // Build message context using OpenClaw's proper API (like WeCom plugin)
214
+ const runtime = getRuntime()
215
+ const core = runtime.channel
216
+
217
+ // Get envelope format options
218
+ const envelopeOptions = core.reply.resolveEnvelopeFormatOptions(ctx.cfg)
219
+
220
+ // Format the message envelope (like WeCom does)
221
+ const body = core.reply.formatAgentEnvelope({
222
+ channel: 'EyeClaw Web',
223
+ from: 'web_user',
224
+ timestamp: Date.now(),
225
+ previousTimestamp: undefined,
226
+ envelope: envelopeOptions,
227
+ body: message,
228
+ })
229
+
230
+ // Build the inbound context payload
231
+ const ctxBase = {
232
+ Body: body,
233
+ RawBody: message,
234
+ CommandBody: message,
235
+ From: `eyeclaw:${streamKey}`,
236
+ To: `eyeclaw:${ctx.accountId}`,
237
+ SessionKey: `eyeclaw:${streamKey}`,
238
+ AccountId: ctx.accountId,
239
+ ChatType: 'direct',
240
+ ConversationLabel: streamKey,
241
+ SenderName: 'web_user',
242
+ SenderId: streamKey,
243
+ Provider: 'eyeclaw',
244
+ Surface: 'eyeclaw',
245
+ OriginatingChannel: 'eyeclaw',
246
+ OriginatingTo: ctx.accountId,
247
+ CommandAuthorized: true,
248
+ }
249
+
250
+ // Finalize the context payload
251
+ const ctxPayload = core.reply.finalizeInboundContext(ctxBase)
252
+
253
+ ctx.log?.info(`Prepared context: SessionKey=${ctxPayload.SessionKey}, Body=${ctxPayload.Body?.substring(0, 50)}`)
254
+
213
255
  // 使用 OpenClaw 的 dispatchReplyWithBufferedBlockDispatcher 实现真正的流式
214
- // 这和 WeCom 插件使用的方式完全相同
215
- // API 路径: runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher
216
256
  await runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
217
- ctx: {
218
- // Inbound message context
219
- sessionKey: `eyeclaw:${streamKey}`,
220
- messageKey: `eyeclaw:${streamKey}:${streamId}`,
221
- peerKey: streamKey,
222
- message: {
223
- role: 'user',
224
- content: message,
225
- roleDetail: 'user',
226
- },
227
- },
257
+ ctx: ctxPayload,
228
258
  cfg: ctx.cfg,
229
259
  dispatcherOptions: {
230
260
  // 流式回调 - LLM 每生成一块文本就实时调用
package/src/client.ts CHANGED
@@ -319,6 +319,8 @@ export class EyeClawClient {
319
319
  }
320
320
 
321
321
  sendStreamChunk(type: string, streamId: string, chunk: string): void {
322
+ this.logger.info(`📤 Sending stream_chunk: type=${type}, streamId=${streamId}, chunk="${chunk.substring(0, 30)}..."`)
323
+
322
324
  // Send to BotChannel which will broadcast to bot_{id} for Rails to receive
323
325
  this.sendChannelMessage('stream_chunk', {
324
326
  type,
@@ -328,6 +330,7 @@ export class EyeClawClient {
328
330
  })
329
331
 
330
332
  // Also broadcast directly to bot_{id} stream as backup (Rails expects stream_type)
333
+ this.logger.info(`📤 Also sending to bot_${this.config.botId} channel`)
331
334
  this.send({
332
335
  command: 'message',
333
336
  identifier: JSON.stringify({