@ynhcj/xiaoyi 2.2.3 → 2.2.5

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/dist/channel.js +13 -165
  2. package/package.json +1 -1
package/dist/channel.js CHANGED
@@ -3,21 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.xiaoyiPlugin = void 0;
4
4
  const runtime_1 = require("./runtime");
5
5
  const file_handler_1 = require("./file-handler");
6
- // Import agent event functions - will be resolved at runtime
7
- // Use dynamic require for compatibility
8
- let onAgentEvent = null;
9
- let registerAgentRunContext = null;
10
- try {
11
- // Try to import from the built openclaw package
12
- const agentEvents = require("openclaw/dist/infra/agent-events");
13
- onAgentEvent = agentEvents.onAgentEvent;
14
- registerAgentRunContext = agentEvents.registerAgentRunContext;
15
- console.log("XiaoYi: [AGENT EVENT] Successfully imported agent event functions");
16
- }
17
- catch (error) {
18
- console.warn("XiaoYi: [AGENT EVENT] Could not import agent event functions:", error);
19
- console.warn("XiaoYi: [AGENT EVENT] Streaming will be disabled");
20
- }
21
6
  /**
22
7
  * XiaoYi Channel Plugin
23
8
  * Implements OpenClaw ChannelPlugin interface for XiaoYi A2A protocol
@@ -322,166 +307,33 @@ exports.xiaoyiPlugin = {
322
307
  SenderId: senderId,
323
308
  OriginatingChannel: "xiaoyi",
324
309
  };
325
- // Use the correct API to dispatch the message (streaming via onAgentEvent)
310
+ // Dispatch message using OpenClaw's reply dispatcher
326
311
  try {
327
- const streamingEnabled = resolvedAccount.config.enableStreaming === true;
328
- const hasAgentEventSupport = typeof onAgentEvent === "function";
329
312
  console.log("\n" + "=".repeat(60));
330
- console.log(`XiaoYi: [STREAMING] Starting message processing`);
313
+ console.log(`XiaoYi: [MESSAGE] Processing user message`);
331
314
  console.log(` Session: ${message.sessionId}`);
332
315
  console.log(` Task ID: ${message.params.id}`);
333
316
  console.log(` User input: ${bodyText.substring(0, 50)}${bodyText.length > 50 ? "..." : ""}`);
334
- console.log(` Config Streaming: ${streamingEnabled ? "ENABLED" : "DISABLED"}`);
335
- console.log(` Agent Event Support: ${hasAgentEventSupport ? "AVAILABLE" : "NOT AVAILABLE"}`);
336
- console.log(` Effective Streaming: ${streamingEnabled && hasAgentEventSupport ? "ENABLED (via onAgentEvent)" : "DISABLED"}`);
317
+ console.log(` Images: ${images.length}`);
337
318
  console.log("=".repeat(60) + "\n");
338
- // Track response state for streaming
339
- let accumulatedText = "";
340
- let taskId = runtime.getTaskIdForSession(message.sessionId) || `task_${Date.now()}`;
341
- let frameCount = 0;
342
- let partialCount = 0;
319
+ const taskId = runtime.getTaskIdForSession(message.sessionId) || `task_${Date.now()}`;
343
320
  const startTime = Date.now();
344
- // Register agent event listener for streaming (NEW METHOD)
345
- let unsubscribeAgentEvents;
346
- let runId;
347
- let isCompleted = false;
348
- if (streamingEnabled && hasAgentEventSupport) {
349
- // Subscribe to agent events BEFORE dispatching the message
350
- unsubscribeAgentEvents = onAgentEvent((evt) => {
351
- if (isCompleted)
352
- return;
353
- // Get runId from first event
354
- if (!runId && evt.runId) {
355
- runId = evt.runId;
356
- console.log(`XiaoYi: [AGENT EVENT] Registered runId: ${runId}`);
357
- }
358
- // Only process events for this run
359
- if (runId && evt.runId !== runId)
360
- return;
361
- const elapsed = Date.now() - startTime;
362
- // Handle streaming text events
363
- if (evt.stream === "assistant" && typeof evt.data?.text === "string") {
364
- const newText = evt.data.text;
365
- if (!newText)
366
- return;
367
- // Calculate delta text
368
- const previousLength = accumulatedText.length;
369
- accumulatedText = newText;
370
- const deltaText = newText.slice(previousLength);
371
- console.log(`\n>>> XiaoYi: [AGENT EVENT] Stream frame #${++partialCount} at ${elapsed}ms`);
372
- console.log(` Run ID: ${evt.runId}`);
373
- console.log(` Delta length: ${deltaText.length} chars`);
374
- console.log(` Total length: ${newText.length} chars`);
375
- console.log(` Delta content: "${deltaText}"`);
376
- // Send PARTIAL frame with delta content
377
- const partialResponse = {
378
- sessionId: message.sessionId,
379
- messageId: `partial_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
380
- timestamp: Date.now(),
381
- agentId: resolvedAccount.config.agentId,
382
- sender: {
383
- id: resolvedAccount.config.agentId,
384
- name: "OpenClaw Agent",
385
- type: "agent",
386
- },
387
- content: {
388
- type: "text",
389
- text: deltaText || newText,
390
- },
391
- status: "processing",
392
- };
393
- const conn = runtime.getConnection();
394
- if (conn) {
395
- conn.sendResponse(partialResponse, taskId, message.sessionId, false, true)
396
- .then(() => {
397
- console.log(` ✓ SENT (isFinal=false, append=true)\n`);
398
- })
399
- .catch((err) => {
400
- console.error(` ✗ Send failed: ${err}\n`);
401
- });
402
- }
403
- }
404
- // Handle lifecycle events (completion/error)
405
- if (evt.stream === "lifecycle") {
406
- const phase = evt.data?.phase;
407
- if (phase === "end") {
408
- isCompleted = true;
409
- console.log("\n" + "-".repeat(60));
410
- console.log(`XiaoYi: [AGENT EVENT] Lifecycle phase: end`);
411
- console.log(` Run ID: ${evt.runId}`);
412
- console.log(` Elapsed: ${elapsed}ms`);
413
- console.log(` Total frames: ${partialCount}`);
414
- console.log(` Final length: ${accumulatedText.length} chars`);
415
- console.log("-".repeat(60) + "\n");
416
- // Send FINAL frame
417
- const response = {
418
- sessionId: message.sessionId,
419
- messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
420
- timestamp: Date.now(),
421
- agentId: resolvedAccount.config.agentId,
422
- sender: {
423
- id: resolvedAccount.config.agentId,
424
- name: "OpenClaw Agent",
425
- type: "agent",
426
- },
427
- content: {
428
- type: "text",
429
- text: accumulatedText,
430
- },
431
- status: "success",
432
- };
433
- const conn = runtime.getConnection();
434
- if (conn) {
435
- conn.sendResponse(response, taskId, message.sessionId, true, false)
436
- .then(() => {
437
- console.log(`✓ XiaoYi: FINAL frame sent (isFinal=true, append=false)\n`);
438
- })
439
- .catch((err) => {
440
- console.error(`✗ Final send failed: ${err}\n`);
441
- });
442
- }
443
- // Unsubscribe from events
444
- if (unsubscribeAgentEvents) {
445
- unsubscribeAgentEvents();
446
- unsubscribeAgentEvents = undefined;
447
- }
448
- }
449
- else if (phase === "error") {
450
- isCompleted = true;
451
- console.error(`XiaoYi: [AGENT EVENT] Error phase:`, evt.data?.error);
452
- // Unsubscribe from events
453
- if (unsubscribeAgentEvents) {
454
- unsubscribeAgentEvents();
455
- unsubscribeAgentEvents = undefined;
456
- }
457
- }
458
- }
459
- });
460
- console.log(`XiaoYi: [AGENT EVENT] Listener registered for streaming`);
461
- }
462
- else if (streamingEnabled && !hasAgentEventSupport) {
463
- console.warn(`XiaoYi: [WARN] Streaming enabled but onAgentEvent not available, falling back to non-streaming mode`);
464
- }
321
+ let accumulatedText = "";
465
322
  await pluginRuntime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
466
323
  ctx: msgContext,
467
324
  cfg: config,
468
325
  dispatcherOptions: {
469
326
  deliver: async (payload) => {
470
- // This is the fallback for when streaming is disabled
471
- if (streamingEnabled) {
472
- // Streaming mode: deliver is handled by onAgentEvent
473
- console.log(`XiaoYi: [DELIVER] Skipping (handled by onAgentEvent)`);
474
- return;
475
- }
476
327
  const elapsed = Date.now() - startTime;
477
328
  const completeText = payload.text || "";
478
329
  accumulatedText = completeText;
479
330
  console.log("\n" + "-".repeat(60));
480
- console.log(`XiaoYi: [DELIVER] Non-streaming mode`);
331
+ console.log(`XiaoYi: [DELIVER] AI response received`);
481
332
  console.log(` Elapsed: ${elapsed}ms`);
482
333
  console.log(` Length: ${completeText.length} chars`);
334
+ console.log(` Preview: ${completeText.substring(0, 100)}...`);
483
335
  console.log("-".repeat(60) + "\n");
484
- // Send final frame
336
+ // Send final response to XiaoYi
485
337
  const response = {
486
338
  sessionId: message.sessionId,
487
339
  messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
@@ -501,7 +353,10 @@ exports.xiaoyiPlugin = {
501
353
  const conn = runtime.getConnection();
502
354
  if (conn) {
503
355
  await conn.sendResponse(response, taskId, message.sessionId, true, false);
504
- console.log(`✓ XiaoYi: FINAL frame sent (non-streaming)\n`);
356
+ console.log(`✓ XiaoYi: Response sent successfully\n`);
357
+ }
358
+ else {
359
+ console.error(`✗ XiaoYi: Connection not available\n`);
505
360
  }
506
361
  },
507
362
  onIdle: async () => {
@@ -509,18 +364,11 @@ exports.xiaoyiPlugin = {
509
364
  console.log("\n" + "=".repeat(60));
510
365
  console.log(`XiaoYi: [IDLE] Processing complete`);
511
366
  console.log(` Total time: ${elapsed}ms`);
512
- console.log(` Streaming frames: ${partialCount}`);
513
367
  console.log(` Final length: ${accumulatedText.length} chars`);
514
368
  console.log("=".repeat(60) + "\n");
515
- // Cleanup event listener if still active
516
- if (unsubscribeAgentEvents && !isCompleted) {
517
- console.log(`XiaoYi: [IDLE] Cleaning up event listener`);
518
- unsubscribeAgentEvents();
519
- unsubscribeAgentEvents = undefined;
520
- }
521
369
  },
522
370
  },
523
- replyOptions: undefined, // NOT using onPartialReply anymore
371
+ replyOptions: undefined,
524
372
  images: images.length > 0 ? images : undefined,
525
373
  });
526
374
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi",
3
- "version": "2.2.3",
3
+ "version": "2.2.5",
4
4
  "description": "XiaoYi channel plugin for OpenClaw",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",