@ynhcj/xiaoyi-channel 0.0.50-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 (42) hide show
  1. package/dist/index.js +42 -0
  2. package/dist/src/bot.js +3 -16
  3. package/dist/src/client.js +0 -3
  4. package/dist/src/cspl/call-api.d.ts +3 -0
  5. package/dist/src/cspl/call-api.js +79 -0
  6. package/dist/src/cspl/config.d.ts +19 -0
  7. package/dist/src/cspl/config.js +50 -0
  8. package/dist/src/cspl/constants.d.ts +43 -0
  9. package/dist/src/cspl/constants.js +22 -0
  10. package/dist/src/cspl/utils.d.ts +10 -0
  11. package/dist/src/cspl/utils.js +57 -0
  12. package/dist/src/formatter.js +3 -23
  13. package/dist/src/heartbeat.js +0 -4
  14. package/dist/src/reply-dispatcher.js +32 -0
  15. package/dist/src/steer-injector.d.ts +16 -0
  16. package/dist/src/steer-injector.js +74 -0
  17. package/dist/src/tools/calendar-tool.js +2 -37
  18. package/dist/src/tools/call-phone-tool.js +1 -42
  19. package/dist/src/tools/create-alarm-tool.js +3 -74
  20. package/dist/src/tools/delete-alarm-tool.js +3 -45
  21. package/dist/src/tools/image-reading-tool.js +0 -47
  22. package/dist/src/tools/location-tool.js +1 -32
  23. package/dist/src/tools/modify-alarm-tool.js +3 -77
  24. package/dist/src/tools/modify-note-tool.js +1 -34
  25. package/dist/src/tools/note-tool.js +2 -4
  26. package/dist/src/tools/search-alarm-tool.js +3 -61
  27. package/dist/src/tools/search-calendar-tool.js +2 -39
  28. package/dist/src/tools/search-contact-tool.js +0 -30
  29. package/dist/src/tools/search-file-tool.js +0 -33
  30. package/dist/src/tools/search-message-tool.js +0 -33
  31. package/dist/src/tools/search-note-tool.js +1 -26
  32. package/dist/src/tools/search-photo-gallery-tool.js +2 -31
  33. package/dist/src/tools/send-file-to-user-tool.js +0 -39
  34. package/dist/src/tools/send-message-tool.js +1 -39
  35. package/dist/src/tools/session-manager.js +0 -45
  36. package/dist/src/tools/upload-file-tool.js +0 -49
  37. package/dist/src/tools/upload-photo-tool.js +0 -42
  38. package/dist/src/tools/view-push-result-tool.js +0 -11
  39. package/dist/src/tools/xiaoyi-collection-tool.js +4 -82
  40. package/dist/src/tools/xiaoyi-gui-tool.js +0 -34
  41. package/dist/src/websocket.js +24 -10
  42. 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 search parameters
6
5
  const RANGE_TYPE_VALUES = ["all", "next", "current"];
7
6
  const ALARM_STATE_VALUES = [0, 1];
@@ -33,7 +32,9 @@ export const searchAlarmTool = {
33
32
 
34
33
  注意:
35
34
  a. 操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。
36
- b. 使用该工具之前需获取当前真实时间`,
35
+ b. 使用该工具之前需获取当前真实时间
36
+
37
+ 回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。`,
37
38
  parameters: {
38
39
  type: "object",
39
40
  properties: {
@@ -63,10 +64,6 @@ b. 使用该工具之前需获取当前真实时间`,
63
64
  },
64
65
  },
65
66
  async execute(toolCallId, params) {
66
- logger.log(`[SEARCH_ALARM_TOOL] 🚀 Starting execution`);
67
- logger.log(`[SEARCH_ALARM_TOOL] - toolCallId: ${toolCallId}`);
68
- logger.log(`[SEARCH_ALARM_TOOL] - params:`, JSON.stringify(params));
69
- logger.log(`[SEARCH_ALARM_TOOL] - timestamp: ${new Date().toISOString()}`);
70
67
  // ===== Validate at least one search criterion is provided =====
71
68
  const hasRangeType = params.rangeType !== undefined && params.rangeType !== null;
72
69
  const hasAlarmState = params.alarmState !== undefined && params.alarmState !== null;
@@ -74,92 +71,64 @@ b. 使用该工具之前需获取当前真实时间`,
74
71
  const hasStartTime = params.startTime !== undefined && params.startTime !== null;
75
72
  const hasEndTime = params.endTime !== undefined && params.endTime !== null;
76
73
  if (!hasRangeType && !hasAlarmState && !hasDaysOfWakeType && !hasStartTime && !hasEndTime) {
77
- logger.error(`[SEARCH_ALARM_TOOL] ❌ No search criteria provided`);
78
74
  throw new Error("至少需要提供一个检索条件:rangeType、alarmState、daysOfWakeType 或时间范围(startTime + endTime)");
79
75
  }
80
76
  // ===== Validate rangeType =====
81
77
  if (hasRangeType) {
82
78
  if (typeof params.rangeType !== "string") {
83
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid rangeType type`);
84
79
  throw new Error("rangeType must be a string");
85
80
  }
86
81
  if (!RANGE_TYPE_VALUES.includes(params.rangeType)) {
87
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid rangeType value: ${params.rangeType}`);
88
82
  throw new Error(`rangeType must be one of: ${RANGE_TYPE_VALUES.join(", ")}`);
89
83
  }
90
- logger.log(`[SEARCH_ALARM_TOOL] - rangeType: ${params.rangeType}`);
91
84
  }
92
85
  // ===== Validate alarmState =====
93
86
  if (hasAlarmState) {
94
87
  if (typeof params.alarmState !== "number") {
95
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid alarmState type`);
96
88
  throw new Error("alarmState must be a number");
97
89
  }
98
90
  if (!ALARM_STATE_VALUES.includes(params.alarmState)) {
99
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid alarmState value: ${params.alarmState}`);
100
91
  throw new Error(`alarmState must be one of: ${ALARM_STATE_VALUES.join(", ")}`);
101
92
  }
102
- logger.log(`[SEARCH_ALARM_TOOL] - alarmState: ${params.alarmState}`);
103
93
  }
104
94
  // ===== Validate daysOfWakeType =====
105
95
  if (hasDaysOfWakeType) {
106
96
  if (typeof params.daysOfWakeType !== "number") {
107
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid daysOfWakeType type`);
108
97
  throw new Error("daysOfWakeType must be a number");
109
98
  }
110
99
  if (!DAYS_OF_WAKE_TYPE_VALUES.includes(params.daysOfWakeType)) {
111
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid daysOfWakeType value: ${params.daysOfWakeType}`);
112
100
  throw new Error(`daysOfWakeType must be one of: ${DAYS_OF_WAKE_TYPE_VALUES.join(", ")}`);
113
101
  }
114
- logger.log(`[SEARCH_ALARM_TOOL] - daysOfWakeType: ${params.daysOfWakeType}`);
115
102
  }
116
103
  // ===== Validate time interval (startTime and endTime must be provided together) =====
117
104
  if (hasStartTime !== hasEndTime) {
118
- logger.error(`[SEARCH_ALARM_TOOL] ❌ startTime and endTime must be provided together`);
119
105
  throw new Error("startTime 和 endTime 必须一起提供");
120
106
  }
121
107
  let timeInterval = null;
122
108
  if (hasStartTime && hasEndTime) {
123
109
  // Parse and convert startTime and endTime to timestamps
124
- logger.log(`[SEARCH_ALARM_TOOL] 🕒 Parsing time interval...`);
125
- logger.log(`[SEARCH_ALARM_TOOL] - startTime input: ${params.startTime}`);
126
- logger.log(`[SEARCH_ALARM_TOOL] - endTime input: ${params.endTime}`);
127
110
  const startTimeMs = parseAlarmTimeToTimestamp(params.startTime);
128
111
  const endTimeMs = parseAlarmTimeToTimestamp(params.endTime);
129
112
  if (startTimeMs === null) {
130
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid startTime format`);
131
113
  throw new Error("Invalid startTime format. Required format: YYYYMMDD hhmmss (e.g., 20240315 000000)");
132
114
  }
133
115
  if (endTimeMs === null) {
134
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid endTime format`);
135
116
  throw new Error("Invalid endTime format. Required format: YYYYMMDD hhmmss (e.g., 20240315 235959)");
136
117
  }
137
118
  if (startTimeMs >= endTimeMs) {
138
- logger.error(`[SEARCH_ALARM_TOOL] ❌ startTime must be before endTime`);
139
119
  throw new Error("startTime 必须早于 endTime");
140
120
  }
141
121
  timeInterval = [startTimeMs, endTimeMs];
142
- logger.log(`[SEARCH_ALARM_TOOL] ✅ Time interval parsed: [${startTimeMs}, ${endTimeMs}]`);
143
122
  }
144
123
  // Get session context
145
- logger.log(`[SEARCH_ALARM_TOOL] 🔍 Attempting to get session context...`);
146
124
  const sessionContext = getCurrentSessionContext();
147
125
  if (!sessionContext) {
148
- logger.error(`[SEARCH_ALARM_TOOL] ❌ FAILED: No active session found!`);
149
- logger.error(`[SEARCH_ALARM_TOOL] - toolCallId: ${toolCallId}`);
150
126
  throw new Error("No active XY session found. Search alarm tool can only be used during an active conversation.");
151
127
  }
152
- logger.log(`[SEARCH_ALARM_TOOL] ✅ Session context found`);
153
- logger.log(`[SEARCH_ALARM_TOOL] - sessionId: ${sessionContext.sessionId}`);
154
- logger.log(`[SEARCH_ALARM_TOOL] - taskId: ${sessionContext.taskId}`);
155
- logger.log(`[SEARCH_ALARM_TOOL] - messageId: ${sessionContext.messageId}`);
156
128
  const { config, sessionId, taskId, messageId } = sessionContext;
157
129
  // Get WebSocket manager
158
- logger.log(`[SEARCH_ALARM_TOOL] 🔌 Getting WebSocket manager...`);
159
130
  const wsManager = getXYWebSocketManager(config);
160
- logger.log(`[SEARCH_ALARM_TOOL] ✅ WebSocket manager obtained`);
161
131
  // Build SearchAlarm command
162
- logger.log(`[SEARCH_ALARM_TOOL] 📦 Building SearchAlarm command...`);
163
132
  // Build intentParam with provided search criteria
164
133
  const intentParam = {};
165
134
  if (hasRangeType) {
@@ -206,25 +175,17 @@ b. 使用该工具之前需获取当前真实时间`,
206
175
  },
207
176
  };
208
177
  // Send command and wait for response (60 second timeout)
209
- logger.log(`[SEARCH_ALARM_TOOL] ⏳ Setting up promise to wait for alarm search response...`);
210
- logger.log(`[SEARCH_ALARM_TOOL] - Timeout: 60 seconds`);
211
178
  return new Promise((resolve, reject) => {
212
179
  const timeout = setTimeout(() => {
213
- logger.error(`[SEARCH_ALARM_TOOL] ⏰ Timeout: No response received within 60 seconds`);
214
180
  wsManager.off("data-event", handler);
215
181
  reject(new Error("检索闹钟超时(60秒)"));
216
182
  }, 60000);
217
183
  // Listen for data events from WebSocket
218
184
  const handler = (event) => {
219
- logger.log(`[SEARCH_ALARM_TOOL] 📨 Received data event:`, JSON.stringify(event));
220
185
  if (event.intentName === "SearchAlarm") {
221
- logger.log(`[SEARCH_ALARM_TOOL] 🎯 SearchAlarm event received`);
222
- logger.log(`[SEARCH_ALARM_TOOL] - status: ${event.status}`);
223
186
  clearTimeout(timeout);
224
187
  wsManager.off("data-event", handler);
225
188
  if (event.status === "success" && event.outputs) {
226
- logger.log(`[SEARCH_ALARM_TOOL] ✅ Alarm search completed successfully`);
227
- logger.log(`[SEARCH_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs));
228
189
  // 成功,直接返回完整的 event.outputs JSON 字符串
229
190
  resolve({
230
191
  content: [
@@ -236,18 +197,13 @@ b. 使用该工具之前需获取当前真实时间`,
236
197
  });
237
198
  }
238
199
  else {
239
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Alarm search failed`);
240
- logger.error(`[SEARCH_ALARM_TOOL] - status: ${event.status}`);
241
- logger.error(`[SEARCH_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs || {}));
242
200
  reject(new Error(`检索闹钟失败: ${event.status}`));
243
201
  }
244
202
  }
245
203
  };
246
204
  // Register event handler
247
- logger.log(`[SEARCH_ALARM_TOOL] 📡 Registering data-event handler on WebSocket manager`);
248
205
  wsManager.on("data-event", handler);
249
206
  // Send the command
250
- logger.log(`[SEARCH_ALARM_TOOL] 📤 Sending SearchAlarm command...`);
251
207
  sendCommand({
252
208
  config,
253
209
  sessionId,
@@ -256,10 +212,8 @@ b. 使用该工具之前需获取当前真实时间`,
256
212
  command,
257
213
  })
258
214
  .then(() => {
259
- logger.log(`[SEARCH_ALARM_TOOL] ✅ Command sent successfully, waiting for response...`);
260
215
  })
261
216
  .catch((error) => {
262
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Failed to send command:`, error);
263
217
  clearTimeout(timeout);
264
218
  wsManager.off("data-event", handler);
265
219
  reject(error);
@@ -279,17 +233,14 @@ function parseAlarmTimeToTimestamp(alarmTime) {
279
233
  const trimmed = alarmTime.trim();
280
234
  // Check basic format (should have at least 13 characters: YYYYMMDD hhmmss)
281
235
  if (trimmed.length < 13) {
282
- logger.error(`[SEARCH_ALARM_TOOL] ❌ alarmTime too short: ${trimmed}`);
283
236
  return null;
284
237
  }
285
238
  // Extract date and time parts
286
239
  // Format: YYYYMMDD hhmmss
287
240
  const datePart = trimmed.substring(0, 8); // YYYYMMDD
288
241
  const timePart = trimmed.substring(8).trim(); // hhmmss (may have leading space)
289
- logger.log(`[SEARCH_ALARM_TOOL] - datePart: ${datePart}, timePart: ${timePart}`);
290
242
  // Validate lengths
291
243
  if (datePart.length !== 8 || timePart.length !== 6) {
292
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid part lengths: datePart=${datePart.length}, timePart=${timePart.length}`);
293
244
  return null;
294
245
  }
295
246
  // Parse components
@@ -299,45 +250,36 @@ function parseAlarmTimeToTimestamp(alarmTime) {
299
250
  const hour = parseInt(timePart.substring(0, 2), 10);
300
251
  const minute = parseInt(timePart.substring(2, 4), 10);
301
252
  const second = parseInt(timePart.substring(4, 6), 10);
302
- logger.log(`[SEARCH_ALARM_TOOL] - Parsed: ${year}-${month}-${day} ${hour}:${minute}:${second}`);
303
253
  // Validate values
304
254
  if (isNaN(year) || isNaN(month) || isNaN(day) ||
305
255
  isNaN(hour) || isNaN(minute) || isNaN(second)) {
306
- logger.error(`[SEARCH_ALARM_TOOL] ❌ NaN detected in parsed values`);
307
256
  return null;
308
257
  }
309
258
  // Validate ranges
310
259
  if (month < 1 || month > 12) {
311
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid month: ${month}`);
312
260
  return null;
313
261
  }
314
262
  if (day < 1 || day > 31) {
315
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid day: ${day}`);
316
263
  return null;
317
264
  }
318
265
  if (hour < 0 || hour > 23) {
319
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid hour: ${hour}`);
320
266
  return null;
321
267
  }
322
268
  if (minute < 0 || minute > 59) {
323
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid minute: ${minute}`);
324
269
  return null;
325
270
  }
326
271
  if (second < 0 || second > 59) {
327
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Invalid second: ${second}`);
328
272
  return null;
329
273
  }
330
274
  // Create Date object and get timestamp
331
275
  const date = new Date(year, month - 1, day, hour, minute, second);
332
276
  const timestamp = date.getTime();
333
277
  if (isNaN(timestamp)) {
334
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Generated timestamp is NaN`);
335
278
  return null;
336
279
  }
337
280
  return timestamp;
338
281
  }
339
282
  catch (error) {
340
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Exception in parseAlarmTimeToTimestamp:`, error);
341
283
  return null;
342
284
  }
343
285
  }
@@ -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 search calendar event tool - searches calendar events on user's device.
7
6
  * Returns matching events based on time range and optional title filter.
@@ -28,6 +27,8 @@ export const searchCalendarTool = {
28
27
  注意:
29
28
  a. 该工具执行时间较长(最多60秒),请勿重复调用,超时或失败时最多重试一次。
30
29
  b. 使用该工具之前需获取当前真实时间
30
+
31
+ 回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。
31
32
  `,
32
33
  parameters: {
33
34
  type: "object",
@@ -48,19 +49,11 @@ b. 使用该工具之前需获取当前真实时间
48
49
  required: ["startTime", "endTime"],
49
50
  },
50
51
  async execute(toolCallId, params) {
51
- logger.log(`[SEARCH_CALENDAR_TOOL] 🚀 Starting execution`);
52
- logger.log(`[SEARCH_CALENDAR_TOOL] - toolCallId: ${toolCallId}`);
53
- logger.log(`[SEARCH_CALENDAR_TOOL] - params:`, JSON.stringify(params));
54
- logger.log(`[SEARCH_CALENDAR_TOOL] - timestamp: ${new Date().toISOString()}`);
55
52
  // Validate parameters
56
53
  if (!params.startTime || !params.endTime) {
57
- logger.error(`[SEARCH_CALENDAR_TOOL] ❌ Missing required parameters`);
58
54
  throw new Error("Missing required parameters: startTime and endTime are required");
59
55
  }
60
56
  // Convert time strings to millisecond timestamps
61
- logger.log(`[SEARCH_CALENDAR_TOOL] 🕒 Converting time strings to timestamps...`);
62
- logger.log(`[SEARCH_CALENDAR_TOOL] - startTime input: ${params.startTime}`);
63
- logger.log(`[SEARCH_CALENDAR_TOOL] - endTime input: ${params.endTime}`);
64
57
  // Parse YYYYMMDD hhmmss format
65
58
  const parseTimeString = (timeStr) => {
66
59
  // Remove any extra spaces and split
@@ -90,42 +83,26 @@ b. 使用该工具之前需获取当前真实时间
90
83
  endTimeMs = parseTimeString(params.endTime);
91
84
  }
92
85
  catch (error) {
93
- logger.error(`[SEARCH_CALENDAR_TOOL] ❌ Time parsing error:`, error);
94
86
  throw new Error(`Invalid time format. Required format: YYYYMMDD hhmmss (e.g., 20240115 143000). Error: ${error instanceof Error ? error.message : String(error)}`);
95
87
  }
96
88
  if (isNaN(startTimeMs) || isNaN(endTimeMs)) {
97
- logger.error(`[SEARCH_CALENDAR_TOOL] ❌ Invalid time format`);
98
89
  throw new Error("Invalid time format. Required format: YYYYMMDD hhmmss (e.g., 20240115 143000)");
99
90
  }
100
- logger.log(`[SEARCH_CALENDAR_TOOL] ✅ Time conversion successful`);
101
- logger.log(`[SEARCH_CALENDAR_TOOL] - startTime timestamp: ${startTimeMs}`);
102
- logger.log(`[SEARCH_CALENDAR_TOOL] - endTime timestamp: ${endTimeMs}`);
103
91
  // Get session context
104
- logger.log(`[SEARCH_CALENDAR_TOOL] 🔍 Attempting to get session context...`);
105
92
  const sessionContext = getCurrentSessionContext();
106
93
  if (!sessionContext) {
107
- logger.error(`[SEARCH_CALENDAR_TOOL] ❌ FAILED: No active session found!`);
108
- logger.error(`[SEARCH_CALENDAR_TOOL] - toolCallId: ${toolCallId}`);
109
94
  throw new Error("No active XY session found. Search calendar tool can only be used during an active conversation.");
110
95
  }
111
- logger.log(`[SEARCH_CALENDAR_TOOL] ✅ Session context found`);
112
- logger.log(`[SEARCH_CALENDAR_TOOL] - sessionId: ${sessionContext.sessionId}`);
113
- logger.log(`[SEARCH_CALENDAR_TOOL] - taskId: ${sessionContext.taskId}`);
114
- logger.log(`[SEARCH_CALENDAR_TOOL] - messageId: ${sessionContext.messageId}`);
115
96
  const { config, sessionId, taskId, messageId } = sessionContext;
116
97
  // Get WebSocket manager
117
- logger.log(`[SEARCH_CALENDAR_TOOL] 🔌 Getting WebSocket manager...`);
118
98
  const wsManager = getXYWebSocketManager(config);
119
- logger.log(`[SEARCH_CALENDAR_TOOL] ✅ WebSocket manager obtained`);
120
99
  // Build SearchCalendarEvent command
121
- logger.log(`[SEARCH_CALENDAR_TOOL] 📦 Building SearchCalendarEvent command...`);
122
100
  // Build intentParam with timeInterval and optional title
123
101
  const intentParam = {
124
102
  timeInterval: [startTimeMs, endTimeMs],
125
103
  };
126
104
  if (params.title) {
127
105
  intentParam.title = params.title;
128
- logger.log(`[SEARCH_CALENDAR_TOOL] - Including title filter: ${params.title}`);
129
106
  }
130
107
  const command = {
131
108
  header: {
@@ -160,25 +137,17 @@ b. 使用该工具之前需获取当前真实时间
160
137
  },
161
138
  };
162
139
  // Send command and wait for response (60 second timeout)
163
- logger.log(`[SEARCH_CALENDAR_TOOL] ⏳ Setting up promise to wait for calendar search response...`);
164
- logger.log(`[SEARCH_CALENDAR_TOOL] - Timeout: 60 seconds`);
165
140
  return new Promise((resolve, reject) => {
166
141
  const timeout = setTimeout(() => {
167
- logger.error(`[SEARCH_CALENDAR_TOOL] ⏰ Timeout: No response received within 60 seconds`);
168
142
  wsManager.off("data-event", handler);
169
143
  reject(new Error("检索日程超时(60秒)"));
170
144
  }, 60000);
171
145
  // Listen for data events from WebSocket
172
146
  const handler = (event) => {
173
- logger.log(`[SEARCH_CALENDAR_TOOL] 📨 Received data event:`, JSON.stringify(event));
174
147
  if (event.intentName === "SearchCalendarEvent") {
175
- logger.log(`[SEARCH_CALENDAR_TOOL] 🎯 SearchCalendarEvent event received`);
176
- logger.log(`[SEARCH_CALENDAR_TOOL] - status: ${event.status}`);
177
148
  clearTimeout(timeout);
178
149
  wsManager.off("data-event", handler);
179
150
  if (event.status === "success" && event.outputs) {
180
- logger.log(`[SEARCH_CALENDAR_TOOL] ✅ Calendar events retrieved successfully`);
181
- logger.log(`[SEARCH_CALENDAR_TOOL] - outputs:`, JSON.stringify(event.outputs));
182
151
  // 成功,直接返回完整的 event.outputs JSON 字符串
183
152
  resolve({
184
153
  content: [
@@ -190,17 +159,13 @@ b. 使用该工具之前需获取当前真实时间
190
159
  });
191
160
  }
192
161
  else {
193
- logger.error(`[SEARCH_CALENDAR_TOOL] ❌ Calendar event search failed`);
194
- logger.error(`[SEARCH_CALENDAR_TOOL] - status: ${event.status}`);
195
162
  reject(new Error(`检索日程失败: ${event.status}`));
196
163
  }
197
164
  }
198
165
  };
199
166
  // Register event handler
200
- logger.log(`[SEARCH_CALENDAR_TOOL] 📡 Registering data-event handler on WebSocket manager`);
201
167
  wsManager.on("data-event", handler);
202
168
  // Send the command
203
- logger.log(`[SEARCH_CALENDAR_TOOL] 📤 Sending SearchCalendarEvent command...`);
204
169
  sendCommand({
205
170
  config,
206
171
  sessionId,
@@ -209,10 +174,8 @@ b. 使用该工具之前需获取当前真实时间
209
174
  command,
210
175
  })
211
176
  .then(() => {
212
- logger.log(`[SEARCH_CALENDAR_TOOL] ✅ Command sent successfully, waiting for response...`);
213
177
  })
214
178
  .catch((error) => {
215
- logger.error(`[SEARCH_CALENDAR_TOOL] ❌ Failed to send command:`, error);
216
179
  clearTimeout(timeout);
217
180
  wsManager.off("data-event", handler);
218
181
  reject(error);
@@ -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 search contact tool - searches contacts on user's device.
7
6
  * Returns matching contact information based on name.
@@ -21,34 +20,19 @@ export const searchContactTool = {
21
20
  required: ["name"],
22
21
  },
23
22
  async execute(toolCallId, params) {
24
- logger.log(`[SEARCH_CONTACT_TOOL] 🚀 Starting execution`);
25
- logger.log(`[SEARCH_CONTACT_TOOL] - toolCallId: ${toolCallId}`);
26
- logger.log(`[SEARCH_CONTACT_TOOL] - params:`, JSON.stringify(params));
27
- logger.log(`[SEARCH_CONTACT_TOOL] - timestamp: ${new Date().toISOString()}`);
28
23
  // Validate parameters
29
24
  if (!params.name) {
30
- logger.error(`[SEARCH_CONTACT_TOOL] ❌ Missing required parameter: name`);
31
25
  throw new Error("Missing required parameter: name is required");
32
26
  }
33
27
  // Get session context
34
- logger.log(`[SEARCH_CONTACT_TOOL] 🔍 Attempting to get session context...`);
35
28
  const sessionContext = getCurrentSessionContext();
36
29
  if (!sessionContext) {
37
- logger.error(`[SEARCH_CONTACT_TOOL] ❌ FAILED: No active session found!`);
38
- logger.error(`[SEARCH_CONTACT_TOOL] - toolCallId: ${toolCallId}`);
39
30
  throw new Error("No active XY session found. Search contact tool can only be used during an active conversation.");
40
31
  }
41
- logger.log(`[SEARCH_CONTACT_TOOL] ✅ Session context found`);
42
- logger.log(`[SEARCH_CONTACT_TOOL] - sessionId: ${sessionContext.sessionId}`);
43
- logger.log(`[SEARCH_CONTACT_TOOL] - taskId: ${sessionContext.taskId}`);
44
- logger.log(`[SEARCH_CONTACT_TOOL] - messageId: ${sessionContext.messageId}`);
45
32
  const { config, sessionId, taskId, messageId } = sessionContext;
46
33
  // Get WebSocket manager
47
- logger.log(`[SEARCH_CONTACT_TOOL] 🔌 Getting WebSocket manager...`);
48
34
  const wsManager = getXYWebSocketManager(config);
49
- logger.log(`[SEARCH_CONTACT_TOOL] ✅ WebSocket manager obtained`);
50
35
  // Build SearchContactLocal command
51
- logger.log(`[SEARCH_CONTACT_TOOL] 📦 Building SearchContactLocal command...`);
52
36
  const command = {
53
37
  header: {
54
38
  namespace: "Common",
@@ -83,25 +67,17 @@ export const searchContactTool = {
83
67
  },
84
68
  };
85
69
  // Send command and wait for response (60 second timeout)
86
- logger.log(`[SEARCH_CONTACT_TOOL] ⏳ Setting up promise to wait for contact search response...`);
87
- logger.log(`[SEARCH_CONTACT_TOOL] - Timeout: 60 seconds`);
88
70
  return new Promise((resolve, reject) => {
89
71
  const timeout = setTimeout(() => {
90
- logger.error(`[SEARCH_CONTACT_TOOL] ⏰ Timeout: No response received within 60 seconds`);
91
72
  wsManager.off("data-event", handler);
92
73
  reject(new Error("搜索联系人超时(60秒)"));
93
74
  }, 60000);
94
75
  // Listen for data events from WebSocket
95
76
  const handler = (event) => {
96
- logger.log(`[SEARCH_CONTACT_TOOL] 📨 Received data event:`, JSON.stringify(event));
97
77
  if (event.intentName === "SearchContactLocal") {
98
- logger.log(`[SEARCH_CONTACT_TOOL] 🎯 SearchContactLocal event received`);
99
- logger.log(`[SEARCH_CONTACT_TOOL] - status: ${event.status}`);
100
78
  clearTimeout(timeout);
101
79
  wsManager.off("data-event", handler);
102
80
  if (event.status === "success" && event.outputs) {
103
- logger.log(`[SEARCH_CONTACT_TOOL] ✅ Contact search completed successfully`);
104
- logger.log(`[SEARCH_CONTACT_TOOL] - outputs:`, JSON.stringify(event.outputs));
105
81
  // 成功,直接返回完整的 event.outputs JSON 字符串
106
82
  resolve({
107
83
  content: [
@@ -113,17 +89,13 @@ export const searchContactTool = {
113
89
  });
114
90
  }
115
91
  else {
116
- logger.error(`[SEARCH_CONTACT_TOOL] ❌ Contact search failed`);
117
- logger.error(`[SEARCH_CONTACT_TOOL] - status: ${event.status}`);
118
92
  reject(new Error(`搜索联系人失败: ${event.status}`));
119
93
  }
120
94
  }
121
95
  };
122
96
  // Register event handler
123
- logger.log(`[SEARCH_CONTACT_TOOL] 📡 Registering data-event handler on WebSocket manager`);
124
97
  wsManager.on("data-event", handler);
125
98
  // Send the command
126
- logger.log(`[SEARCH_CONTACT_TOOL] 📤 Sending SearchContactLocal command...`);
127
99
  sendCommand({
128
100
  config,
129
101
  sessionId,
@@ -132,10 +104,8 @@ export const searchContactTool = {
132
104
  command,
133
105
  })
134
106
  .then(() => {
135
- logger.log(`[SEARCH_CONTACT_TOOL] ✅ Command sent successfully, waiting for response...`);
136
107
  })
137
108
  .catch((error) => {
138
- logger.error(`[SEARCH_CONTACT_TOOL] ❌ Failed to send command:`, error);
139
109
  clearTimeout(timeout);
140
110
  wsManager.off("data-event", handler);
141
111
  reject(error);
@@ -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 search file tool - searches files on user's device file system.
7
6
  * Returns matching files based on keyword search in file name or content.
@@ -33,35 +32,19 @@ export const searchFileTool = {
33
32
  required: ["query"],
34
33
  },
35
34
  async execute(toolCallId, params) {
36
- logger.log(`[SEARCH_FILE_TOOL] 🚀 Starting execution`);
37
- logger.log(`[SEARCH_FILE_TOOL] - toolCallId: ${toolCallId}`);
38
- logger.log(`[SEARCH_FILE_TOOL] - params:`, JSON.stringify(params));
39
- logger.log(`[SEARCH_FILE_TOOL] - timestamp: ${new Date().toISOString()}`);
40
35
  // Validate query parameter
41
36
  if (!params.query || typeof params.query !== "string" || params.query.trim() === "") {
42
- logger.error(`[SEARCH_FILE_TOOL] ❌ Missing or invalid query parameter`);
43
37
  throw new Error("Missing required parameter: query must be a non-empty string");
44
38
  }
45
- logger.log(`[SEARCH_FILE_TOOL] 🔍 Searching for files with keyword: ${params.query}`);
46
39
  // Get session context
47
- logger.log(`[SEARCH_FILE_TOOL] 🔍 Attempting to get session context...`);
48
40
  const sessionContext = getCurrentSessionContext();
49
41
  if (!sessionContext) {
50
- logger.error(`[SEARCH_FILE_TOOL] ❌ FAILED: No active session found!`);
51
- logger.error(`[SEARCH_FILE_TOOL] - toolCallId: ${toolCallId}`);
52
42
  throw new Error("No active XY session found. Search file tool can only be used during an active conversation.");
53
43
  }
54
- logger.log(`[SEARCH_FILE_TOOL] ✅ Session context found`);
55
- logger.log(`[SEARCH_FILE_TOOL] - sessionId: ${sessionContext.sessionId}`);
56
- logger.log(`[SEARCH_FILE_TOOL] - taskId: ${sessionContext.taskId}`);
57
- logger.log(`[SEARCH_FILE_TOOL] - messageId: ${sessionContext.messageId}`);
58
44
  const { config, sessionId, taskId, messageId } = sessionContext;
59
45
  // Get WebSocket manager
60
- logger.log(`[SEARCH_FILE_TOOL] 🔌 Getting WebSocket manager...`);
61
46
  const wsManager = getXYWebSocketManager(config);
62
- logger.log(`[SEARCH_FILE_TOOL] ✅ WebSocket manager obtained`);
63
47
  // Build SearchFile command
64
- logger.log(`[SEARCH_FILE_TOOL] 📦 Building SearchFile command...`);
65
48
  const command = {
66
49
  header: {
67
50
  namespace: "Common",
@@ -95,27 +78,18 @@ export const searchFileTool = {
95
78
  pageControlRelated: false,
96
79
  },
97
80
  };
98
- logger.log(`[SEARCH_FILE_TOOL] 📋 Command details:`, JSON.stringify(command, null, 2));
99
81
  // Send command and wait for response (60 second timeout)
100
- logger.log(`[SEARCH_FILE_TOOL] ⏳ Setting up promise to wait for file search response...`);
101
- logger.log(`[SEARCH_FILE_TOOL] - Timeout: 60 seconds`);
102
82
  return new Promise((resolve, reject) => {
103
83
  const timeout = setTimeout(() => {
104
- logger.error(`[SEARCH_FILE_TOOL] ⏰ Timeout: No response received within 60 seconds`);
105
84
  wsManager.off("data-event", handler);
106
85
  reject(new Error("搜索文件超时(60秒)"));
107
86
  }, 60000);
108
87
  // Listen for data events from WebSocket
109
88
  const handler = (event) => {
110
- logger.log(`[SEARCH_FILE_TOOL] 📨 Received data event:`, JSON.stringify(event));
111
89
  if (event.intentName === "SearchFile") {
112
- logger.log(`[SEARCH_FILE_TOOL] 🎯 SearchFile event received`);
113
- logger.log(`[SEARCH_FILE_TOOL] - status: ${event.status}`);
114
90
  clearTimeout(timeout);
115
91
  wsManager.off("data-event", handler);
116
92
  if (event.status === "success" && event.outputs) {
117
- logger.log(`[SEARCH_FILE_TOOL] ✅ File search completed successfully`);
118
- logger.log(`[SEARCH_FILE_TOOL] - outputs:`, JSON.stringify(event.outputs));
119
93
  // 成功,直接返回完整的 event.outputs JSON 字符串
120
94
  resolve({
121
95
  content: [
@@ -127,19 +101,14 @@ export const searchFileTool = {
127
101
  });
128
102
  }
129
103
  else {
130
- logger.error(`[SEARCH_FILE_TOOL] ❌ File search failed`);
131
- logger.error(`[SEARCH_FILE_TOOL] - status: ${event.status}`);
132
- logger.error(`[SEARCH_FILE_TOOL] - outputs:`, JSON.stringify(event.outputs || {}));
133
104
  const errorDetail = event.outputs ? JSON.stringify(event.outputs) : event.status;
134
105
  reject(new Error(`搜索文件失败: ${errorDetail}`));
135
106
  }
136
107
  }
137
108
  };
138
109
  // Register event handler
139
- logger.log(`[SEARCH_FILE_TOOL] 📡 Registering data-event handler on WebSocket manager`);
140
110
  wsManager.on("data-event", handler);
141
111
  // Send the command
142
- logger.log(`[SEARCH_FILE_TOOL] 📤 Sending SearchFile command...`);
143
112
  sendCommand({
144
113
  config,
145
114
  sessionId,
@@ -148,10 +117,8 @@ export const searchFileTool = {
148
117
  command,
149
118
  })
150
119
  .then(() => {
151
- logger.log(`[SEARCH_FILE_TOOL] ✅ Command sent successfully, waiting for response...`);
152
120
  })
153
121
  .catch((error) => {
154
- logger.error(`[SEARCH_FILE_TOOL] ❌ Failed to send command:`, error);
155
122
  clearTimeout(timeout);
156
123
  wsManager.off("data-event", handler);
157
124
  reject(error);