@ynhcj/xiaoyi 2.4.6 → 2.4.8
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 +52 -11
- package/package.json +6 -6
package/dist/channel.js
CHANGED
|
@@ -323,6 +323,7 @@ exports.xiaoyiPlugin = {
|
|
|
323
323
|
const startTime = Date.now();
|
|
324
324
|
let accumulatedText = "";
|
|
325
325
|
let sentTextLength = 0; // Track sent text length for streaming
|
|
326
|
+
let hasSentFinal = false; // Track if final content has been sent (to prevent duplicate isFinal=true)
|
|
326
327
|
// ==================== CREATE ABORT CONTROLLER ====================
|
|
327
328
|
// Create AbortController for this session to allow cancelation
|
|
328
329
|
const { controller: abortController, signal: abortSignal } = runtime.createAbortControllerForSession(sessionId);
|
|
@@ -479,8 +480,16 @@ exports.xiaoyiPlugin = {
|
|
|
479
480
|
console.log(` Session: ${sessionId}`);
|
|
480
481
|
console.log(` Elapsed: ${elapsed}ms`);
|
|
481
482
|
console.log(` Total length: ${completeText.length} chars`);
|
|
483
|
+
console.log(` Has already sent final: ${hasSentFinal}`);
|
|
482
484
|
console.log(` Preview: "${completeText.substring(0, 100)}..."`);
|
|
483
485
|
console.log("=".repeat(60) + "\n");
|
|
486
|
+
// Check if we've already sent final content - prevent duplicate isFinal=true
|
|
487
|
+
if (hasSentFinal) {
|
|
488
|
+
console.log(`XiaoYi: [STREAM] Skipping duplicate final response (already sent)\n`);
|
|
489
|
+
// Don't send anything, but clear timeout to prevent timeout warnings
|
|
490
|
+
runtime.clearSessionTimeout(sessionId);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
484
493
|
const response = {
|
|
485
494
|
sessionId: sessionId,
|
|
486
495
|
messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
@@ -497,13 +506,16 @@ exports.xiaoyiPlugin = {
|
|
|
497
506
|
},
|
|
498
507
|
status: "success",
|
|
499
508
|
};
|
|
500
|
-
// Send complete text as
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
//
|
|
509
|
+
// Send complete text but NOT as final yet - use append mode to keep stream alive
|
|
510
|
+
// The true isFinal=true will be sent in onIdle callback
|
|
511
|
+
await conn.sendResponse(response, taskId, sessionId, false, true);
|
|
512
|
+
console.log(`✓ XiaoYi: Final response content sent (${completeText.length} chars, stream kept alive)\n`);
|
|
513
|
+
// Mark that we've sent the final content
|
|
514
|
+
hasSentFinal = true;
|
|
515
|
+
// Clear timeout to prevent timeout warnings, but don't mark session as completed yet
|
|
516
|
+
runtime.clearSessionTimeout(sessionId);
|
|
517
|
+
// Note: We DON'T call markSessionCompleted here
|
|
518
|
+
// The session will be marked completed in onIdle when we send isFinal=true
|
|
507
519
|
}
|
|
508
520
|
else if (kind === "tool") {
|
|
509
521
|
// Tool results - typically not sent as messages
|
|
@@ -520,15 +532,44 @@ exports.xiaoyiPlugin = {
|
|
|
520
532
|
console.log(`XiaoYi: [IDLE] Processing complete`);
|
|
521
533
|
console.log(` Total time: ${elapsed}ms`);
|
|
522
534
|
console.log(` Final length: ${accumulatedText.length} chars`);
|
|
523
|
-
|
|
524
|
-
//
|
|
535
|
+
console.log(` Has sent final: ${hasSentFinal}`);
|
|
536
|
+
// Only send final close message if we have valid content
|
|
525
537
|
if (accumulatedText.length > 0) {
|
|
538
|
+
const conn = runtime.getConnection();
|
|
539
|
+
if (conn) {
|
|
540
|
+
try {
|
|
541
|
+
// Send the true final response with isFinal=true to properly close the stream
|
|
542
|
+
const finalResponse = {
|
|
543
|
+
sessionId: sessionId,
|
|
544
|
+
messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
545
|
+
timestamp: Date.now(),
|
|
546
|
+
agentId: resolvedAccount.config.agentId,
|
|
547
|
+
sender: {
|
|
548
|
+
id: resolvedAccount.config.agentId,
|
|
549
|
+
name: "OpenClaw Agent",
|
|
550
|
+
type: "agent",
|
|
551
|
+
},
|
|
552
|
+
content: {
|
|
553
|
+
type: "text",
|
|
554
|
+
text: accumulatedText,
|
|
555
|
+
},
|
|
556
|
+
status: "success",
|
|
557
|
+
};
|
|
558
|
+
// Send with isFinal=true to properly close the A2A communication stream
|
|
559
|
+
await conn.sendResponse(finalResponse, taskId, sessionId, true, false);
|
|
560
|
+
console.log(`✓ XiaoYi: True isFinal=true sent to close stream\n`);
|
|
561
|
+
}
|
|
562
|
+
catch (error) {
|
|
563
|
+
console.error(`✗ XiaoYi: Failed to send final close message:`, error);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
// Now mark session as completed and clean up
|
|
526
567
|
runtime.markSessionCompleted(sessionId);
|
|
527
568
|
runtime.clearAbortControllerForSession(sessionId);
|
|
528
|
-
console.log(`[TIMEOUT]
|
|
569
|
+
console.log(`[TIMEOUT] Session completed and cleaned up\n`);
|
|
529
570
|
}
|
|
530
571
|
else {
|
|
531
|
-
console.log(`[TIMEOUT]
|
|
572
|
+
console.log(`[TIMEOUT] No valid response, keeping timeout active\n`);
|
|
532
573
|
}
|
|
533
574
|
console.log("=".repeat(60) + "\n");
|
|
534
575
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ynhcj/xiaoyi",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.8",
|
|
4
4
|
"description": "XiaoYi channel plugin for OpenClaw",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
"extensions": ["xiaoyi.js"],
|
|
21
21
|
"channels": ["xiaoyi"],
|
|
22
22
|
"installDependencies": true,
|
|
23
|
+
"install": {
|
|
24
|
+
"npmSpec": "@ynhcj/xiaoyi",
|
|
25
|
+
"localPath": ".",
|
|
26
|
+
"defaultChoice": "npm"
|
|
27
|
+
},
|
|
23
28
|
"channel": {
|
|
24
29
|
"id": "xiaoyi",
|
|
25
30
|
"label": "XiaoYi",
|
|
@@ -29,11 +34,6 @@
|
|
|
29
34
|
"blurb": "小艺 A2A 协议支持,通过 WebSocket 连接。",
|
|
30
35
|
"order": 80,
|
|
31
36
|
"aliases": ["xy"]
|
|
32
|
-
},
|
|
33
|
-
"install": {
|
|
34
|
-
"npmSpec": "@ynhcj/xiaoyi",
|
|
35
|
-
"localPath": ".",
|
|
36
|
-
"defaultChoice": "npm"
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|