@ynhcj/xiaoyi 2.1.8 → 2.2.0

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 CHANGED
@@ -364,102 +364,15 @@ exports.xiaoyiPlugin = {
364
364
  }
365
365
  });
366
366
  // Setup cancel handler
367
+ // Note: The response is already sent in websocket.ts, this is just for logging
367
368
  connection.on("cancel", async (data) => {
368
369
  console.log("\n" + "=".repeat(60));
369
- console.log(`XiaoYi: [CANCEL] Received cancel request`);
370
+ console.log(`XiaoYi: [CANCEL] Cancel event received (response already sent)`);
370
371
  console.log(` Session: ${data.sessionId}`);
371
372
  console.log(` Task ID: ${data.taskId || "N/A"}`);
372
373
  console.log("=".repeat(60) + "\n");
373
- // CRITICAL: Use dynamic require to get the latest runtime module after hot-reload
374
- const { getXiaoYiRuntime } = require("./runtime");
375
- const runtime = getXiaoYiRuntime();
376
- // Build SessionKey to match the format used in message handler
377
- const sessionKey = `xiaoyi:${resolvedAccount.accountId}:${data.sessionId}`;
378
- // Try to abort the running agent using OpenClaw's internal API
379
- try {
380
- // Try to load OpenClaw's internal abort function
381
- // Note: This requires the plugin to be run within OpenClaw's environment
382
- const abortEmbeddedPiRun = globalThis["__openclaw_abortEmbeddedPiRun"] ||
383
- (() => {
384
- try {
385
- const openclawPath = require.resolve("openclaw");
386
- const runsModule = require(`${openclawPath}/dist/agents/pi-embedded-runner/runs.js`);
387
- return runsModule.abortEmbeddedPiRun;
388
- }
389
- catch {
390
- return null;
391
- }
392
- })();
393
- if (!abortEmbeddedPiRun) {
394
- console.warn(`XiaoYi: [CANCEL] abortEmbeddedPiRun not available, falling back to event emission`);
395
- throw new Error("abortEmbeddedPiRun not available");
396
- }
397
- // Try to load session store functions
398
- const loadSessionStore = globalThis["__openclaw_loadSessionStore"] ||
399
- (() => {
400
- try {
401
- const openclawPath = require.resolve("openclaw");
402
- const sessionModule = require(`${openclawPath}/dist/config/sessions.js`);
403
- return sessionModule.loadSessionStore;
404
- }
405
- catch {
406
- return null;
407
- }
408
- })();
409
- const resolveStorePath = globalThis["__openclaw_resolveStorePath"] ||
410
- (() => {
411
- try {
412
- const openclawPath = require.resolve("openclaw");
413
- const sessionModule = require(`${openclawPath}/dist/config/sessions.js`);
414
- return sessionModule.resolveStorePath;
415
- }
416
- catch {
417
- return null;
418
- }
419
- })();
420
- if (!loadSessionStore || !resolveStorePath) {
421
- console.warn(`XiaoYi: [CANCEL] Session store functions not available`);
422
- throw new Error("Session store functions not available");
423
- }
424
- // Load session store and find the internal sessionId
425
- const agentId = resolvedAccount.config.agentId || "default";
426
- const storePath = resolveStorePath(config.session?.store, { agentId });
427
- const store = loadSessionStore(storePath);
428
- const sessionEntry = store[sessionKey];
429
- if (sessionEntry && sessionEntry.sessionId) {
430
- console.log(`XiaoYi: [CANCEL] Found session entry with internal sessionId: ${sessionEntry.sessionId}`);
431
- // Abort the running agent
432
- const aborted = abortEmbeddedPiRun(sessionEntry.sessionId);
433
- if (aborted) {
434
- console.log(`XiaoYi: [CANCEL] ✓ Successfully aborted agent run for session: ${data.sessionId}\n`);
435
- }
436
- else {
437
- console.warn(`XiaoYi: [CANCEL] ⚠ No active run found for session: ${data.sessionId}\n`);
438
- }
439
- }
440
- else {
441
- console.warn(`XiaoYi: [CANCEL] ⚠ No session entry found for key: ${sessionKey}\n`);
442
- }
443
- }
444
- catch (error) {
445
- console.error(`XiaoYi: [CANCEL] Error aborting agent:`, error);
446
- // Fallback: emit cancel event for any listeners
447
- const pluginRuntime = runtime.getPluginRuntime();
448
- if (pluginRuntime) {
449
- pluginRuntime.emit("task:cancel", {
450
- channel: "xiaoyi",
451
- accountId: resolvedAccount.accountId,
452
- taskId: data.taskId,
453
- sessionId: data.sessionId,
454
- });
455
- console.log(`XiaoYi: [CANCEL] Emitted task:cancel event as fallback\n`);
456
- }
457
- }
458
- // Send success response
459
- const connection = runtime.getConnection();
460
- if (connection) {
461
- await connection.sendCancelSuccessResponse(data.sessionId, data.taskId, data.id);
462
- }
374
+ // NOTE: The cancel response has already been sent to XiaoYi in websocket.ts.
375
+ // Actual cancellation of the agent run depends on OpenClaw's internal mechanisms.
463
376
  });
464
377
  console.log("XiaoYi: Event handlers registered");
465
378
  console.log("XiaoYi: startAccount() completed - END");
@@ -78,6 +78,10 @@ export declare class XiaoYiWebSocketManager extends EventEmitter {
78
78
  /**
79
79
  * Handle A2A tasks/cancel message
80
80
  * Reference: https://developer.huawei.com/consumer/cn/doc/service/tasks-cancel-0000002537561193
81
+ *
82
+ * Simplified implementation similar to clearContext:
83
+ * 1. Send success response immediately
84
+ * 2. Emit cancel event for application to handle
81
85
  */
82
86
  private handleTasksCancelMessage;
83
87
  /**
package/dist/websocket.js CHANGED
@@ -379,21 +379,33 @@ class XiaoYiWebSocketManager extends events_1.EventEmitter {
379
379
  /**
380
380
  * Handle A2A tasks/cancel message
381
381
  * Reference: https://developer.huawei.com/consumer/cn/doc/service/tasks-cancel-0000002537561193
382
+ *
383
+ * Simplified implementation similar to clearContext:
384
+ * 1. Send success response immediately
385
+ * 2. Emit cancel event for application to handle
382
386
  */
383
387
  handleTasksCancelMessage(message) {
384
388
  // Use taskId if available, otherwise use id as the task identifier
385
389
  const effectiveTaskId = message.taskId || message.id;
386
- console.log(`Received tasks/cancel message for task: ${effectiveTaskId}`);
390
+ console.log(`\n============================================================`);
391
+ console.log(`XiaoYi: [CANCEL] Received cancel request`);
387
392
  console.log(` Session: ${message.sessionId}`);
393
+ console.log(` Task ID: ${effectiveTaskId}`);
388
394
  console.log(` Message ID: ${message.id}`);
395
+ console.log(`===========================================================\n`);
396
+ // Send success response immediately (similar to clearContext)
397
+ this.sendTasksCancelResponse(message.id, message.sessionId, true).catch(error => {
398
+ console.error("Failed to send tasks/cancel response:", error);
399
+ });
389
400
  // Emit cancel event for application to handle
401
+ // The application can decide how to handle the cancellation
390
402
  this.emit("cancel", {
391
403
  sessionId: message.sessionId,
392
404
  taskId: effectiveTaskId,
393
405
  id: message.id,
394
406
  });
395
- // Note: We'll send the success response after OpenClaw confirms cancellation
396
- // This will be handled by the channel plugin
407
+ // Remove from active tasks
408
+ this.activeTasks.delete(effectiveTaskId);
397
409
  }
398
410
  /**
399
411
  * Send tasks/cancel success response
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi",
3
- "version": "2.1.8",
3
+ "version": "2.2.0",
4
4
  "description": "XiaoYi channel plugin for OpenClaw",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",