@ynhcj/xiaoyi-channel 0.0.215-beta → 0.0.217-beta

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/src/bot.js CHANGED
@@ -291,6 +291,14 @@ export async function handleXYMessage(params) {
291
291
  log.log(`[BOT] Downloaded ${downloadedFiles.length} file(s)`);
292
292
  mediaPayload = buildXYMediaPayload(downloadedFiles);
293
293
  }
294
+ // 🔑 对于 steer 消息,将文件路径附加到消息文本中。
295
+ // auto-reply 管道的 steer 注入只携带 prompt 文本(followupRun.prompt),
296
+ // 不携带 mediaPayload,所以模型需要以文本形式看到附件路径。
297
+ if (isUpdate && mediaPayload.MediaPaths?.length) {
298
+ const fileHint = `\n【用户上传附件】:${JSON.stringify(mediaPayload.MediaPaths)}`;
299
+ textForAgent = `${textForAgent}${fileHint}`;
300
+ log.log(`[BOT] Steer: appended file paths to text`);
301
+ }
294
302
  // Resolve envelope format options (following feishu pattern)
295
303
  const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg);
296
304
  // Build message body with speaker prefix (following feishu pattern)
@@ -230,6 +230,7 @@ export function createXYReplyDispatcher(params) {
230
230
  if (steerState.steered && !hasSentResponse) {
231
231
  scopedLog().log(`[ON-IDLE] Steered dispatch, no response generated, skipping`);
232
232
  stopStatusInterval();
233
+ await onIdleComplete?.();
233
234
  return;
234
235
  }
235
236
  // 🔑 用 try/finally 确保 cleanup 在 onIdle 的 async 工作全部完成后才执行。
@@ -3,6 +3,8 @@ interface TaskIdBinding {
3
3
  currentTaskId: string;
4
4
  currentMessageId: string;
5
5
  updatedAt: number;
6
+ /** 引用计数:每次 registerTaskId +1,每次 decrementTaskIdRef -1,归零时删除 */
7
+ refCount: number;
6
8
  }
7
9
  /**
8
10
  * 注册或更新session的活跃taskId。
@@ -19,10 +19,11 @@ const activeTaskIds = _g.__xyActiveTaskIds;
19
19
  export function registerTaskId(sessionId, taskId, messageId) {
20
20
  const existing = activeTaskIds.get(sessionId);
21
21
  if (existing) {
22
- logger.log(`[TASK_MANAGER] Updating taskId: ${existing.currentTaskId} → ${taskId}`);
22
+ logger.log(`[TASK_MANAGER] Updating taskId: ${existing.currentTaskId} → ${taskId}, refCount: ${existing.refCount} → ${existing.refCount + 1}`);
23
23
  existing.currentTaskId = taskId;
24
24
  existing.currentMessageId = messageId;
25
25
  existing.updatedAt = Date.now();
26
+ existing.refCount++;
26
27
  return true; // isUpdate
27
28
  }
28
29
  else {
@@ -31,8 +32,9 @@ export function registerTaskId(sessionId, taskId, messageId) {
31
32
  currentTaskId: taskId,
32
33
  currentMessageId: messageId,
33
34
  updatedAt: Date.now(),
35
+ refCount: 1,
34
36
  });
35
- logger.log(`[TASK_MANAGER] Registered new taskId: ${taskId}`);
37
+ logger.log(`[TASK_MANAGER] Registered new taskId: ${taskId}, refCount: 1`);
36
38
  return false;
37
39
  }
38
40
  }
@@ -40,8 +42,17 @@ export function registerTaskId(sessionId, taskId, messageId) {
40
42
  * 移除session的活跃taskId(消息处理完成时调用)。
41
43
  */
42
44
  export function decrementTaskIdRef(sessionId) {
43
- logger.log(`[TASK_MANAGER] Removing taskId`);
44
- activeTaskIds.delete(sessionId);
45
+ const binding = activeTaskIds.get(sessionId);
46
+ if (!binding) {
47
+ logger.log(`[TASK_MANAGER] decrementTaskIdRef: no binding for ${sessionId}`);
48
+ return;
49
+ }
50
+ binding.refCount--;
51
+ logger.log(`[TASK_MANAGER] decrementTaskIdRef: taskId=${binding.currentTaskId}, refCount: ${binding.refCount + 1} → ${binding.refCount}`);
52
+ if (binding.refCount <= 0) {
53
+ activeTaskIds.delete(sessionId);
54
+ logger.log(`[TASK_MANAGER] Removed taskId binding (refCount reached 0)`);
55
+ }
45
56
  }
46
57
  /**
47
58
  * 获取session的当前活跃taskId。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi-channel",
3
- "version": "0.0.215-beta",
3
+ "version": "0.0.217-beta",
4
4
  "description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",