@ynhcj/xiaoyi 2.4.4 → 2.4.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/dist/channel.js +110 -32
  2. package/package.json +1 -1
package/dist/channel.js CHANGED
@@ -322,6 +322,7 @@ exports.xiaoyiPlugin = {
322
322
  const taskId = runtime.getTaskIdForSession(sessionId) || `task_${Date.now()}`;
323
323
  const startTime = Date.now();
324
324
  let accumulatedText = "";
325
+ let sentTextLength = 0; // Track sent text length for streaming
325
326
  // ==================== CREATE ABORT CONTROLLER ====================
326
327
  // Create AbortController for this session to allow cancelation
327
328
  const { controller: abortController, signal: abortSignal } = runtime.createAbortControllerForSession(sessionId);
@@ -365,15 +366,33 @@ exports.xiaoyiPlugin = {
365
366
  ctx: msgContext,
366
367
  cfg: config,
367
368
  dispatcherOptions: {
368
- deliver: async (payload) => {
369
+ deliver: async (payload, info) => {
369
370
  const elapsed = Date.now() - startTime;
370
371
  const completeText = payload.text || "";
371
372
  accumulatedText = completeText;
373
+ const kind = info.kind; // "tool" | "block" | "final"
374
+ // ==================== DEBUG LOG - ENTRY POINT ====================
375
+ // Log EVERY call to deliver with full details
376
+ console.log("\n" + "█".repeat(70));
377
+ console.log(`📨 [DELIVER ENTRY] deliver() callback invoked`);
378
+ console.log(` Session: ${sessionId}`);
379
+ console.log(` Elapsed: ${elapsed}ms`);
380
+ console.log(` Kind: "${kind}"`);
381
+ console.log(` Text length: ${completeText.length} chars`);
382
+ console.log(` Sent so far: ${sentTextLength} chars`);
383
+ if (completeText.length > 0) {
384
+ console.log(` Text preview: "${completeText.substring(0, 80)}${completeText.length > 80 ? "..." : ""}"`);
385
+ }
386
+ console.log(` Full info object:`, JSON.stringify(info, null, 2));
387
+ console.log(` Full payload keys:`, Object.keys(payload));
388
+ console.log("█".repeat(70) + "\n");
389
+ // =================================================================
372
390
  // Check if session was aborted
373
391
  if (runtime.isSessionAborted(sessionId)) {
374
392
  console.log("\n" + "=".repeat(60));
375
393
  console.log(`[ABORT] Response received AFTER abort`);
376
394
  console.log(` Session: ${sessionId}`);
395
+ console.log(` Kind: ${kind}`);
377
396
  console.log(` Elapsed: ${elapsed}ms`);
378
397
  console.log(` Action: DISCARDING (session was canceled)`);
379
398
  console.log("=".repeat(60) + "\n");
@@ -385,6 +404,7 @@ exports.xiaoyiPlugin = {
385
404
  console.log("\n" + "=".repeat(60));
386
405
  console.log(`[TIMEOUT] Response received AFTER timeout`);
387
406
  console.log(` Session: ${sessionId}`);
407
+ console.log(` Kind: ${kind}`);
388
408
  console.log(` Elapsed: ${elapsed}ms`);
389
409
  console.log(` Action: DISCARDING (timeout message already sent)`);
390
410
  console.log("=".repeat(60) + "\n");
@@ -394,47 +414,105 @@ exports.xiaoyiPlugin = {
394
414
  // If response is empty, don't clear timeout (let it trigger)
395
415
  if (!completeText || completeText.length === 0) {
396
416
  console.log("\n" + "=".repeat(60));
397
- console.log(`[TIMEOUT] Empty response detected`);
417
+ console.log(`[STREAM] Empty ${kind} response detected`);
398
418
  console.log(` Session: ${sessionId}`);
399
419
  console.log(` Elapsed: ${elapsed}ms`);
400
- console.log(` Action: KEEPING TIMEOUT (session conflict detected)`);
420
+ console.log(` Action: SKIPPING (empty response)`);
401
421
  console.log("=".repeat(60) + "\n");
402
422
  // Don't send anything, and don't clear timeout
403
423
  return;
404
424
  }
405
- console.log("\n" + "-".repeat(60));
406
- console.log(`XiaoYi: [DELIVER] AI response received`);
407
- console.log(` Elapsed: ${elapsed}ms`);
408
- console.log(` Length: ${completeText.length} chars`);
409
- console.log(` Preview: ${completeText.substring(0, 100)}...`);
410
- console.log("-".repeat(60) + "\n");
411
- // Send final response to XiaoYi
412
- const response = {
413
- sessionId: sessionId,
414
- messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
415
- timestamp: Date.now(),
416
- agentId: resolvedAccount.config.agentId,
417
- sender: {
418
- id: resolvedAccount.config.agentId,
419
- name: "OpenClaw Agent",
420
- type: "agent",
421
- },
422
- content: {
423
- type: "text",
424
- text: accumulatedText,
425
- },
426
- status: "success",
427
- };
428
425
  const conn = runtime.getConnection();
429
- if (conn) {
426
+ if (!conn) {
427
+ console.error(`✗ XiaoYi: Connection not available\n`);
428
+ return;
429
+ }
430
+ // ==================== STREAMING LOGIC ====================
431
+ // For "block" kind: send incremental text (streaming)
432
+ // For "final" kind: send complete text (final message)
433
+ if (kind === "block") {
434
+ // Calculate incremental text
435
+ const incrementalText = completeText.slice(sentTextLength);
436
+ if (incrementalText.length > 0) {
437
+ console.log("\n" + "-".repeat(60));
438
+ console.log(`XiaoYi: [STREAM] Incremental block received`);
439
+ console.log(` Session: ${sessionId}`);
440
+ console.log(` Elapsed: ${elapsed}ms`);
441
+ console.log(` Total length: ${completeText.length} chars`);
442
+ console.log(` Incremental: +${incrementalText.length} chars (sent: ${sentTextLength})`);
443
+ console.log(` Preview: "${incrementalText.substring(0, 50)}${incrementalText.length > 50 ? "..." : ""}"`);
444
+ console.log("-".repeat(60) + "\n");
445
+ const response = {
446
+ sessionId: sessionId,
447
+ messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
448
+ timestamp: Date.now(),
449
+ agentId: resolvedAccount.config.agentId,
450
+ sender: {
451
+ id: resolvedAccount.config.agentId,
452
+ name: "OpenClaw Agent",
453
+ type: "agent",
454
+ },
455
+ content: {
456
+ type: "text",
457
+ text: incrementalText,
458
+ },
459
+ status: "success",
460
+ };
461
+ // Send incremental text, NOT final, append mode
462
+ await conn.sendResponse(response, taskId, sessionId, false, true);
463
+ console.log(`✓ XiaoYi: Stream chunk sent (+${incrementalText.length} chars)\n`);
464
+ // Update sent length
465
+ sentTextLength = completeText.length;
466
+ }
467
+ else {
468
+ console.log("\n" + "-".repeat(60));
469
+ console.log(`XiaoYi: [STREAM] No new text to send`);
470
+ console.log(` Session: ${sessionId}`);
471
+ console.log(` Total length: ${completeText.length} chars`);
472
+ console.log(` Already sent: ${sentTextLength} chars`);
473
+ console.log("-".repeat(60) + "\n");
474
+ }
475
+ }
476
+ else if (kind === "final") {
477
+ console.log("\n" + "=".repeat(60));
478
+ console.log(`XiaoYi: [STREAM] Final response received`);
479
+ console.log(` Session: ${sessionId}`);
480
+ console.log(` Elapsed: ${elapsed}ms`);
481
+ console.log(` Total length: ${completeText.length} chars`);
482
+ console.log(` Preview: "${completeText.substring(0, 100)}..."`);
483
+ console.log("=".repeat(60) + "\n");
484
+ const response = {
485
+ sessionId: sessionId,
486
+ messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
487
+ timestamp: Date.now(),
488
+ agentId: resolvedAccount.config.agentId,
489
+ sender: {
490
+ id: resolvedAccount.config.agentId,
491
+ name: "OpenClaw Agent",
492
+ type: "agent",
493
+ },
494
+ content: {
495
+ type: "text",
496
+ text: completeText,
497
+ },
498
+ status: "success",
499
+ };
500
+ // Send complete text as FINAL, NOT append
430
501
  await conn.sendResponse(response, taskId, sessionId, true, false);
431
- console.log(`✓ XiaoYi: Response sent successfully\n`);
502
+ console.log(`✓ XiaoYi: Final response sent (${completeText.length} chars)\n`);
503
+ // Clear timeout and abort controller on final
504
+ runtime.markSessionCompleted(sessionId);
505
+ // Note: Don't clear abort controller here, let onIdle handle it
506
+ // This ensures we can still abort if there's any pending cleanup
432
507
  }
433
- else {
434
- console.error(`✗ XiaoYi: Connection not available\n`);
508
+ else if (kind === "tool") {
509
+ // Tool results - typically not sent as messages
510
+ console.log("\n" + "-".repeat(60));
511
+ console.log(`XiaoYi: [STREAM] Tool result received (not forwarded)`);
512
+ console.log(` Session: ${sessionId}`);
513
+ console.log(` Elapsed: ${elapsed}ms`);
514
+ console.log("-".repeat(60) + "\n");
435
515
  }
436
- // Clear timeout as response was sent successfully
437
- runtime.markSessionCompleted(sessionId);
438
516
  },
439
517
  onIdle: async () => {
440
518
  const elapsed = Date.now() - startTime;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi",
3
- "version": "2.4.4",
3
+ "version": "2.4.6",
4
4
  "description": "XiaoYi channel plugin for OpenClaw",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",