@ynhcj/xiaoyi-channel 0.0.51-beta → 0.0.52-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.
Files changed (31) hide show
  1. package/dist/src/bot.js +0 -16
  2. package/dist/src/client.js +0 -2
  3. package/dist/src/formatter.js +3 -23
  4. package/dist/src/heartbeat.js +0 -1
  5. package/dist/src/reply-dispatcher.js +32 -0
  6. package/dist/src/tools/calendar-tool.js +2 -37
  7. package/dist/src/tools/call-phone-tool.js +1 -42
  8. package/dist/src/tools/create-alarm-tool.js +3 -74
  9. package/dist/src/tools/delete-alarm-tool.js +3 -45
  10. package/dist/src/tools/image-reading-tool.js +0 -47
  11. package/dist/src/tools/location-tool.js +1 -32
  12. package/dist/src/tools/modify-alarm-tool.js +3 -77
  13. package/dist/src/tools/modify-note-tool.js +1 -34
  14. package/dist/src/tools/note-tool.js +2 -4
  15. package/dist/src/tools/search-alarm-tool.js +3 -61
  16. package/dist/src/tools/search-calendar-tool.js +2 -39
  17. package/dist/src/tools/search-contact-tool.js +0 -30
  18. package/dist/src/tools/search-file-tool.js +0 -33
  19. package/dist/src/tools/search-message-tool.js +0 -33
  20. package/dist/src/tools/search-note-tool.js +1 -26
  21. package/dist/src/tools/search-photo-gallery-tool.js +2 -31
  22. package/dist/src/tools/send-file-to-user-tool.js +0 -39
  23. package/dist/src/tools/send-message-tool.js +1 -39
  24. package/dist/src/tools/session-manager.js +0 -45
  25. package/dist/src/tools/upload-file-tool.js +0 -49
  26. package/dist/src/tools/upload-photo-tool.js +0 -42
  27. package/dist/src/tools/view-push-result-tool.js +0 -11
  28. package/dist/src/tools/xiaoyi-collection-tool.js +4 -82
  29. package/dist/src/tools/xiaoyi-gui-tool.js +0 -34
  30. package/dist/src/websocket.js +24 -8
  31. package/package.json +1 -1
@@ -1,7 +1,6 @@
1
1
  import { getXYWebSocketManager } from "../client.js";
2
2
  import { sendCommand } from "../formatter.js";
3
3
  import { getCurrentSessionContext } from "./session-manager.js";
4
- import { logger } from "../utils/logger.js";
5
4
  // Enum definitions for alarm parameters
6
5
  const ALARM_SNOOZE_DURATION_VALUES = [5, 10, 15, 20, 25, 30];
7
6
  const ALARM_SNOOZE_TOTAL_VALUES = [0, 1, 3, 5, 10];
@@ -32,7 +31,9 @@ export const createAlarmTool = {
32
31
 
33
32
  注意事项:
34
33
  a. 操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。
35
- b. 使用该工具之前需获取当前真实时间`,
34
+ b. 使用该工具之前需获取当前真实时间
35
+
36
+ 回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。`,
36
37
  parameters: {
37
38
  type: "object",
38
39
  properties: {
@@ -69,170 +70,127 @@ b. 使用该工具之前需获取当前真实时间`,
69
70
  required: ["alarmTime"],
70
71
  },
71
72
  async execute(toolCallId, params) {
72
- logger.log(`[CREATE_ALARM_TOOL] 🚀 Starting execution`);
73
- logger.log(`[CREATE_ALARM_TOOL] - toolCallId: ${toolCallId}`);
74
- logger.log(`[CREATE_ALARM_TOOL] - params:`, JSON.stringify(params));
75
- logger.log(`[CREATE_ALARM_TOOL] - timestamp: ${new Date().toISOString()}`);
76
73
  // ===== Validate required parameter: alarmTime =====
77
74
  if (!params.alarmTime || typeof params.alarmTime !== "string") {
78
- logger.error(`[CREATE_ALARM_TOOL] ❌ Missing or invalid alarmTime`);
79
75
  throw new Error("Missing required parameter: alarmTime must be a string in format YYYYMMDD hhmmss");
80
76
  }
81
77
  // Parse and convert alarmTime to timestamp
82
- logger.log(`[CREATE_ALARM_TOOL] 🕒 Parsing alarmTime: ${params.alarmTime}`);
83
78
  const alarmTimeMs = parseAlarmTimeToTimestamp(params.alarmTime);
84
79
  if (alarmTimeMs === null) {
85
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid alarmTime format`);
86
80
  throw new Error("Invalid alarmTime format. Required format: YYYYMMDD hhmmss (e.g., 20240315 143000)");
87
81
  }
88
- logger.log(`[CREATE_ALARM_TOOL] ✅ alarmTime converted to timestamp: ${alarmTimeMs}`);
89
82
  // ===== Validate and set optional parameters with defaults =====
90
83
  // alarmTitle - default to "闹钟"
91
84
  const alarmTitle = params.alarmTitle && typeof params.alarmTitle === "string"
92
85
  ? params.alarmTitle
93
86
  : "闹钟";
94
- logger.log(`[CREATE_ALARM_TOOL] - alarmTitle: ${alarmTitle}`);
95
87
  // alarmSnoozeDuration - default 10
96
88
  let alarmSnoozeDuration = 10;
97
89
  if (params.alarmSnoozeDuration !== undefined && params.alarmSnoozeDuration !== null) {
98
90
  if (typeof params.alarmSnoozeDuration !== "number") {
99
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid alarmSnoozeDuration type`);
100
91
  throw new Error("alarmSnoozeDuration must be a number");
101
92
  }
102
93
  if (!ALARM_SNOOZE_DURATION_VALUES.includes(params.alarmSnoozeDuration)) {
103
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid alarmSnoozeDuration value: ${params.alarmSnoozeDuration}`);
104
94
  throw new Error(`alarmSnoozeDuration must be one of: ${ALARM_SNOOZE_DURATION_VALUES.join(", ")}`);
105
95
  }
106
96
  alarmSnoozeDuration = params.alarmSnoozeDuration;
107
97
  }
108
- logger.log(`[CREATE_ALARM_TOOL] - alarmSnoozeDuration: ${alarmSnoozeDuration}`);
109
98
  // alarmSnoozeTotal - default 0
110
99
  let alarmSnoozeTotal = 0;
111
100
  if (params.alarmSnoozeTotal !== undefined && params.alarmSnoozeTotal !== null) {
112
101
  if (typeof params.alarmSnoozeTotal !== "number") {
113
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid alarmSnoozeTotal type`);
114
102
  throw new Error("alarmSnoozeTotal must be a number");
115
103
  }
116
104
  if (!ALARM_SNOOZE_TOTAL_VALUES.includes(params.alarmSnoozeTotal)) {
117
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid alarmSnoozeTotal value: ${params.alarmSnoozeTotal}`);
118
105
  throw new Error(`alarmSnoozeTotal must be one of: ${ALARM_SNOOZE_TOTAL_VALUES.join(", ")}`);
119
106
  }
120
107
  alarmSnoozeTotal = params.alarmSnoozeTotal;
121
108
  }
122
- logger.log(`[CREATE_ALARM_TOOL] - alarmSnoozeTotal: ${alarmSnoozeTotal}`);
123
109
  // alarmRingDuration - default 20
124
110
  let alarmRingDuration = 20;
125
111
  if (params.alarmRingDuration !== undefined && params.alarmRingDuration !== null) {
126
112
  if (typeof params.alarmRingDuration !== "number") {
127
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid alarmRingDuration type`);
128
113
  throw new Error("alarmRingDuration must be a number");
129
114
  }
130
115
  if (!ALARM_RING_DURATION_VALUES.includes(params.alarmRingDuration)) {
131
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid alarmRingDuration value: ${params.alarmRingDuration}`);
132
116
  throw new Error(`alarmRingDuration must be one of: ${ALARM_RING_DURATION_VALUES.join(", ")}`);
133
117
  }
134
118
  alarmRingDuration = params.alarmRingDuration;
135
119
  }
136
- logger.log(`[CREATE_ALARM_TOOL] - alarmRingDuration: ${alarmRingDuration}`);
137
120
  // daysOfWakeType - default 0
138
121
  let daysOfWakeType = 0;
139
122
  if (params.daysOfWakeType !== undefined && params.daysOfWakeType !== null) {
140
123
  if (typeof params.daysOfWakeType !== "number") {
141
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid daysOfWakeType type`);
142
124
  throw new Error("daysOfWakeType must be a number");
143
125
  }
144
126
  if (!DAYS_OF_WAKE_TYPE_VALUES.includes(params.daysOfWakeType)) {
145
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid daysOfWakeType value: ${params.daysOfWakeType}`);
146
127
  throw new Error(`daysOfWakeType must be one of: ${DAYS_OF_WAKE_TYPE_VALUES.join(", ")}`);
147
128
  }
148
129
  daysOfWakeType = params.daysOfWakeType;
149
130
  }
150
- logger.log(`[CREATE_ALARM_TOOL] - daysOfWakeType: ${daysOfWakeType}`);
151
131
  // daysOfWeek - only required when daysOfWakeType is 3
152
132
  let daysOfWeek = [];
153
133
  if (daysOfWakeType === 3) {
154
134
  if (!params.daysOfWeek) {
155
- logger.error(`[CREATE_ALARM_TOOL] ❌ Missing daysOfWeek when daysOfWakeType=3`);
156
135
  throw new Error("daysOfWeek is required when daysOfWakeType is 3 (custom)");
157
136
  }
158
137
  // ===== 参数规范化:兼容数组和 JSON 字符串 =====
159
138
  let normalizedDaysOfWeek = null;
160
139
  // 情况1: 已经是数组
161
140
  if (Array.isArray(params.daysOfWeek)) {
162
- logger.log(`[CREATE_ALARM_TOOL] ✅ daysOfWeek is already an array`);
163
141
  normalizedDaysOfWeek = params.daysOfWeek;
164
142
  }
165
143
  // 情况2: 是字符串,尝试解析为 JSON 数组
166
144
  else if (typeof params.daysOfWeek === 'string') {
167
- logger.log(`[CREATE_ALARM_TOOL] 🔄 daysOfWeek is a string, attempting to parse as JSON...`);
168
145
  try {
169
146
  const parsed = JSON.parse(params.daysOfWeek);
170
147
  if (Array.isArray(parsed)) {
171
- logger.log(`[CREATE_ALARM_TOOL] ✅ Successfully parsed JSON string to array`);
172
148
  normalizedDaysOfWeek = parsed;
173
149
  }
174
150
  else {
175
- logger.error(`[CREATE_ALARM_TOOL] ❌ Parsed JSON is not an array:`, typeof parsed);
176
151
  throw new Error("daysOfWeek must be an array or a JSON string representing an array");
177
152
  }
178
153
  }
179
154
  catch (parseError) {
180
- logger.error(`[CREATE_ALARM_TOOL] ❌ Failed to parse daysOfWeek as JSON:`, parseError);
181
155
  throw new Error(`daysOfWeek must be a valid JSON array string. Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
182
156
  }
183
157
  }
184
158
  // 情况3: 其他类型,报错
185
159
  else {
186
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid daysOfWeek type:`, typeof params.daysOfWeek);
187
160
  throw new Error(`daysOfWeek must be an array or a JSON string, got ${typeof params.daysOfWeek}`);
188
161
  }
189
162
  // 验证数组非空
190
163
  if (!normalizedDaysOfWeek || normalizedDaysOfWeek.length === 0) {
191
- logger.error(`[CREATE_ALARM_TOOL] ❌ daysOfWeek array is empty`);
192
164
  throw new Error("daysOfWeek array cannot be empty");
193
165
  }
194
166
  // 验证数组长度必须为1
195
167
  if (normalizedDaysOfWeek.length !== 1) {
196
- logger.error(`[CREATE_ALARM_TOOL] ❌ daysOfWeek array length must be 1, got ${normalizedDaysOfWeek.length}`);
197
168
  throw new Error("daysOfWeek 仅支持长度为1的数组。如果需要一周中不同的几天,需要多次调用此工具");
198
169
  }
199
170
  // Validate each day
200
171
  for (const day of normalizedDaysOfWeek) {
201
172
  if (typeof day !== "string" || !DAYS_OF_WEEK_VALUES.includes(day)) {
202
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid day value: ${day}`);
203
173
  throw new Error(`daysOfWeek must contain only: ${DAYS_OF_WEEK_VALUES.join(", ")}`);
204
174
  }
205
175
  }
206
176
  daysOfWeek = normalizedDaysOfWeek;
207
- logger.log(`[CREATE_ALARM_TOOL] - daysOfWeek: ${daysOfWeek.join(", ")}`);
208
177
  }
209
178
  else {
210
179
  // daysOfWakeType is not 3, daysOfWeek should not be provided
211
180
  if (params.daysOfWeek) {
212
- logger.warn(`[CREATE_ALARM_TOOL] ⚠️ daysOfWeek parameter is ignored when daysOfWakeType is not 3 (current: ${daysOfWakeType}). Please remove daysOfWeek parameter.`);
213
181
  }
214
182
  // Explicitly set to empty array
215
183
  daysOfWeek = [];
216
184
  }
217
185
  // Get session context
218
- logger.log(`[CREATE_ALARM_TOOL] 🔍 Attempting to get session context...`);
219
186
  const sessionContext = getCurrentSessionContext();
220
187
  if (!sessionContext) {
221
- logger.error(`[CREATE_ALARM_TOOL] ❌ FAILED: No active session found!`);
222
- logger.error(`[CREATE_ALARM_TOOL] - toolCallId: ${toolCallId}`);
223
188
  throw new Error("No active XY session found. Create alarm tool can only be used during an active conversation.");
224
189
  }
225
- logger.log(`[CREATE_ALARM_TOOL] ✅ Session context found`);
226
- logger.log(`[CREATE_ALARM_TOOL] - sessionId: ${sessionContext.sessionId}`);
227
- logger.log(`[CREATE_ALARM_TOOL] - taskId: ${sessionContext.taskId}`);
228
- logger.log(`[CREATE_ALARM_TOOL] - messageId: ${sessionContext.messageId}`);
229
190
  const { config, sessionId, taskId, messageId } = sessionContext;
230
191
  // Get WebSocket manager
231
- logger.log(`[CREATE_ALARM_TOOL] 🔌 Getting WebSocket manager...`);
232
192
  const wsManager = getXYWebSocketManager(config);
233
- logger.log(`[CREATE_ALARM_TOOL] ✅ WebSocket manager obtained`);
234
193
  // Build CreateAlarm command
235
- logger.log(`[CREATE_ALARM_TOOL] 📦 Building CreateAlarm command...`);
236
194
  // Build intentParam - only include daysOfWeek when daysOfWakeType is 3
237
195
  const intentParam = {
238
196
  entityName: "Alarm",
@@ -246,10 +204,8 @@ b. 使用该工具之前需获取当前真实时间`,
246
204
  // Only include daysOfWeek when daysOfWakeType is 3
247
205
  if (daysOfWakeType === 3 && daysOfWeek.length > 0) {
248
206
  intentParam.daysOfWeek = daysOfWeek;
249
- logger.log(`[CREATE_ALARM_TOOL] - Including daysOfWeek in intentParam: ${daysOfWeek.join(", ")}`);
250
207
  }
251
208
  else {
252
- logger.log(`[CREATE_ALARM_TOOL] - Excluding daysOfWeek from intentParam (daysOfWakeType=${daysOfWakeType})`);
253
209
  }
254
210
  const command = {
255
211
  header: {
@@ -283,25 +239,17 @@ b. 使用该工具之前需获取当前真实时间`,
283
239
  },
284
240
  };
285
241
  // Send command and wait for response (60 second timeout)
286
- logger.log(`[CREATE_ALARM_TOOL] ⏳ Setting up promise to wait for alarm creation response...`);
287
- logger.log(`[CREATE_ALARM_TOOL] - Timeout: 60 seconds`);
288
242
  return new Promise((resolve, reject) => {
289
243
  const timeout = setTimeout(() => {
290
- logger.error(`[CREATE_ALARM_TOOL] ⏰ Timeout: No response received within 60 seconds`);
291
244
  wsManager.off("data-event", handler);
292
245
  reject(new Error("创建闹钟超时(60秒)"));
293
246
  }, 60000);
294
247
  // Listen for data events from WebSocket
295
248
  const handler = (event) => {
296
- logger.log(`[CREATE_ALARM_TOOL] 📨 Received data event:`, JSON.stringify(event));
297
249
  if (event.intentName === "CreateAlarm") {
298
- logger.log(`[CREATE_ALARM_TOOL] 🎯 CreateAlarm event received`);
299
- logger.log(`[CREATE_ALARM_TOOL] - status: ${event.status}`);
300
250
  clearTimeout(timeout);
301
251
  wsManager.off("data-event", handler);
302
252
  if (event.status === "success" && event.outputs) {
303
- logger.log(`[CREATE_ALARM_TOOL] ✅ Alarm creation completed successfully`);
304
- logger.log(`[CREATE_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs));
305
253
  // 成功,直接返回完整的 event.outputs JSON 字符串
306
254
  resolve({
307
255
  content: [
@@ -313,18 +261,13 @@ b. 使用该工具之前需获取当前真实时间`,
313
261
  });
314
262
  }
315
263
  else {
316
- logger.error(`[CREATE_ALARM_TOOL] ❌ Alarm creation failed`);
317
- logger.error(`[CREATE_ALARM_TOOL] - status: ${event.status}`);
318
- logger.error(`[CREATE_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs || {}));
319
264
  reject(new Error(`创建闹钟失败: ${event.status}`));
320
265
  }
321
266
  }
322
267
  };
323
268
  // Register event handler
324
- logger.log(`[CREATE_ALARM_TOOL] 📡 Registering data-event handler on WebSocket manager`);
325
269
  wsManager.on("data-event", handler);
326
270
  // Send the command
327
- logger.log(`[CREATE_ALARM_TOOL] 📤 Sending CreateAlarm command...`);
328
271
  sendCommand({
329
272
  config,
330
273
  sessionId,
@@ -333,10 +276,8 @@ b. 使用该工具之前需获取当前真实时间`,
333
276
  command,
334
277
  })
335
278
  .then(() => {
336
- logger.log(`[CREATE_ALARM_TOOL] ✅ Command sent successfully, waiting for response...`);
337
279
  })
338
280
  .catch((error) => {
339
- logger.error(`[CREATE_ALARM_TOOL] ❌ Failed to send command:`, error);
340
281
  clearTimeout(timeout);
341
282
  wsManager.off("data-event", handler);
342
283
  reject(error);
@@ -356,17 +297,14 @@ function parseAlarmTimeToTimestamp(alarmTime) {
356
297
  const trimmed = alarmTime.trim();
357
298
  // Check basic format (should have at least 13 characters: YYYYMMDD hhmmss)
358
299
  if (trimmed.length < 13) {
359
- logger.error(`[CREATE_ALARM_TOOL] ❌ alarmTime too short: ${trimmed}`);
360
300
  return null;
361
301
  }
362
302
  // Extract date and time parts
363
303
  // Format: YYYYMMDD hhmmss
364
304
  const datePart = trimmed.substring(0, 8); // YYYYMMDD
365
305
  const timePart = trimmed.substring(8).trim(); // hhmmss (may have leading space)
366
- logger.log(`[CREATE_ALARM_TOOL] - datePart: ${datePart}, timePart: ${timePart}`);
367
306
  // Validate lengths
368
307
  if (datePart.length !== 8 || timePart.length !== 6) {
369
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid part lengths: datePart=${datePart.length}, timePart=${timePart.length}`);
370
308
  return null;
371
309
  }
372
310
  // Parse components
@@ -376,45 +314,36 @@ function parseAlarmTimeToTimestamp(alarmTime) {
376
314
  const hour = parseInt(timePart.substring(0, 2), 10);
377
315
  const minute = parseInt(timePart.substring(2, 4), 10);
378
316
  const second = parseInt(timePart.substring(4, 6), 10);
379
- logger.log(`[CREATE_ALARM_TOOL] - Parsed: ${year}-${month}-${day} ${hour}:${minute}:${second}`);
380
317
  // Validate values
381
318
  if (isNaN(year) || isNaN(month) || isNaN(day) ||
382
319
  isNaN(hour) || isNaN(minute) || isNaN(second)) {
383
- logger.error(`[CREATE_ALARM_TOOL] ❌ NaN detected in parsed values`);
384
320
  return null;
385
321
  }
386
322
  // Validate ranges
387
323
  if (month < 1 || month > 12) {
388
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid month: ${month}`);
389
324
  return null;
390
325
  }
391
326
  if (day < 1 || day > 31) {
392
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid day: ${day}`);
393
327
  return null;
394
328
  }
395
329
  if (hour < 0 || hour > 23) {
396
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid hour: ${hour}`);
397
330
  return null;
398
331
  }
399
332
  if (minute < 0 || minute > 59) {
400
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid minute: ${minute}`);
401
333
  return null;
402
334
  }
403
335
  if (second < 0 || second > 59) {
404
- logger.error(`[CREATE_ALARM_TOOL] ❌ Invalid second: ${second}`);
405
336
  return null;
406
337
  }
407
338
  // Create Date object and get timestamp
408
339
  const date = new Date(year, month - 1, day, hour, minute, second);
409
340
  const timestamp = date.getTime();
410
341
  if (isNaN(timestamp)) {
411
- logger.error(`[CREATE_ALARM_TOOL] ❌ Generated timestamp is NaN`);
412
342
  return null;
413
343
  }
414
344
  return timestamp;
415
345
  }
416
346
  catch (error) {
417
- logger.error(`[CREATE_ALARM_TOOL] ❌ Exception in parseAlarmTimeToTimestamp:`, error);
418
347
  return null;
419
348
  }
420
349
  }
@@ -1,7 +1,6 @@
1
1
  import { getXYWebSocketManager } from "../client.js";
2
2
  import { sendCommand } from "../formatter.js";
3
3
  import { getCurrentSessionContext } from "./session-manager.js";
4
- import { logger } from "../utils/logger.js";
5
4
  /**
6
5
  * XY delete alarm tool - deletes existing alarms on user's device.
7
6
  * Requires entityId(s) from search_alarm or create_alarm tool as prerequisite.
@@ -27,7 +26,9 @@ export const deleteAlarmTool = {
27
26
  注意事项:
28
27
  1. 操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。
29
28
  2. 删除操作不可撤销,请确认 entityId 正确后再删除。
30
- 3. items 参数支持数组或 JSON 字符串格式,代码会自动解析。`,
29
+ 3. items 参数支持数组或 JSON 字符串格式,代码会自动解析。
30
+
31
+ 回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。`,
31
32
  parameters: {
32
33
  type: "object",
33
34
  properties: {
@@ -40,85 +41,57 @@ export const deleteAlarmTool = {
40
41
  required: ["items"],
41
42
  },
42
43
  async execute(toolCallId, params) {
43
- logger.log(`[DELETE_ALARM_TOOL] 🚀 Starting execution`);
44
- logger.log(`[DELETE_ALARM_TOOL] - toolCallId: ${toolCallId}`);
45
- logger.log(`[DELETE_ALARM_TOOL] - params (raw):`, JSON.stringify(params));
46
- logger.log(`[DELETE_ALARM_TOOL] - params.items type:`, typeof params.items);
47
- logger.log(`[DELETE_ALARM_TOOL] - timestamp: ${new Date().toISOString()}`);
48
44
  // ===== 参数规范化:兼容数组和 JSON 字符串 =====
49
45
  let items = null;
50
46
  if (!params.items) {
51
- logger.error(`[DELETE_ALARM_TOOL] ❌ Missing parameter: items`);
52
47
  throw new Error("Missing required parameter: items");
53
48
  }
54
49
  // 情况1: 已经是数组
55
50
  if (Array.isArray(params.items)) {
56
- logger.log(`[DELETE_ALARM_TOOL] ✅ items is already an array`);
57
51
  items = params.items;
58
52
  }
59
53
  // 情况2: 是字符串,尝试解析为 JSON 数组
60
54
  else if (typeof params.items === 'string') {
61
- logger.log(`[DELETE_ALARM_TOOL] 🔄 items is a string, attempting to parse as JSON...`);
62
55
  try {
63
56
  const parsed = JSON.parse(params.items);
64
57
  if (Array.isArray(parsed)) {
65
- logger.log(`[DELETE_ALARM_TOOL] ✅ Successfully parsed JSON string to array`);
66
58
  items = parsed;
67
59
  }
68
60
  else {
69
- logger.error(`[DELETE_ALARM_TOOL] ❌ Parsed JSON is not an array:`, typeof parsed);
70
61
  throw new Error("items must be an array or a JSON string representing an array");
71
62
  }
72
63
  }
73
64
  catch (parseError) {
74
- logger.error(`[DELETE_ALARM_TOOL] ❌ Failed to parse items as JSON:`, parseError);
75
65
  throw new Error(`items must be a valid JSON array string. Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
76
66
  }
77
67
  }
78
68
  // 情况3: 其他类型,报错
79
69
  else {
80
- logger.error(`[DELETE_ALARM_TOOL] ❌ Invalid items type:`, typeof params.items);
81
70
  throw new Error(`items must be an array or a JSON string, got ${typeof params.items}`);
82
71
  }
83
72
  // 验证数组非空
84
73
  if (!items || items.length === 0) {
85
- logger.error(`[DELETE_ALARM_TOOL] ❌ items array is empty`);
86
74
  throw new Error("items array cannot be empty");
87
75
  }
88
- logger.log(`[DELETE_ALARM_TOOL] ✅ Normalized items:`, JSON.stringify(items));
89
76
  // 验证每个 item 是否有有效的 entityId
90
77
  for (let i = 0; i < items.length; i++) {
91
78
  const item = items[i];
92
79
  if (!item || typeof item !== 'object') {
93
- logger.error(`[DELETE_ALARM_TOOL] ❌ Item at index ${i} is not an object`);
94
80
  throw new Error(`items[${i}] must be an object with entityId property`);
95
81
  }
96
82
  if (!item.entityId || typeof item.entityId !== 'string') {
97
- logger.error(`[DELETE_ALARM_TOOL] ❌ Item at index ${i} missing or invalid entityId`);
98
83
  throw new Error(`items[${i}] must have a valid entityId string property`);
99
84
  }
100
85
  }
101
- logger.log(`[DELETE_ALARM_TOOL] - items count: ${items.length}`);
102
- logger.log(`[DELETE_ALARM_TOOL] - entityIds:`, items.map(item => item.entityId).join(", "));
103
86
  // Get session context
104
- logger.log(`[DELETE_ALARM_TOOL] 🔍 Attempting to get session context...`);
105
87
  const sessionContext = getCurrentSessionContext();
106
88
  if (!sessionContext) {
107
- logger.error(`[DELETE_ALARM_TOOL] ❌ FAILED: No active session found!`);
108
- logger.error(`[DELETE_ALARM_TOOL] - toolCallId: ${toolCallId}`);
109
89
  throw new Error("No active XY session found. Delete alarm tool can only be used during an active conversation.");
110
90
  }
111
- logger.log(`[DELETE_ALARM_TOOL] ✅ Session context found`);
112
- logger.log(`[DELETE_ALARM_TOOL] - sessionId: ${sessionContext.sessionId}`);
113
- logger.log(`[DELETE_ALARM_TOOL] - taskId: ${sessionContext.taskId}`);
114
- logger.log(`[DELETE_ALARM_TOOL] - messageId: ${sessionContext.messageId}`);
115
91
  const { config, sessionId, taskId, messageId } = sessionContext;
116
92
  // Get WebSocket manager
117
- logger.log(`[DELETE_ALARM_TOOL] 🔌 Getting WebSocket manager...`);
118
93
  const wsManager = getXYWebSocketManager(config);
119
- logger.log(`[DELETE_ALARM_TOOL] ✅ WebSocket manager obtained`);
120
94
  // Build DeleteAlarm command
121
- logger.log(`[DELETE_ALARM_TOOL] 📦 Building DeleteAlarm command...`);
122
95
  const command = {
123
96
  header: {
124
97
  namespace: "Common",
@@ -153,25 +126,17 @@ export const deleteAlarmTool = {
153
126
  },
154
127
  };
155
128
  // Send command and wait for response (60 second timeout)
156
- logger.log(`[DELETE_ALARM_TOOL] ⏳ Setting up promise to wait for alarm deletion response...`);
157
- logger.log(`[DELETE_ALARM_TOOL] - Timeout: 60 seconds`);
158
129
  return new Promise((resolve, reject) => {
159
130
  const timeout = setTimeout(() => {
160
- logger.error(`[DELETE_ALARM_TOOL] ⏰ Timeout: No response received within 60 seconds`);
161
131
  wsManager.off("data-event", handler);
162
132
  reject(new Error("删除闹钟超时(60秒)"));
163
133
  }, 60000);
164
134
  // Listen for data events from WebSocket
165
135
  const handler = (event) => {
166
- logger.log(`[DELETE_ALARM_TOOL] 📨 Received data event:`, JSON.stringify(event));
167
136
  if (event.intentName === "DeleteAlarm") {
168
- logger.log(`[DELETE_ALARM_TOOL] 🎯 DeleteAlarm event received`);
169
- logger.log(`[DELETE_ALARM_TOOL] - status: ${event.status}`);
170
137
  clearTimeout(timeout);
171
138
  wsManager.off("data-event", handler);
172
139
  if (event.status === "success" && event.outputs) {
173
- logger.log(`[DELETE_ALARM_TOOL] ✅ Alarm deletion completed successfully`);
174
- logger.log(`[DELETE_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs));
175
140
  // 成功,直接返回完整的 event.outputs JSON 字符串
176
141
  resolve({
177
142
  content: [
@@ -183,18 +148,13 @@ export const deleteAlarmTool = {
183
148
  });
184
149
  }
185
150
  else {
186
- logger.error(`[DELETE_ALARM_TOOL] ❌ Alarm deletion failed`);
187
- logger.error(`[DELETE_ALARM_TOOL] - status: ${event.status}`);
188
- logger.error(`[DELETE_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs || {}));
189
151
  reject(new Error(`删除闹钟失败: ${event.status}`));
190
152
  }
191
153
  }
192
154
  };
193
155
  // Register event handler
194
- logger.log(`[DELETE_ALARM_TOOL] 📡 Registering data-event handler on WebSocket manager`);
195
156
  wsManager.on("data-event", handler);
196
157
  // Send the command
197
- logger.log(`[DELETE_ALARM_TOOL] 📤 Sending DeleteAlarm command...`);
198
158
  sendCommand({
199
159
  config,
200
160
  sessionId,
@@ -203,10 +163,8 @@ export const deleteAlarmTool = {
203
163
  command,
204
164
  })
205
165
  .then(() => {
206
- logger.log(`[DELETE_ALARM_TOOL] ✅ Command sent successfully, waiting for response...`);
207
166
  })
208
167
  .catch((error) => {
209
- logger.error(`[DELETE_ALARM_TOOL] ❌ Failed to send command:`, error);
210
168
  clearTimeout(timeout);
211
169
  wsManager.off("data-event", handler);
212
170
  reject(error);