@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 +1 -1
- package/src/channel.ts +44 -14
- package/src/client.ts +3 -0
package/package.json
CHANGED
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 =
|
|
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({
|