@ynhcj/xiaoyi-channel 0.0.162-next → 0.0.163-next

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/index.js CHANGED
@@ -37,38 +37,63 @@ function registerCronDetectionHook(api) {
37
37
  }
38
38
  /** 从 cron add 工具结果中提取 jobId 并写入 pushId 映射。 */
39
39
  async function captureCronAddMapping(event, ctx) {
40
+ // 诊断:先看 after_tool_call 是否为 cron 工具触发
40
41
  if (event.toolName !== "cron")
41
42
  return;
42
43
  const action = typeof event.params?.action === "string" ? event.params.action : "";
43
- if (action !== "add")
44
+ console.log(`[CRONMAP] after_tool_call cron, action=${action}, resultType=${typeof event.result}`);
45
+ if (action !== "add") {
46
+ console.log(`[CRONMAP] skip: action !== "add" (got ${action})`);
44
47
  return;
48
+ }
45
49
  const jobId = readJobIdFromResult(event.result);
46
- if (!jobId)
50
+ if (!jobId) {
51
+ console.log(`[CRONMAP] skip: could not extract jobId from result. preview=${preview(event.result)}`);
47
52
  return;
53
+ }
54
+ console.log(`[CRONMAP] extracted jobId=${jobId}`);
48
55
  const sessionCtx = ctx.sessionKey ? getSessionContext(ctx.sessionKey) : null;
49
56
  const sessionId = sessionCtx?.sessionId;
50
- if (!sessionId)
57
+ if (!sessionId) {
58
+ console.log(`[CRONMAP] skip: no sessionId (sessionKey=${ctx.sessionKey}, ctxFound=${!!sessionCtx})`);
51
59
  return;
60
+ }
52
61
  const pushId = configManager.getPushId(sessionId);
53
- if (!pushId)
62
+ if (!pushId) {
63
+ console.log(`[CRONMAP] skip: configManager has no pushId for sessionId=${sessionId}`);
54
64
  return;
65
+ }
66
+ console.log(`[CRONMAP] writing map: jobId=${jobId}, sessionId=${sessionId}, pushId=${pushId.substring(0, 16)}...`);
55
67
  await setJobPushId(jobId, {
56
68
  pushId,
57
69
  sessionId,
58
70
  deviceType: sessionCtx?.deviceType,
59
71
  source: "conversation",
60
72
  });
73
+ console.log(`[CRONMAP] map written OK`);
74
+ }
75
+ /** 取结果的短预览,用于诊断。 */
76
+ function preview(value) {
77
+ if (value == null)
78
+ return String(value);
79
+ const s = typeof value === "string" ? value : JSON.stringify(value);
80
+ return s.length > 200 ? s.slice(0, 200) + "…" : s;
61
81
  }
62
- /** 防御性地从 cron add 结果中取 job id(可能是对象或 JSON 字符串)。 */
82
+ /** 防御性地从 cron add 结果中取 job id(可能是对象、JSON 字符串或工具输出文本)。 */
63
83
  function readJobIdFromResult(result) {
64
84
  if (!result)
65
85
  return undefined;
66
86
  let obj = result;
67
87
  if (typeof result === "string") {
88
+ // 优先尝试 JSON 解析
68
89
  try {
69
90
  obj = JSON.parse(result);
70
91
  }
71
92
  catch {
93
+ // 解析失败:可能是纯文本工具输出,尝试从文本里抓 "id":"..." 或 id=...
94
+ const m = result.match(/"id"\s*:\s*"([^"]+)"/);
95
+ if (m)
96
+ return m[1];
72
97
  return undefined;
73
98
  }
74
99
  }
@@ -76,6 +101,15 @@ function readJobIdFromResult(result) {
76
101
  const id = obj.id;
77
102
  if (typeof id === "string" && id.trim())
78
103
  return id.trim();
104
+ // 兜底:result 可能把 job 包在 data/result 字段里
105
+ for (const k of ["data", "result", "job"]) {
106
+ const inner = obj[k];
107
+ if (inner && typeof inner === "object") {
108
+ const innerId = inner.id;
109
+ if (typeof innerId === "string" && innerId.trim())
110
+ return innerId.trim();
111
+ }
112
+ }
79
113
  }
80
114
  return undefined;
81
115
  }
@@ -117,20 +117,30 @@ export async function handleCronQueryEvent(context, cfg) {
117
117
  * 从 cron.add 结果中提取 jobId,配合 sessionId 对应的 pushId 写入映射。
118
118
  */
119
119
  async function persistCronPushMap(sessionId, result) {
120
- if (!sessionId)
120
+ logger.log(`[CRONMAP] cron-query persist: sessionId=${sessionId ?? "(none)"}, resultType=${typeof result}`);
121
+ if (!sessionId) {
122
+ logger.log(`[CRONMAP] cron-query skip: no sessionId in context`);
121
123
  return;
124
+ }
122
125
  let jobId;
123
126
  if (result && typeof result === "object") {
124
127
  const id = result.id;
125
128
  if (typeof id === "string" && id.trim())
126
129
  jobId = id.trim();
127
130
  }
128
- if (!jobId)
131
+ if (!jobId) {
132
+ const preview = typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result)?.slice(0, 200);
133
+ logger.log(`[CRONMAP] cron-query skip: no jobId in result. preview=${preview ?? "(empty)"}`);
129
134
  return;
135
+ }
130
136
  const pushId = configManager.getPushId(sessionId);
131
- if (!pushId)
137
+ if (!pushId) {
138
+ logger.log(`[CRONMAP] cron-query skip: configManager has no pushId for sessionId=${sessionId}`);
132
139
  return;
140
+ }
141
+ logger.log(`[CRONMAP] cron-query writing map: jobId=${jobId}, pushId=${pushId.substring(0, 16)}...`);
133
142
  await setJobPushId(jobId, { pushId, sessionId, source: "cron-query" });
143
+ logger.log(`[CRONMAP] cron-query map written OK`);
134
144
  }
135
145
  /**
136
146
  * Read local cron folder directly (bypassing openclaw RPC) and return
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi-channel",
3
- "version": "0.0.162-next",
3
+ "version": "0.0.163-next",
4
4
  "description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",