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