@ynhcj/xiaoyi 2.2.4 → 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.
- package/dist/channel.js +13 -199
- package/package.json +1 -1
package/dist/channel.js
CHANGED
|
@@ -3,57 +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 multiple import paths
|
|
12
|
-
let agentEvents = null;
|
|
13
|
-
// Try path 1: openclaw/dist/infra/agent-events
|
|
14
|
-
try {
|
|
15
|
-
agentEvents = require("openclaw/dist/infra/agent-events");
|
|
16
|
-
console.log("XiaoYi: [AGENT EVENT] Imported from openclaw/dist/infra/agent-events");
|
|
17
|
-
}
|
|
18
|
-
catch (e1) {
|
|
19
|
-
console.log("XiaoYi: [AGENT EVENT] Path 1 failed:", e1?.message || e1);
|
|
20
|
-
// Try path 2: ../openclaw/dist/infra/agent-events
|
|
21
|
-
try {
|
|
22
|
-
agentEvents = require("../openclaw/dist/infra/agent-events");
|
|
23
|
-
console.log("XiaoYi: [AGENT EVENT] Imported from ../openclaw/dist/infra/agent-events");
|
|
24
|
-
}
|
|
25
|
-
catch (e2) {
|
|
26
|
-
console.log("XiaoYi: [AGENT EVENT] Path 2 failed:", e2?.message || e2);
|
|
27
|
-
// Try path 3: ../../openclaw/dist/infra/agent-events
|
|
28
|
-
try {
|
|
29
|
-
agentEvents = require("../../openclaw/dist/infra/agent-events");
|
|
30
|
-
console.log("XiaoYi: [AGENT EVENT] Imported from ../../openclaw/dist/infra/agent-events");
|
|
31
|
-
}
|
|
32
|
-
catch (e3) {
|
|
33
|
-
console.error("XiaoYi: [AGENT EVENT] All import paths failed:");
|
|
34
|
-
console.error(" Path 1 (openclaw/dist/infra/agent-events):", e1?.message || e1);
|
|
35
|
-
console.error(" Path 2 (../openclaw/dist/infra/agent-events):", e2?.message || e2);
|
|
36
|
-
console.error(" Path 3 (../../openclaw/dist/infra/agent-events):", e3?.message || e3);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (agentEvents) {
|
|
41
|
-
onAgentEvent = agentEvents.onAgentEvent;
|
|
42
|
-
registerAgentRunContext = agentEvents.registerAgentRunContext;
|
|
43
|
-
if (typeof onAgentEvent === "function") {
|
|
44
|
-
console.log("XiaoYi: [AGENT EVENT] ✓ onAgentEvent function imported successfully");
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
console.error("XiaoYi: [AGENT EVENT] ✗ onAgentEvent is not a function, type:", typeof onAgentEvent);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
console.warn("XiaoYi: [AGENT EVENT] Could not import agent event module");
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
console.error("XiaoYi: [AGENT EVENT] Fatal import error:", error?.message || error);
|
|
56
|
-
}
|
|
57
6
|
/**
|
|
58
7
|
* XiaoYi Channel Plugin
|
|
59
8
|
* Implements OpenClaw ChannelPlugin interface for XiaoYi A2A protocol
|
|
@@ -358,164 +307,33 @@ exports.xiaoyiPlugin = {
|
|
|
358
307
|
SenderId: senderId,
|
|
359
308
|
OriginatingChannel: "xiaoyi",
|
|
360
309
|
};
|
|
361
|
-
//
|
|
310
|
+
// Dispatch message using OpenClaw's reply dispatcher
|
|
362
311
|
try {
|
|
363
|
-
const streamingEnabled = resolvedAccount.config.enableStreaming === true;
|
|
364
|
-
const hasAgentEventSupport = typeof onAgentEvent === "function";
|
|
365
312
|
console.log("\n" + "=".repeat(60));
|
|
366
|
-
console.log(`XiaoYi: [
|
|
313
|
+
console.log(`XiaoYi: [MESSAGE] Processing user message`);
|
|
367
314
|
console.log(` Session: ${message.sessionId}`);
|
|
368
315
|
console.log(` Task ID: ${message.params.id}`);
|
|
369
316
|
console.log(` User input: ${bodyText.substring(0, 50)}${bodyText.length > 50 ? "..." : ""}`);
|
|
370
|
-
console.log(`
|
|
371
|
-
console.log(` Agent Event Support: ${hasAgentEventSupport ? "AVAILABLE" : "NOT AVAILABLE"}`);
|
|
372
|
-
console.log(` Effective Streaming: ${streamingEnabled && hasAgentEventSupport ? "ENABLED (via onAgentEvent)" : "DISABLED"}`);
|
|
317
|
+
console.log(` Images: ${images.length}`);
|
|
373
318
|
console.log("=".repeat(60) + "\n");
|
|
374
|
-
|
|
375
|
-
let accumulatedText = "";
|
|
376
|
-
let taskId = runtime.getTaskIdForSession(message.sessionId) || `task_${Date.now()}`;
|
|
377
|
-
let frameCount = 0;
|
|
378
|
-
let partialCount = 0;
|
|
319
|
+
const taskId = runtime.getTaskIdForSession(message.sessionId) || `task_${Date.now()}`;
|
|
379
320
|
const startTime = Date.now();
|
|
380
|
-
|
|
381
|
-
let unsubscribeAgentEvents;
|
|
382
|
-
let runId;
|
|
383
|
-
let isCompleted = false;
|
|
384
|
-
if (streamingEnabled && hasAgentEventSupport) {
|
|
385
|
-
// Subscribe to agent events BEFORE dispatching the message
|
|
386
|
-
unsubscribeAgentEvents = onAgentEvent((evt) => {
|
|
387
|
-
if (isCompleted)
|
|
388
|
-
return;
|
|
389
|
-
// Get runId from first event
|
|
390
|
-
if (!runId && evt.runId) {
|
|
391
|
-
runId = evt.runId;
|
|
392
|
-
console.log(`XiaoYi: [AGENT EVENT] Registered runId: ${runId}`);
|
|
393
|
-
}
|
|
394
|
-
// Only process events for this run
|
|
395
|
-
if (runId && evt.runId !== runId)
|
|
396
|
-
return;
|
|
397
|
-
const elapsed = Date.now() - startTime;
|
|
398
|
-
// Handle streaming text events
|
|
399
|
-
if (evt.stream === "assistant" && typeof evt.data?.text === "string") {
|
|
400
|
-
const newText = evt.data.text;
|
|
401
|
-
if (!newText)
|
|
402
|
-
return;
|
|
403
|
-
// Calculate delta text
|
|
404
|
-
const previousLength = accumulatedText.length;
|
|
405
|
-
accumulatedText = newText;
|
|
406
|
-
const deltaText = newText.slice(previousLength);
|
|
407
|
-
console.log(`\n>>> XiaoYi: [AGENT EVENT] Stream frame #${++partialCount} at ${elapsed}ms`);
|
|
408
|
-
console.log(` Run ID: ${evt.runId}`);
|
|
409
|
-
console.log(` Delta length: ${deltaText.length} chars`);
|
|
410
|
-
console.log(` Total length: ${newText.length} chars`);
|
|
411
|
-
console.log(` Delta content: "${deltaText}"`);
|
|
412
|
-
// Send PARTIAL frame with delta content
|
|
413
|
-
const partialResponse = {
|
|
414
|
-
sessionId: message.sessionId,
|
|
415
|
-
messageId: `partial_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
416
|
-
timestamp: Date.now(),
|
|
417
|
-
agentId: resolvedAccount.config.agentId,
|
|
418
|
-
sender: {
|
|
419
|
-
id: resolvedAccount.config.agentId,
|
|
420
|
-
name: "OpenClaw Agent",
|
|
421
|
-
type: "agent",
|
|
422
|
-
},
|
|
423
|
-
content: {
|
|
424
|
-
type: "text",
|
|
425
|
-
text: deltaText || newText,
|
|
426
|
-
},
|
|
427
|
-
status: "processing",
|
|
428
|
-
};
|
|
429
|
-
const conn = runtime.getConnection();
|
|
430
|
-
if (conn) {
|
|
431
|
-
conn.sendResponse(partialResponse, taskId, message.sessionId, false, true)
|
|
432
|
-
.then(() => {
|
|
433
|
-
console.log(` ✓ SENT (isFinal=false, append=true)\n`);
|
|
434
|
-
})
|
|
435
|
-
.catch((err) => {
|
|
436
|
-
console.error(` ✗ Send failed: ${err}\n`);
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
// Handle lifecycle events (completion/error)
|
|
441
|
-
if (evt.stream === "lifecycle") {
|
|
442
|
-
const phase = evt.data?.phase;
|
|
443
|
-
if (phase === "end") {
|
|
444
|
-
isCompleted = true;
|
|
445
|
-
console.log("\n" + "-".repeat(60));
|
|
446
|
-
console.log(`XiaoYi: [AGENT EVENT] Lifecycle phase: end`);
|
|
447
|
-
console.log(` Run ID: ${evt.runId}`);
|
|
448
|
-
console.log(` Elapsed: ${elapsed}ms`);
|
|
449
|
-
console.log(` Total frames: ${partialCount}`);
|
|
450
|
-
console.log(` Final length: ${accumulatedText.length} chars`);
|
|
451
|
-
console.log("-".repeat(60) + "\n");
|
|
452
|
-
// Send FINAL frame
|
|
453
|
-
const response = {
|
|
454
|
-
sessionId: message.sessionId,
|
|
455
|
-
messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
456
|
-
timestamp: Date.now(),
|
|
457
|
-
agentId: resolvedAccount.config.agentId,
|
|
458
|
-
sender: {
|
|
459
|
-
id: resolvedAccount.config.agentId,
|
|
460
|
-
name: "OpenClaw Agent",
|
|
461
|
-
type: "agent",
|
|
462
|
-
},
|
|
463
|
-
content: {
|
|
464
|
-
type: "text",
|
|
465
|
-
text: accumulatedText,
|
|
466
|
-
},
|
|
467
|
-
status: "success",
|
|
468
|
-
};
|
|
469
|
-
const conn = runtime.getConnection();
|
|
470
|
-
if (conn) {
|
|
471
|
-
conn.sendResponse(response, taskId, message.sessionId, true, false)
|
|
472
|
-
.then(() => {
|
|
473
|
-
console.log(`✓ XiaoYi: FINAL frame sent (isFinal=true, append=false)\n`);
|
|
474
|
-
})
|
|
475
|
-
.catch((err) => {
|
|
476
|
-
console.error(`✗ Final send failed: ${err}\n`);
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
// Unsubscribe from events
|
|
480
|
-
if (unsubscribeAgentEvents) {
|
|
481
|
-
unsubscribeAgentEvents();
|
|
482
|
-
unsubscribeAgentEvents = undefined;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
else if (phase === "error") {
|
|
486
|
-
isCompleted = true;
|
|
487
|
-
console.error(`XiaoYi: [AGENT EVENT] Error phase:`, evt.data?.error);
|
|
488
|
-
// Unsubscribe from events
|
|
489
|
-
if (unsubscribeAgentEvents) {
|
|
490
|
-
unsubscribeAgentEvents();
|
|
491
|
-
unsubscribeAgentEvents = undefined;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
});
|
|
496
|
-
console.log(`XiaoYi: [AGENT EVENT] Listener registered for streaming`);
|
|
497
|
-
}
|
|
498
|
-
else if (streamingEnabled && !hasAgentEventSupport) {
|
|
499
|
-
console.warn(`XiaoYi: [WARN] Streaming enabled but onAgentEvent not available, falling back to non-streaming mode`);
|
|
500
|
-
}
|
|
321
|
+
let accumulatedText = "";
|
|
501
322
|
await pluginRuntime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
502
323
|
ctx: msgContext,
|
|
503
324
|
cfg: config,
|
|
504
325
|
dispatcherOptions: {
|
|
505
326
|
deliver: async (payload) => {
|
|
506
|
-
// NOTE: onAgentEvent does NOT emit "assistant" stream events in production
|
|
507
|
-
// Only lifecycle and tool events are emitted
|
|
508
|
-
// So we must handle the final result here
|
|
509
327
|
const elapsed = Date.now() - startTime;
|
|
510
328
|
const completeText = payload.text || "";
|
|
511
329
|
accumulatedText = completeText;
|
|
512
330
|
console.log("\n" + "-".repeat(60));
|
|
513
|
-
console.log(`XiaoYi: [DELIVER]
|
|
331
|
+
console.log(`XiaoYi: [DELIVER] AI response received`);
|
|
514
332
|
console.log(` Elapsed: ${elapsed}ms`);
|
|
515
333
|
console.log(` Length: ${completeText.length} chars`);
|
|
516
|
-
console.log(`
|
|
334
|
+
console.log(` Preview: ${completeText.substring(0, 100)}...`);
|
|
517
335
|
console.log("-".repeat(60) + "\n");
|
|
518
|
-
// Send
|
|
336
|
+
// Send final response to XiaoYi
|
|
519
337
|
const response = {
|
|
520
338
|
sessionId: message.sessionId,
|
|
521
339
|
messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
@@ -535,7 +353,10 @@ exports.xiaoyiPlugin = {
|
|
|
535
353
|
const conn = runtime.getConnection();
|
|
536
354
|
if (conn) {
|
|
537
355
|
await conn.sendResponse(response, taskId, message.sessionId, true, false);
|
|
538
|
-
console.log(`✓ XiaoYi:
|
|
356
|
+
console.log(`✓ XiaoYi: Response sent successfully\n`);
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
console.error(`✗ XiaoYi: Connection not available\n`);
|
|
539
360
|
}
|
|
540
361
|
},
|
|
541
362
|
onIdle: async () => {
|
|
@@ -543,18 +364,11 @@ exports.xiaoyiPlugin = {
|
|
|
543
364
|
console.log("\n" + "=".repeat(60));
|
|
544
365
|
console.log(`XiaoYi: [IDLE] Processing complete`);
|
|
545
366
|
console.log(` Total time: ${elapsed}ms`);
|
|
546
|
-
console.log(` Streaming frames: ${partialCount}`);
|
|
547
367
|
console.log(` Final length: ${accumulatedText.length} chars`);
|
|
548
368
|
console.log("=".repeat(60) + "\n");
|
|
549
|
-
// Cleanup event listener if still active
|
|
550
|
-
if (unsubscribeAgentEvents && !isCompleted) {
|
|
551
|
-
console.log(`XiaoYi: [IDLE] Cleaning up event listener`);
|
|
552
|
-
unsubscribeAgentEvents();
|
|
553
|
-
unsubscribeAgentEvents = undefined;
|
|
554
|
-
}
|
|
555
369
|
},
|
|
556
370
|
},
|
|
557
|
-
replyOptions: undefined,
|
|
371
|
+
replyOptions: undefined,
|
|
558
372
|
images: images.length > 0 ? images : undefined,
|
|
559
373
|
});
|
|
560
374
|
}
|