@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.
- package/dist/channel.js +110 -32
- 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(`[
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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;
|