@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 parameters (same as create-alarm-tool)
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];
@@ -39,7 +38,9 @@ export const modifyAlarmTool = {
39
38
  2. 调用此工具修改闹钟,传入 entityId 和需要修改的参数
40
39
  3. 其余不涉及需改的参数,如果search_alarm 或 create_alarm的结果中有相应的值,需要一并填上,需要与原有的保持一致,防止不填采用默认值
41
40
 
42
- 注意事项:操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。`,
41
+ 注意事项:操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。
42
+
43
+ 回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。`,
43
44
  parameters: {
44
45
  type: "object",
45
46
  properties: {
@@ -84,16 +85,10 @@ export const modifyAlarmTool = {
84
85
  required: ["entityId"],
85
86
  },
86
87
  async execute(toolCallId, params) {
87
- logger.log(`[MODIFY_ALARM_TOOL] 🚀 Starting execution`);
88
- logger.log(`[MODIFY_ALARM_TOOL] - toolCallId: ${toolCallId}`);
89
- logger.log(`[MODIFY_ALARM_TOOL] - params:`, JSON.stringify(params));
90
- logger.log(`[MODIFY_ALARM_TOOL] - timestamp: ${new Date().toISOString()}`);
91
88
  // ===== Validate required parameter: entityId =====
92
89
  if (!params.entityId || typeof params.entityId !== "string") {
93
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Missing or invalid entityId`);
94
90
  throw new Error("Missing required parameter: entityId must be a string obtained from search_alarm or create_alarm");
95
91
  }
96
- logger.log(`[MODIFY_ALARM_TOOL] - entityId: ${params.entityId}`);
97
92
  // ===== Build intentParam with provided parameters =====
98
93
  const intentParam = {
99
94
  entityName: "Alarm",
@@ -102,98 +97,76 @@ export const modifyAlarmTool = {
102
97
  // Parse and convert alarmTime if provided
103
98
  if (params.alarmTime !== undefined && params.alarmTime !== null) {
104
99
  if (typeof params.alarmTime !== "string") {
105
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmTime type`);
106
100
  throw new Error("alarmTime must be a string in format YYYYMMDD hhmmss");
107
101
  }
108
- logger.log(`[MODIFY_ALARM_TOOL] 🕒 Parsing alarmTime: ${params.alarmTime}`);
109
102
  const alarmTimeMs = parseAlarmTimeToTimestamp(params.alarmTime);
110
103
  if (alarmTimeMs === null) {
111
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmTime format`);
112
104
  throw new Error("Invalid alarmTime format. Required format: YYYYMMDD hhmmss (e.g., 20240315 143000)");
113
105
  }
114
106
  intentParam.alarmTime = alarmTimeMs;
115
- logger.log(`[MODIFY_ALARM_TOOL] ✅ alarmTime converted to timestamp: ${alarmTimeMs}`);
116
107
  }
117
108
  // Add alarmTitle if provided
118
109
  if (params.alarmTitle !== undefined && params.alarmTitle !== null) {
119
110
  if (typeof params.alarmTitle !== "string") {
120
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmTitle type`);
121
111
  throw new Error("alarmTitle must be a string");
122
112
  }
123
113
  intentParam.alarmTitle = params.alarmTitle;
124
- logger.log(`[MODIFY_ALARM_TOOL] - alarmTitle: ${params.alarmTitle}`);
125
114
  }
126
115
  // Add alarmState if provided
127
116
  if (params.alarmState !== undefined && params.alarmState !== null) {
128
117
  if (typeof params.alarmState !== "number") {
129
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmState type`);
130
118
  throw new Error("alarmState must be a number");
131
119
  }
132
120
  if (!ALARM_STATE_VALUES.includes(params.alarmState)) {
133
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmState value: ${params.alarmState}`);
134
121
  throw new Error(`alarmState must be one of: ${ALARM_STATE_VALUES.join(", ")}`);
135
122
  }
136
123
  intentParam.alarmState = params.alarmState;
137
- logger.log(`[MODIFY_ALARM_TOOL] - alarmState: ${params.alarmState}`);
138
124
  }
139
125
  // Add alarmSnoozeDuration if provided
140
126
  if (params.alarmSnoozeDuration !== undefined && params.alarmSnoozeDuration !== null) {
141
127
  if (typeof params.alarmSnoozeDuration !== "number") {
142
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmSnoozeDuration type`);
143
128
  throw new Error("alarmSnoozeDuration must be a number");
144
129
  }
145
130
  if (!ALARM_SNOOZE_DURATION_VALUES.includes(params.alarmSnoozeDuration)) {
146
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmSnoozeDuration value: ${params.alarmSnoozeDuration}`);
147
131
  throw new Error(`alarmSnoozeDuration must be one of: ${ALARM_SNOOZE_DURATION_VALUES.join(", ")}`);
148
132
  }
149
133
  intentParam.alarmSnoozeDuration = params.alarmSnoozeDuration;
150
- logger.log(`[MODIFY_ALARM_TOOL] - alarmSnoozeDuration: ${params.alarmSnoozeDuration}`);
151
134
  }
152
135
  // Add alarmSnoozeTotal if provided
153
136
  if (params.alarmSnoozeTotal !== undefined && params.alarmSnoozeTotal !== null) {
154
137
  if (typeof params.alarmSnoozeTotal !== "number") {
155
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmSnoozeTotal type`);
156
138
  throw new Error("alarmSnoozeTotal must be a number");
157
139
  }
158
140
  if (!ALARM_SNOOZE_TOTAL_VALUES.includes(params.alarmSnoozeTotal)) {
159
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmSnoozeTotal value: ${params.alarmSnoozeTotal}`);
160
141
  throw new Error(`alarmSnoozeTotal must be one of: ${ALARM_SNOOZE_TOTAL_VALUES.join(", ")}`);
161
142
  }
162
143
  intentParam.alarmSnoozeTotal = params.alarmSnoozeTotal;
163
- logger.log(`[MODIFY_ALARM_TOOL] - alarmSnoozeTotal: ${params.alarmSnoozeTotal}`);
164
144
  }
165
145
  // Add alarmRingDuration if provided
166
146
  if (params.alarmRingDuration !== undefined && params.alarmRingDuration !== null) {
167
147
  if (typeof params.alarmRingDuration !== "number") {
168
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmRingDuration type`);
169
148
  throw new Error("alarmRingDuration must be a number");
170
149
  }
171
150
  if (!ALARM_RING_DURATION_VALUES.includes(params.alarmRingDuration)) {
172
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid alarmRingDuration value: ${params.alarmRingDuration}`);
173
151
  throw new Error(`alarmRingDuration must be one of: ${ALARM_RING_DURATION_VALUES.join(", ")}`);
174
152
  }
175
153
  intentParam.alarmRingDuration = params.alarmRingDuration;
176
- logger.log(`[MODIFY_ALARM_TOOL] - alarmRingDuration: ${params.alarmRingDuration}`);
177
154
  }
178
155
  // Add daysOfWakeType if provided
179
156
  if (params.daysOfWakeType !== undefined && params.daysOfWakeType !== null) {
180
157
  if (typeof params.daysOfWakeType !== "number") {
181
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid daysOfWakeType type`);
182
158
  throw new Error("daysOfWakeType must be a number");
183
159
  }
184
160
  if (!DAYS_OF_WAKE_TYPE_VALUES.includes(params.daysOfWakeType)) {
185
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid daysOfWakeType value: ${params.daysOfWakeType}`);
186
161
  throw new Error(`daysOfWakeType must be one of: ${DAYS_OF_WAKE_TYPE_VALUES.join(", ")}`);
187
162
  }
188
163
  intentParam.daysOfWakeType = params.daysOfWakeType;
189
- logger.log(`[MODIFY_ALARM_TOOL] - daysOfWakeType: ${params.daysOfWakeType}`);
190
164
  }
191
165
  // Add daysOfWeek if provided - only valid when daysOfWakeType is 3
192
166
  if (params.daysOfWeek !== undefined && params.daysOfWeek !== null) {
193
167
  // Check if daysOfWakeType is 3 or will be set to 3
194
168
  const targetDaysOfWakeType = params.daysOfWakeType !== undefined ? params.daysOfWakeType : null;
195
169
  if (targetDaysOfWakeType !== null && targetDaysOfWakeType !== 3) {
196
- logger.warn(`[MODIFY_ALARM_TOOL] ⚠️ daysOfWeek parameter is ignored when daysOfWakeType is not 3 (current: ${targetDaysOfWakeType}). Please remove daysOfWeek parameter.`);
197
170
  // Skip processing daysOfWeek when daysOfWakeType is not 3
198
171
  }
199
172
  else {
@@ -201,73 +174,53 @@ export const modifyAlarmTool = {
201
174
  let normalizedDaysOfWeek = null;
202
175
  // 情况1: 已经是数组
203
176
  if (Array.isArray(params.daysOfWeek)) {
204
- logger.log(`[MODIFY_ALARM_TOOL] ✅ daysOfWeek is already an array`);
205
177
  normalizedDaysOfWeek = params.daysOfWeek;
206
178
  }
207
179
  // 情况2: 是字符串,尝试解析为 JSON 数组
208
180
  else if (typeof params.daysOfWeek === 'string') {
209
- logger.log(`[MODIFY_ALARM_TOOL] 🔄 daysOfWeek is a string, attempting to parse as JSON...`);
210
181
  try {
211
182
  const parsed = JSON.parse(params.daysOfWeek);
212
183
  if (Array.isArray(parsed)) {
213
- logger.log(`[MODIFY_ALARM_TOOL] ✅ Successfully parsed JSON string to array`);
214
184
  normalizedDaysOfWeek = parsed;
215
185
  }
216
186
  else {
217
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Parsed JSON is not an array:`, typeof parsed);
218
187
  throw new Error("daysOfWeek must be an array or a JSON string representing an array");
219
188
  }
220
189
  }
221
190
  catch (parseError) {
222
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Failed to parse daysOfWeek as JSON:`, parseError);
223
191
  throw new Error(`daysOfWeek must be a valid JSON array string. Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
224
192
  }
225
193
  }
226
194
  // 情况3: 其他类型,报错
227
195
  else {
228
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid daysOfWeek type:`, typeof params.daysOfWeek);
229
196
  throw new Error(`daysOfWeek must be an array or a JSON string, got ${typeof params.daysOfWeek}`);
230
197
  }
231
198
  // 验证数组非空
232
199
  if (!normalizedDaysOfWeek || normalizedDaysOfWeek.length === 0) {
233
- logger.error(`[MODIFY_ALARM_TOOL] ❌ daysOfWeek array is empty`);
234
200
  throw new Error("daysOfWeek array cannot be empty");
235
201
  }
236
202
  // 验证数组长度必须为1
237
203
  if (normalizedDaysOfWeek.length !== 1) {
238
- logger.error(`[MODIFY_ALARM_TOOL] ❌ daysOfWeek array length must be 1, got ${normalizedDaysOfWeek.length}`);
239
204
  throw new Error("daysOfWeek 仅支持长度为1的数组。如果需要一周中不同的几天,需要多次调用此工具");
240
205
  }
241
206
  // Validate each day
242
207
  for (const day of normalizedDaysOfWeek) {
243
208
  if (typeof day !== "string" || !DAYS_OF_WEEK_VALUES.includes(day)) {
244
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid day value: ${day}`);
245
209
  throw new Error(`daysOfWeek must contain only: ${DAYS_OF_WEEK_VALUES.join(", ")}`);
246
210
  }
247
211
  }
248
212
  intentParam.daysOfWeek = normalizedDaysOfWeek;
249
- logger.log(`[MODIFY_ALARM_TOOL] - daysOfWeek: ${normalizedDaysOfWeek.join(", ")}`);
250
213
  }
251
214
  }
252
215
  // Get session context
253
- logger.log(`[MODIFY_ALARM_TOOL] 🔍 Attempting to get session context...`);
254
216
  const sessionContext = getCurrentSessionContext();
255
217
  if (!sessionContext) {
256
- logger.error(`[MODIFY_ALARM_TOOL] ❌ FAILED: No active session found!`);
257
- logger.error(`[MODIFY_ALARM_TOOL] - toolCallId: ${toolCallId}`);
258
218
  throw new Error("No active XY session found. Modify alarm tool can only be used during an active conversation.");
259
219
  }
260
- logger.log(`[MODIFY_ALARM_TOOL] ✅ Session context found`);
261
- logger.log(`[MODIFY_ALARM_TOOL] - sessionId: ${sessionContext.sessionId}`);
262
- logger.log(`[MODIFY_ALARM_TOOL] - taskId: ${sessionContext.taskId}`);
263
- logger.log(`[MODIFY_ALARM_TOOL] - messageId: ${sessionContext.messageId}`);
264
220
  const { config, sessionId, taskId, messageId } = sessionContext;
265
221
  // Get WebSocket manager
266
- logger.log(`[MODIFY_ALARM_TOOL] 🔌 Getting WebSocket manager...`);
267
222
  const wsManager = getXYWebSocketManager(config);
268
- logger.log(`[MODIFY_ALARM_TOOL] ✅ WebSocket manager obtained`);
269
223
  // Build ModifyAlarm command
270
- logger.log(`[MODIFY_ALARM_TOOL] 📦 Building ModifyAlarm command...`);
271
224
  const command = {
272
225
  header: {
273
226
  namespace: "Common",
@@ -300,25 +253,17 @@ export const modifyAlarmTool = {
300
253
  },
301
254
  };
302
255
  // Send command and wait for response (60 second timeout)
303
- logger.log(`[MODIFY_ALARM_TOOL] ⏳ Setting up promise to wait for alarm modification response...`);
304
- logger.log(`[MODIFY_ALARM_TOOL] - Timeout: 60 seconds`);
305
256
  return new Promise((resolve, reject) => {
306
257
  const timeout = setTimeout(() => {
307
- logger.error(`[MODIFY_ALARM_TOOL] ⏰ Timeout: No response received within 60 seconds`);
308
258
  wsManager.off("data-event", handler);
309
259
  reject(new Error("修改闹钟超时(60秒)"));
310
260
  }, 60000);
311
261
  // Listen for data events from WebSocket
312
262
  const handler = (event) => {
313
- logger.log(`[MODIFY_ALARM_TOOL] 📨 Received data event:`, JSON.stringify(event));
314
263
  if (event.intentName === "ModifyAlarm") {
315
- logger.log(`[MODIFY_ALARM_TOOL] 🎯 ModifyAlarm event received`);
316
- logger.log(`[MODIFY_ALARM_TOOL] - status: ${event.status}`);
317
264
  clearTimeout(timeout);
318
265
  wsManager.off("data-event", handler);
319
266
  if (event.status === "success" && event.outputs) {
320
- logger.log(`[MODIFY_ALARM_TOOL] ✅ Alarm modification completed successfully`);
321
- logger.log(`[MODIFY_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs));
322
267
  // 成功,直接返回完整的 event.outputs JSON 字符串
323
268
  resolve({
324
269
  content: [
@@ -330,18 +275,13 @@ export const modifyAlarmTool = {
330
275
  });
331
276
  }
332
277
  else {
333
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Alarm modification failed`);
334
- logger.error(`[MODIFY_ALARM_TOOL] - status: ${event.status}`);
335
- logger.error(`[MODIFY_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs || {}));
336
278
  reject(new Error(`修改闹钟失败: ${event.status}`));
337
279
  }
338
280
  }
339
281
  };
340
282
  // Register event handler
341
- logger.log(`[MODIFY_ALARM_TOOL] 📡 Registering data-event handler on WebSocket manager`);
342
283
  wsManager.on("data-event", handler);
343
284
  // Send the command
344
- logger.log(`[MODIFY_ALARM_TOOL] 📤 Sending ModifyAlarm command...`);
345
285
  sendCommand({
346
286
  config,
347
287
  sessionId,
@@ -350,10 +290,8 @@ export const modifyAlarmTool = {
350
290
  command,
351
291
  })
352
292
  .then(() => {
353
- logger.log(`[MODIFY_ALARM_TOOL] ✅ Command sent successfully, waiting for response...`);
354
293
  })
355
294
  .catch((error) => {
356
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Failed to send command:`, error);
357
295
  clearTimeout(timeout);
358
296
  wsManager.off("data-event", handler);
359
297
  reject(error);
@@ -375,17 +313,14 @@ function parseAlarmTimeToTimestamp(alarmTime) {
375
313
  const trimmed = alarmTime.trim();
376
314
  // Check basic format (should have at least 13 characters: YYYYMMDD hhmmss)
377
315
  if (trimmed.length < 13) {
378
- logger.error(`[MODIFY_ALARM_TOOL] ❌ alarmTime too short: ${trimmed}`);
379
316
  return null;
380
317
  }
381
318
  // Extract date and time parts
382
319
  // Format: YYYYMMDD hhmmss
383
320
  const datePart = trimmed.substring(0, 8); // YYYYMMDD
384
321
  const timePart = trimmed.substring(8).trim(); // hhmmss (may have leading space)
385
- logger.log(`[MODIFY_ALARM_TOOL] - datePart: ${datePart}, timePart: ${timePart}`);
386
322
  // Validate lengths
387
323
  if (datePart.length !== 8 || timePart.length !== 6) {
388
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid part lengths: datePart=${datePart.length}, timePart=${timePart.length}`);
389
324
  return null;
390
325
  }
391
326
  // Parse components
@@ -395,45 +330,36 @@ function parseAlarmTimeToTimestamp(alarmTime) {
395
330
  const hour = parseInt(timePart.substring(0, 2), 10);
396
331
  const minute = parseInt(timePart.substring(2, 4), 10);
397
332
  const second = parseInt(timePart.substring(4, 6), 10);
398
- logger.log(`[MODIFY_ALARM_TOOL] - Parsed: ${year}-${month}-${day} ${hour}:${minute}:${second}`);
399
333
  // Validate values
400
334
  if (isNaN(year) || isNaN(month) || isNaN(day) ||
401
335
  isNaN(hour) || isNaN(minute) || isNaN(second)) {
402
- logger.error(`[MODIFY_ALARM_TOOL] ❌ NaN detected in parsed values`);
403
336
  return null;
404
337
  }
405
338
  // Validate ranges
406
339
  if (month < 1 || month > 12) {
407
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid month: ${month}`);
408
340
  return null;
409
341
  }
410
342
  if (day < 1 || day > 31) {
411
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid day: ${day}`);
412
343
  return null;
413
344
  }
414
345
  if (hour < 0 || hour > 23) {
415
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid hour: ${hour}`);
416
346
  return null;
417
347
  }
418
348
  if (minute < 0 || minute > 59) {
419
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid minute: ${minute}`);
420
349
  return null;
421
350
  }
422
351
  if (second < 0 || second > 59) {
423
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Invalid second: ${second}`);
424
352
  return null;
425
353
  }
426
354
  // Create Date object and get timestamp
427
355
  const date = new Date(year, month - 1, day, hour, minute, second);
428
356
  const timestamp = date.getTime();
429
357
  if (isNaN(timestamp)) {
430
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Generated timestamp is NaN`);
431
358
  return null;
432
359
  }
433
360
  return timestamp;
434
361
  }
435
362
  catch (error) {
436
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Exception in parseAlarmTimeToTimestamp:`, error);
437
363
  return null;
438
364
  }
439
365
  }
@@ -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 modify note tool - appends content to an existing note on user's device.
7
6
  * Requires entityId from search_notes tool as prerequisite.
@@ -13,7 +12,7 @@ import { logger } from "../utils/logger.js";
13
12
  export const modifyNoteTool = {
14
13
  name: "modify_note",
15
14
  label: "Modify Note",
16
- description: "在指定备忘录中追加新内容。使用前必须先调用 search_notes 工具获取备忘录的 entityId。参数说明:entityId 是备忘录的唯一标识符(从 search_notes 工具获取),text 是要追加的文本内容。注意:操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。",
15
+ description: "在指定备忘录中追加新内容。使用前必须先调用 search_notes 工具获取备忘录的 entityId。参数说明:entityId 是备忘录的唯一标识符(从 search_notes 工具获取),text 是要追加的文本内容。注意:操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。",
17
16
  parameters: {
18
17
  type: "object",
19
18
  properties: {
@@ -29,34 +28,19 @@ export const modifyNoteTool = {
29
28
  required: ["entityId", "text"],
30
29
  },
31
30
  async execute(toolCallId, params) {
32
- logger.log(`[MODIFY_NOTE_TOOL] 🚀 Starting execution`);
33
- logger.log(`[MODIFY_NOTE_TOOL] - toolCallId: ${toolCallId}`);
34
- logger.log(`[MODIFY_NOTE_TOOL] - params:`, JSON.stringify(params));
35
- logger.log(`[MODIFY_NOTE_TOOL] - timestamp: ${new Date().toISOString()}`);
36
31
  // Validate parameters
37
32
  if (!params.entityId || !params.text) {
38
- logger.error(`[MODIFY_NOTE_TOOL] ❌ Missing required parameters`);
39
33
  throw new Error("Missing required parameters: entityId and text are required");
40
34
  }
41
35
  // Get session context
42
- logger.log(`[MODIFY_NOTE_TOOL] 🔍 Attempting to get session context...`);
43
36
  const sessionContext = getCurrentSessionContext();
44
37
  if (!sessionContext) {
45
- logger.error(`[MODIFY_NOTE_TOOL] ❌ FAILED: No active session found!`);
46
- logger.error(`[MODIFY_NOTE_TOOL] - toolCallId: ${toolCallId}`);
47
38
  throw new Error("No active XY session found. Modify note tool can only be used during an active conversation.");
48
39
  }
49
- logger.log(`[MODIFY_NOTE_TOOL] ✅ Session context found`);
50
- logger.log(`[MODIFY_NOTE_TOOL] - sessionId: ${sessionContext.sessionId}`);
51
- logger.log(`[MODIFY_NOTE_TOOL] - taskId: ${sessionContext.taskId}`);
52
- logger.log(`[MODIFY_NOTE_TOOL] - messageId: ${sessionContext.messageId}`);
53
40
  const { config, sessionId, taskId, messageId } = sessionContext;
54
41
  // Get WebSocket manager
55
- logger.log(`[MODIFY_NOTE_TOOL] 🔌 Getting WebSocket manager...`);
56
42
  const wsManager = getXYWebSocketManager(config);
57
- logger.log(`[MODIFY_NOTE_TOOL] ✅ WebSocket manager obtained`);
58
43
  // Build ModifyNote command
59
- logger.log(`[MODIFY_NOTE_TOOL] 📦 Building ModifyNote command...`);
60
44
  const command = {
61
45
  header: {
62
46
  namespace: "Common",
@@ -92,29 +76,18 @@ export const modifyNoteTool = {
92
76
  pageControlRelated: false,
93
77
  },
94
78
  };
95
- logger.log(`[MODIFY_NOTE_TOOL] - entityId: ${params.entityId}`);
96
- logger.log(`[MODIFY_NOTE_TOOL] - contentType: 1 (append mode)`);
97
- logger.log(`[MODIFY_NOTE_TOOL] - text length: ${params.text.length} characters`);
98
79
  // Send command and wait for response (60 second timeout)
99
- logger.log(`[MODIFY_NOTE_TOOL] ⏳ Setting up promise to wait for note modification response...`);
100
- logger.log(`[MODIFY_NOTE_TOOL] - Timeout: 60 seconds`);
101
80
  return new Promise((resolve, reject) => {
102
81
  const timeout = setTimeout(() => {
103
- logger.error(`[MODIFY_NOTE_TOOL] ⏰ Timeout: No response received within 60 seconds`);
104
82
  wsManager.off("data-event", handler);
105
83
  reject(new Error("修改备忘录超时(60秒)"));
106
84
  }, 60000);
107
85
  // Listen for data events from WebSocket
108
86
  const handler = (event) => {
109
- logger.log(`[MODIFY_NOTE_TOOL] 📨 Received data event:`, JSON.stringify(event));
110
87
  if (event.intentName === "ModifyNote") {
111
- logger.log(`[MODIFY_NOTE_TOOL] 🎯 ModifyNote event received`);
112
- logger.log(`[MODIFY_NOTE_TOOL] - status: ${event.status}`);
113
88
  clearTimeout(timeout);
114
89
  wsManager.off("data-event", handler);
115
90
  if (event.status === "success" && event.outputs) {
116
- logger.log(`[MODIFY_NOTE_TOOL] ✅ Note modified successfully`);
117
- logger.log(`[MODIFY_NOTE_TOOL] - outputs:`, JSON.stringify(event.outputs));
118
91
  // 成功,直接返回完整的 event.outputs JSON 字符串
119
92
  resolve({
120
93
  content: [
@@ -126,17 +99,13 @@ export const modifyNoteTool = {
126
99
  });
127
100
  }
128
101
  else {
129
- logger.error(`[MODIFY_NOTE_TOOL] ❌ Note modification failed`);
130
- logger.error(`[MODIFY_NOTE_TOOL] - status: ${event.status}`);
131
102
  reject(new Error(`修改备忘录失败: ${event.status}`));
132
103
  }
133
104
  }
134
105
  };
135
106
  // Register event handler
136
- logger.log(`[MODIFY_NOTE_TOOL] 📡 Registering data-event handler on WebSocket manager`);
137
107
  wsManager.on("data-event", handler);
138
108
  // Send the command
139
- logger.log(`[MODIFY_NOTE_TOOL] 📤 Sending ModifyNote command...`);
140
109
  sendCommand({
141
110
  config,
142
111
  sessionId,
@@ -145,10 +114,8 @@ export const modifyNoteTool = {
145
114
  command,
146
115
  })
147
116
  .then(() => {
148
- logger.log(`[MODIFY_NOTE_TOOL] ✅ Command sent successfully, waiting for response...`);
149
117
  })
150
118
  .catch((error) => {
151
- logger.error(`[MODIFY_NOTE_TOOL] ❌ Failed to send command:`, error);
152
119
  clearTimeout(timeout);
153
120
  wsManager.off("data-event", handler);
154
121
  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
  * Duck-typed ToolInputError: openclaw 按 .name 字段匹配,不用 instanceof。
7
6
  * 抛出此错误会让 openclaw 返回 HTTP 400 而非 500,
@@ -26,6 +25,8 @@ export const noteTool = {
26
25
  a. 操作超时时间为60秒,请勿重复调用此工具
27
26
  b. 如果遇到各类调用失败场景,最多只能重试一次,不可以重复调用多次。
28
27
  c. 调用工具前需认真检查调用参数是否满足工具要求
28
+
29
+ 回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,例如告诉用户如何授权,如何解决报错等都是不需要的,请严格遵守。
29
30
  `,
30
31
  parameters: {
31
32
  type: "object",
@@ -42,7 +43,6 @@ export const noteTool = {
42
43
  required: ["title", "content"],
43
44
  },
44
45
  async execute(toolCallId, params) {
45
- logger.debug("Executing note tool, toolCallId:", toolCallId);
46
46
  // Validate parameters — 抛 ToolInputError 而非普通 Error,
47
47
  // 让 openclaw 返回 400 而非 500,明确告知 LLM 这是参数错误,不应重试。
48
48
  if (typeof params.title !== "string" || !params.title) {
@@ -101,12 +101,10 @@ export const noteTool = {
101
101
  }, 60000);
102
102
  // Listen for data events from WebSocket
103
103
  const handler = (event) => {
104
- logger.debug("Received data event:", event);
105
104
  if (event.intentName === "CreateNote") {
106
105
  clearTimeout(timeout);
107
106
  wsManager.off("data-event", handler);
108
107
  if (event.status === "success" && event.outputs) {
109
- logger.log(`Note created successfully, outputs:`, JSON.stringify(event.outputs));
110
108
  // 成功,直接返回完整的 event.outputs JSON 字符串
111
109
  resolve({
112
110
  content: [