@ynhcj/xiaoyi-channel 0.0.47-beta → 0.0.49-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.
@@ -22,7 +22,7 @@ import { searchAlarmTool } from "./tools/search-alarm-tool.js";
22
22
  import { modifyAlarmTool } from "./tools/modify-alarm-tool.js";
23
23
  import { deleteAlarmTool } from "./tools/delete-alarm-tool.js";
24
24
  import { sendFileToUserTool } from "./tools/send-file-to-user-tool.js";
25
- // import { xiaoyiCollectionTool } from "./tools/xiaoyi-collection-tool.js"; // 暂时取消注册
25
+ import { xiaoyiCollectionTool } from "./tools/xiaoyi-collection-tool.js";
26
26
  import { viewPushResultTool } from "./tools/view-push-result-tool.js";
27
27
  import { imageReadingTool } from "./tools/image-reading-tool.js";
28
28
  /**
@@ -64,7 +64,7 @@ export const xyPlugin = {
64
64
  },
65
65
  outbound: xyOutbound,
66
66
  onboarding: xyOnboardingAdapter,
67
- agentTools: [locationTool, noteTool, searchNoteTool, modifyNoteTool, calendarTool, searchCalendarTool, searchContactTool, searchPhotoGalleryTool, uploadPhotoTool, xiaoyiGuiTool, callPhoneTool, searchMessageTool, sendMessageTool, searchFileTool, uploadFileTool, createAlarmTool, searchAlarmTool, modifyAlarmTool, deleteAlarmTool, sendFileToUserTool, viewPushResultTool, imageReadingTool],
67
+ agentTools: [locationTool, noteTool, searchNoteTool, modifyNoteTool, calendarTool, searchCalendarTool, searchContactTool, searchPhotoGalleryTool, uploadPhotoTool, xiaoyiGuiTool, xiaoyiCollectionTool, callPhoneTool, searchMessageTool, sendMessageTool, searchFileTool, uploadFileTool, createAlarmTool, searchAlarmTool, modifyAlarmTool, deleteAlarmTool, sendFileToUserTool, viewPushResultTool, imageReadingTool],
68
68
  messaging: {
69
69
  normalizeTarget: (raw) => {
70
70
  const trimmed = raw.trim();
@@ -302,16 +302,6 @@ b. 使用该工具之前需获取当前真实时间`,
302
302
  if (event.status === "success" && event.outputs) {
303
303
  logger.log(`[CREATE_ALARM_TOOL] ✅ Alarm creation completed successfully`);
304
304
  logger.log(`[CREATE_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs));
305
- // Check for error code in outputs
306
- const code = event.outputs.code !== undefined ? event.outputs.code : null;
307
- if (code !== null && code !== 0) {
308
- logger.error(`[CREATE_ALARM_TOOL] ❌ Device returned error`);
309
- logger.error(`[CREATE_ALARM_TOOL] - code: ${code}`);
310
- const errorMsg = event.outputs.errorMsg || event.outputs.errMsg || "未知错误";
311
- logger.error(`[CREATE_ALARM_TOOL] - errorMsg: ${errorMsg}`);
312
- reject(new Error(`创建闹钟失败: ${errorMsg} (错误代码: ${code})`));
313
- return;
314
- }
315
305
  // 成功,直接返回完整的 event.outputs JSON 字符串
316
306
  resolve({
317
307
  content: [
@@ -172,18 +172,7 @@ export const deleteAlarmTool = {
172
172
  if (event.status === "success" && event.outputs) {
173
173
  logger.log(`[DELETE_ALARM_TOOL] ✅ Alarm deletion completed successfully`);
174
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
175
  // 成功,直接返回完整的 event.outputs JSON 字符串
186
- logger.log(`[DELETE_ALARM_TOOL] 🎉 Successfully deleted ${items.length} alarm(s)`);
187
176
  resolve({
188
177
  content: [
189
178
  {
@@ -75,6 +75,10 @@ async function processImageInput(imageInput, uploadService) {
75
75
  const localPath = await downloadRemoteFile(imageInput);
76
76
  logger.log(`[IMAGE_READING_TOOL] 📤 Uploading downloaded file to OBS...`);
77
77
  const imageUrl = await uploadService.uploadFileAndGetUrl(localPath, "TEMPORARY_MATERIAL_DOC");
78
+ if (!imageUrl) {
79
+ logger.error(`[IMAGE_READING_TOOL] ❌ Failed to get URL after upload`);
80
+ throw new Error("图片上传失败:无法获取图片访问地址");
81
+ }
78
82
  logger.log(`[IMAGE_READING_TOOL] ✅ Uploaded to OBS: ${imageUrl}`);
79
83
  return { imageUrl, localPath };
80
84
  }
@@ -83,6 +87,10 @@ async function processImageInput(imageInput, uploadService) {
83
87
  if (isLocal) {
84
88
  logger.log(`[IMAGE_READING_TOOL] 📁 Input is local file, uploading...`);
85
89
  const imageUrl = await uploadService.uploadFileAndGetUrl(imageInput, "TEMPORARY_MATERIAL_DOC");
90
+ if (!imageUrl) {
91
+ logger.error(`[IMAGE_READING_TOOL] ❌ Failed to get URL after upload`);
92
+ throw new Error("图片上传失败:无法获取图片访问地址");
93
+ }
86
94
  logger.log(`[IMAGE_READING_TOOL] ✅ Uploaded to OBS: ${imageUrl}`);
87
95
  return { imageUrl };
88
96
  }
@@ -347,7 +355,21 @@ d. 返回图像理解的文本描述内容`,
347
355
  }
348
356
  }
349
357
  logger.error(`[IMAGE_READING_TOOL] ❌ Execution failed:`, error);
350
- throw error;
358
+ const errorMessage = error instanceof Error ? error.message : "图片分析失败";
359
+ // Return error result instead of throwing
360
+ return {
361
+ content: [
362
+ {
363
+ type: "text",
364
+ text: JSON.stringify({
365
+ error: errorMessage,
366
+ prompt,
367
+ imageSource: params.localUrl ? "local" : "remote",
368
+ success: false,
369
+ }),
370
+ },
371
+ ],
372
+ };
351
373
  }
352
374
  },
353
375
  };
@@ -319,16 +319,6 @@ export const modifyAlarmTool = {
319
319
  if (event.status === "success" && event.outputs) {
320
320
  logger.log(`[MODIFY_ALARM_TOOL] ✅ Alarm modification completed successfully`);
321
321
  logger.log(`[MODIFY_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs));
322
- // Check for error code in outputs
323
- const code = event.outputs.code !== undefined ? event.outputs.code : null;
324
- if (code !== null && code !== 0) {
325
- logger.error(`[MODIFY_ALARM_TOOL] ❌ Device returned error`);
326
- logger.error(`[MODIFY_ALARM_TOOL] - code: ${code}`);
327
- const errorMsg = event.outputs.errorMsg || event.outputs.errMsg || "未知错误";
328
- logger.error(`[MODIFY_ALARM_TOOL] - errorMsg: ${errorMsg}`);
329
- reject(new Error(`修改闹钟失败: ${errorMsg} (错误代码: ${code})`));
330
- return;
331
- }
332
322
  // 成功,直接返回完整的 event.outputs JSON 字符串
333
323
  resolve({
334
324
  content: [
@@ -225,63 +225,15 @@ b. 使用该工具之前需获取当前真实时间`,
225
225
  if (event.status === "success" && event.outputs) {
226
226
  logger.log(`[SEARCH_ALARM_TOOL] ✅ Alarm search completed successfully`);
227
227
  logger.log(`[SEARCH_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs));
228
- // Check for error code in outputs
229
- const code = event.outputs.code !== undefined ? event.outputs.code : null;
230
- if (code !== null && code !== 0) {
231
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Device returned error`);
232
- logger.error(`[SEARCH_ALARM_TOOL] - code: ${code}`);
233
- const errorMsg = event.outputs.errorMsg || event.outputs.errMsg || "未知错误";
234
- logger.error(`[SEARCH_ALARM_TOOL] - errorMsg: ${errorMsg}`);
235
- reject(new Error(`检索闹钟失败: ${errorMsg} (错误代码: ${code})`));
236
- return;
237
- }
238
- // Extract result.items with safe checks
239
- const result = event.outputs.result;
240
- let items = [];
241
- if (result && typeof result === "object" && Array.isArray(result.items)) {
242
- items = result.items;
243
- logger.log(`[SEARCH_ALARM_TOOL] 📋 Found ${items.length} alarm(s)`);
244
- // Parse JSON strings in items array
245
- // Items are returned as JSON strings that need to be parsed
246
- const parsedItems = items.map((itemStr, index) => {
247
- if (typeof itemStr !== "string") {
248
- logger.warn(`[SEARCH_ALARM_TOOL] ⚠️ Item at index ${index} is not a string:`, typeof itemStr);
249
- return null;
250
- }
251
- try {
252
- const parsed = JSON.parse(itemStr);
253
- logger.log(`[SEARCH_ALARM_TOOL] 📋 Parsed alarm [${index}]:`, JSON.stringify(parsed));
254
- return parsed;
255
- }
256
- catch (parseError) {
257
- logger.error(`[SEARCH_ALARM_TOOL] ❌ Failed to parse item at index ${index}:`, parseError);
258
- logger.error(`[SEARCH_ALARM_TOOL] - itemStr: ${itemStr}`);
259
- return null;
260
- }
261
- }).filter((item) => item !== null);
262
- logger.log(`[SEARCH_ALARM_TOOL] 🎉 Successfully parsed ${parsedItems.length} alarm(s)`);
263
- resolve({
264
- content: [
265
- {
266
- type: "text",
267
- text: JSON.stringify(parsedItems),
268
- },
269
- ],
270
- });
271
- }
272
- else {
273
- logger.warn(`[SEARCH_ALARM_TOOL] ⚠️ No items found in result or result is invalid`);
274
- logger.warn(`[SEARCH_ALARM_TOOL] - result:`, JSON.stringify(result || {}));
275
- // Return empty array
276
- resolve({
277
- content: [
278
- {
279
- type: "text",
280
- text: "[]",
281
- },
282
- ],
283
- });
284
- }
228
+ // 成功,直接返回完整的 event.outputs JSON 字符串
229
+ resolve({
230
+ content: [
231
+ {
232
+ type: "text",
233
+ text: JSON.stringify(event.outputs),
234
+ },
235
+ ],
236
+ });
285
237
  }
286
238
  else {
287
239
  logger.error(`[SEARCH_ALARM_TOOL] ❌ Alarm search failed`);
@@ -83,17 +83,6 @@ b. 使用该工具之前需获取当前真实时间
83
83
  const date = new Date(year, month, day, hours, minutes, seconds);
84
84
  return date.getTime();
85
85
  };
86
- // Helper function to convert timestamp to YYYYMMDD hhmmss format
87
- const formatTimestamp = (timestamp) => {
88
- const date = new Date(timestamp);
89
- const year = date.getFullYear();
90
- const month = String(date.getMonth() + 1).padStart(2, '0');
91
- const day = String(date.getDate()).padStart(2, '0');
92
- const hours = String(date.getHours()).padStart(2, '0');
93
- const minutes = String(date.getMinutes()).padStart(2, '0');
94
- const seconds = String(date.getSeconds()).padStart(2, '0');
95
- return `${year}${month}${day} ${hours}${minutes}${seconds}`;
96
- };
97
86
  let startTimeMs;
98
87
  let endTimeMs;
99
88
  try {
@@ -188,43 +177,14 @@ b. 使用该工具之前需获取当前真实时间
188
177
  clearTimeout(timeout);
189
178
  wsManager.off("data-event", handler);
190
179
  if (event.status === "success" && event.outputs) {
191
- logger.log(`[SEARCH_CALENDAR_TOOL] ✅ Calendar events response received`);
180
+ logger.log(`[SEARCH_CALENDAR_TOOL] ✅ Calendar events retrieved successfully`);
192
181
  logger.log(`[SEARCH_CALENDAR_TOOL] - outputs:`, JSON.stringify(event.outputs));
193
- // Check for error code in outputs
194
- if (event.outputs.retErrCode && event.outputs.retErrCode !== "0") {
195
- logger.error(`[SEARCH_CALENDAR_TOOL] ❌ Device returned error`);
196
- logger.error(`[SEARCH_CALENDAR_TOOL] - retErrCode: ${event.outputs.retErrCode}`);
197
- logger.error(`[SEARCH_CALENDAR_TOOL] - errMsg: ${event.outputs.errMsg || "Unknown error"}`);
198
- reject(new Error(`检索日程失败: ${event.outputs.errMsg || "未知错误"} (错误代码: ${event.outputs.retErrCode})`));
199
- return;
200
- }
201
- // Return the result directly as requested
202
- const result = event.outputs.result;
203
- // Ensure result is not undefined
204
- if (result === undefined) {
205
- logger.warn(`[SEARCH_CALENDAR_TOOL] ⚠️ Result is undefined, returning empty result`);
206
- }
207
- // Convert dtStart and dtEnd from timestamps to YYYYMMDD hhmmss format
208
- if (result && result.items && Array.isArray(result.items)) {
209
- logger.log(`[SEARCH_CALENDAR_TOOL] 🔄 Converting timestamps to formatted dates...`);
210
- result.items = result.items.map((item) => {
211
- const formattedItem = { ...item };
212
- if (item.dtStart) {
213
- formattedItem.dtStart = formatTimestamp(item.dtStart);
214
- logger.log(`[SEARCH_CALENDAR_TOOL] - dtStart: ${item.dtStart} -> ${formattedItem.dtStart}`);
215
- }
216
- if (item.dtEnd) {
217
- formattedItem.dtEnd = formatTimestamp(item.dtEnd);
218
- logger.log(`[SEARCH_CALENDAR_TOOL] - dtEnd: ${item.dtEnd} -> ${formattedItem.dtEnd}`);
219
- }
220
- return formattedItem;
221
- });
222
- }
182
+ // 成功,直接返回完整的 event.outputs JSON 字符串
223
183
  resolve({
224
184
  content: [
225
185
  {
226
186
  type: "text",
227
- text: result !== undefined ? JSON.stringify(result) : "[]",
187
+ text: JSON.stringify(event.outputs),
228
188
  },
229
189
  ],
230
190
  });
@@ -102,35 +102,12 @@ export const searchContactTool = {
102
102
  if (event.status === "success" && event.outputs) {
103
103
  logger.log(`[SEARCH_CONTACT_TOOL] ✅ Contact search completed successfully`);
104
104
  logger.log(`[SEARCH_CONTACT_TOOL] - outputs:`, JSON.stringify(event.outputs));
105
- // Check for error code first
106
- if (event.outputs.retErrCode && event.outputs.retErrCode !== "0") {
107
- logger.error(`[SEARCH_CONTACT_TOOL] ❌ Search failed with error code: ${event.outputs.retErrCode}`);
108
- logger.error(`[SEARCH_CONTACT_TOOL] - errMsg: ${event.outputs.errMsg}`);
109
- reject(new Error(`搜索联系人失败: ${event.outputs.errMsg || '未知错误'} (错误码: ${event.outputs.retErrCode})`));
110
- return;
111
- }
112
- // Get the result
113
- const result = event.outputs.result;
114
- // Check if result exists
115
- if (!result) {
116
- logger.warn(`[SEARCH_CONTACT_TOOL] ⚠️ No result found for name "${params.name}"`);
117
- resolve({
118
- content: [
119
- {
120
- type: "text",
121
- text: JSON.stringify({ items: [], message: "未找到匹配的联系人" }),
122
- },
123
- ],
124
- });
125
- return;
126
- }
127
- logger.log(`[SEARCH_CONTACT_TOOL] 📊 Contacts found: ${result?.items?.length || 0} results for name "${params.name}"`);
128
- // Return the result with valid string content
105
+ // 成功,直接返回完整的 event.outputs JSON 字符串
129
106
  resolve({
130
107
  content: [
131
108
  {
132
109
  type: "text",
133
- text: JSON.stringify(result),
110
+ text: JSON.stringify(event.outputs),
134
111
  },
135
112
  ],
136
113
  });
@@ -114,40 +114,16 @@ export const searchFileTool = {
114
114
  clearTimeout(timeout);
115
115
  wsManager.off("data-event", handler);
116
116
  if (event.status === "success" && event.outputs) {
117
- logger.log(`[SEARCH_FILE_TOOL] ✅ File search response received`);
117
+ logger.log(`[SEARCH_FILE_TOOL] ✅ File search completed successfully`);
118
118
  logger.log(`[SEARCH_FILE_TOOL] - outputs:`, JSON.stringify(event.outputs));
119
- // Check for error code in outputs
120
- const code = event.outputs.code !== undefined ? event.outputs.code : null;
121
- if (code !== null && code !== 0) {
122
- logger.error(`[SEARCH_FILE_TOOL] ❌ Device returned error`);
123
- logger.error(`[SEARCH_FILE_TOOL] - code: ${code}`);
124
- const errorMsg = event.outputs.errorMsg || event.outputs.errMsg || "未知错误";
125
- logger.error(`[SEARCH_FILE_TOOL] - errorMsg: ${errorMsg}`);
126
- reject(new Error(`搜索文件失败: ${errorMsg} (错误代码: ${code})`));
127
- return;
128
- }
129
- // Extract result.items with safe checks
130
- const result = event.outputs.result;
131
- let items = [];
132
- if (result && typeof result === "object" && Array.isArray(result.items)) {
133
- items = result.items;
134
- logger.log(`[SEARCH_FILE_TOOL] 📋 Found ${items.length} file(s)`);
135
- }
136
- else {
137
- logger.warn(`[SEARCH_FILE_TOOL] ⚠️ No items found in result or result is invalid`);
138
- logger.warn(`[SEARCH_FILE_TOOL] - result:`, JSON.stringify(result || {}));
139
- }
140
- // Return items array as JSON string
141
- logger.log(`[SEARCH_FILE_TOOL] 🎉 File search completed successfully`);
142
- logger.log(`[SEARCH_FILE_TOOL] - keyword: ${params.query}`);
143
- logger.log(`[SEARCH_FILE_TOOL] - result count: ${items.length}`);
119
+ // 成功,直接返回完整的 event.outputs JSON 字符串
144
120
  resolve({
145
121
  content: [
146
122
  {
147
123
  type: "text",
148
- text: JSON.stringify(items),
149
- },
150
- ],
124
+ text: JSON.stringify(event.outputs),
125
+ }
126
+ ]
151
127
  });
152
128
  }
153
129
  else {
@@ -102,38 +102,14 @@ export const searchMessageTool = {
102
102
  clearTimeout(timeout);
103
103
  wsManager.off("data-event", handler);
104
104
  if (event.status === "success" && event.outputs) {
105
- logger.log(`[SEARCH_MESSAGE_TOOL] ✅ Message search response received`);
105
+ logger.log(`[SEARCH_MESSAGE_TOOL] ✅ Message search completed successfully`);
106
106
  logger.log(`[SEARCH_MESSAGE_TOOL] - outputs:`, JSON.stringify(event.outputs));
107
- // Check for error code in outputs
108
- const code = event.outputs.code !== undefined ? event.outputs.code : null;
109
- if (code !== null && code !== 0) {
110
- logger.error(`[SEARCH_MESSAGE_TOOL] ❌ Device returned error`);
111
- logger.error(`[SEARCH_MESSAGE_TOOL] - code: ${code}`);
112
- const errorMsg = event.outputs.errorMsg || event.outputs.errMsg || "未知错误";
113
- logger.error(`[SEARCH_MESSAGE_TOOL] - errorMsg: ${errorMsg}`);
114
- reject(new Error(`搜索短信失败: ${errorMsg} (错误代码: ${code})`));
115
- return;
116
- }
117
- // Extract result.items with safe checks
118
- const result = event.outputs.result;
119
- let items = [];
120
- if (result && typeof result === "object" && Array.isArray(result.items)) {
121
- items = result.items;
122
- logger.log(`[SEARCH_MESSAGE_TOOL] 📋 Found ${items.length} message(s)`);
123
- }
124
- else {
125
- logger.warn(`[SEARCH_MESSAGE_TOOL] ⚠️ No items found in result or result is invalid`);
126
- logger.warn(`[SEARCH_MESSAGE_TOOL] - result:`, JSON.stringify(result || {}));
127
- }
128
- // Return items array as JSON string
129
- logger.log(`[SEARCH_MESSAGE_TOOL] 🎉 Message search completed successfully`);
130
- logger.log(`[SEARCH_MESSAGE_TOOL] - keyword: ${params.content}`);
131
- logger.log(`[SEARCH_MESSAGE_TOOL] - result count: ${items.length}`);
107
+ // 成功,直接返回完整的 event.outputs JSON 字符串
132
108
  resolve({
133
109
  content: [
134
110
  {
135
111
  type: "text",
136
- text: JSON.stringify(items),
112
+ text: JSON.stringify(event.outputs),
137
113
  },
138
114
  ],
139
115
  });
@@ -21,19 +21,28 @@ export const searchNoteTool = {
21
21
  required: ["query"],
22
22
  },
23
23
  async execute(toolCallId, params) {
24
- logger.debug("Executing search note tool, toolCallId:", toolCallId);
24
+ logger.log(`[SEARCH_NOTE_TOOL] 🚀 Starting execution`);
25
+ logger.log(`[SEARCH_NOTE_TOOL] - toolCallId: ${toolCallId}`);
26
+ logger.log(`[SEARCH_NOTE_TOOL] - params:`, JSON.stringify(params));
27
+ logger.log(`[SEARCH_NOTE_TOOL] - timestamp: ${new Date().toISOString()}`);
25
28
  // Validate parameters
26
29
  if (!params.query) {
30
+ logger.error(`[SEARCH_NOTE_TOOL] ❌ Missing required parameter: query`);
27
31
  throw new Error("Missing required parameter: query is required");
28
32
  }
29
33
  // Get session context
34
+ logger.log(`[SEARCH_NOTE_TOOL] 🔍 Attempting to get session context...`);
30
35
  const sessionContext = getCurrentSessionContext();
31
36
  if (!sessionContext) {
37
+ logger.error(`[SEARCH_NOTE_TOOL] ❌ FAILED: No active session found!`);
32
38
  throw new Error("No active XY session found. Search note tool can only be used during an active conversation.");
33
39
  }
40
+ logger.log(`[SEARCH_NOTE_TOOL] ✅ Session context found`);
34
41
  const { config, sessionId, taskId, messageId } = sessionContext;
35
42
  // Get WebSocket manager
43
+ logger.log(`[SEARCH_NOTE_TOOL] 🔌 Getting WebSocket manager...`);
36
44
  const wsManager = getXYWebSocketManager(config);
45
+ logger.log(`[SEARCH_NOTE_TOOL] ✅ WebSocket manager obtained`);
37
46
  // Build SearchNote command
38
47
  const command = {
39
48
  header: {
@@ -68,59 +77,57 @@ export const searchNoteTool = {
68
77
  },
69
78
  };
70
79
  // Send command and wait for response (60 second timeout)
80
+ logger.log(`[SEARCH_NOTE_TOOL] ⏳ Setting up promise to wait for note search response...`);
81
+ logger.log(`[SEARCH_NOTE_TOOL] - Timeout: 60 seconds`);
71
82
  return new Promise((resolve, reject) => {
72
83
  const timeout = setTimeout(() => {
84
+ logger.error(`[SEARCH_NOTE_TOOL] ⏰ Timeout: No response received within 60 seconds`);
73
85
  wsManager.off("data-event", handler);
74
86
  reject(new Error("搜索备忘录超时(60秒)"));
75
87
  }, 60000);
76
88
  // Listen for data events from WebSocket
77
89
  const handler = (event) => {
78
- logger.debug("Received data event:", event);
90
+ logger.log(`[SEARCH_NOTE_TOOL] 📨 Received data event:`, JSON.stringify(event));
79
91
  if (event.intentName === "SearchNote") {
92
+ logger.log(`[SEARCH_NOTE_TOOL] 🎯 SearchNote event received`);
93
+ logger.log(`[SEARCH_NOTE_TOOL] - status: ${event.status}`);
80
94
  clearTimeout(timeout);
81
95
  wsManager.off("data-event", handler);
82
96
  if (event.status === "success" && event.outputs) {
83
- const { result, code } = event.outputs;
84
- const items = result?.items || [];
85
- logger.log(`Notes found: ${items.length} results for query "${params.query}"`);
97
+ logger.log(`[SEARCH_NOTE_TOOL] Note search completed successfully`);
98
+ logger.log(`[SEARCH_NOTE_TOOL] - outputs:`, JSON.stringify(event.outputs));
99
+ // 成功,直接返回完整的 event.outputs JSON 字符串
86
100
  resolve({
87
101
  content: [
88
102
  {
89
103
  type: "text",
90
- text: JSON.stringify({
91
- success: true,
92
- query: params.query,
93
- totalResults: items.length,
94
- notes: items.map((item) => ({
95
- entityId: item.entityId,
96
- entityName: item.entityName,
97
- title: item.title?.replace(/<\/?em>/g, ''), // Remove <em> tags
98
- content: item.content,
99
- createdDate: item.createdDate,
100
- modifiedDate: item.modifiedDate,
101
- })),
102
- indexName: result?.indexName,
103
- code,
104
- }),
104
+ text: JSON.stringify(event.outputs),
105
105
  },
106
106
  ],
107
107
  });
108
108
  }
109
109
  else {
110
+ logger.error(`[SEARCH_NOTE_TOOL] ❌ Note search failed`);
111
+ logger.error(`[SEARCH_NOTE_TOOL] - status: ${event.status}`);
110
112
  reject(new Error(`搜索备忘录失败: ${event.status}`));
111
113
  }
112
114
  }
113
115
  };
114
116
  // Register event handler
117
+ logger.log(`[SEARCH_NOTE_TOOL] 📡 Registering data-event handler on WebSocket manager`);
115
118
  wsManager.on("data-event", handler);
116
119
  // Send the command
120
+ logger.log(`[SEARCH_NOTE_TOOL] 📤 Sending SearchNote command...`);
117
121
  sendCommand({
118
122
  config,
119
123
  sessionId,
120
124
  taskId,
121
125
  messageId,
122
126
  command,
127
+ }).then(() => {
128
+ logger.log(`[SEARCH_NOTE_TOOL] ✅ Command sent successfully, waiting for response...`);
123
129
  }).catch((error) => {
130
+ logger.error(`[SEARCH_NOTE_TOOL] ❌ Failed to send command:`, error);
124
131
  clearTimeout(timeout);
125
132
  wsManager.off("data-event", handler);
126
133
  reject(error);
@@ -91,33 +91,14 @@ export const searchPhotoGalleryTool = {
91
91
  logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] ✅ WebSocket manager obtained`);
92
92
  // Search for photos
93
93
  logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] 📸 Searching for photos...`);
94
- const items = await searchPhotos(wsManager, config, sessionId, taskId, messageId, params.query);
95
- if (!items || items.length === 0) {
96
- logger.warn(`[SEARCH_PHOTO_GALLERY_TOOL] ⚠️ No photos found for query: ${params.query}`);
97
- return {
98
- content: [
99
- {
100
- type: "text",
101
- text: JSON.stringify({
102
- items: [],
103
- count: 0,
104
- message: "未找到匹配的照片"
105
- }),
106
- },
107
- ],
108
- };
109
- }
110
- logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] ✅ Found ${items.length} photos`);
111
- logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] - items:`, JSON.stringify(items));
94
+ const outputs = await searchPhotos(wsManager, config, sessionId, taskId, messageId, params.query);
95
+ logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] Photo search completed successfully`);
96
+ logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] - outputs:`, JSON.stringify(outputs));
112
97
  return {
113
98
  content: [
114
99
  {
115
100
  type: "text",
116
- text: JSON.stringify({
117
- items,
118
- count: items.length,
119
- message: `找到 ${items.length} 张照片。注意:mediaUri 和 thumbnailUri 是本地路径,无法直接访问。如需下载或查看,请使用 upload_photo 工具。`
120
- }),
101
+ text: JSON.stringify(outputs),
121
102
  },
122
103
  ],
123
104
  };
@@ -125,7 +106,7 @@ export const searchPhotoGalleryTool = {
125
106
  };
126
107
  /**
127
108
  * Search for photos using query description
128
- * Returns array of photo items with complete information
109
+ * Returns complete event.outputs object
129
110
  */
130
111
  async function searchPhotos(wsManager, config, sessionId, taskId, messageId, query) {
131
112
  logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] 📦 Building SearchPhotoVideo command...`);
@@ -177,10 +158,9 @@ async function searchPhotos(wsManager, config, sessionId, taskId, messageId, que
177
158
  wsManager.off("data-event", handler);
178
159
  if (event.status === "success" && event.outputs) {
179
160
  logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] ✅ Photo search completed successfully`);
180
- const result = event.outputs.result;
181
- const items = result?.items || [];
182
- logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] 📊 Found ${items.length} photo items`);
183
- resolve(items);
161
+ logger.log(`[SEARCH_PHOTO_GALLERY_TOOL] - outputs:`, JSON.stringify(event.outputs));
162
+ // 成功,直接返回完整的 event.outputs
163
+ resolve(event.outputs);
184
164
  }
185
165
  else {
186
166
  logger.error(`[SEARCH_PHOTO_GALLERY_TOOL] ❌ Photo search failed`);
@@ -128,30 +128,17 @@ export const sendMessageTool = {
128
128
  clearTimeout(timeout);
129
129
  wsManager.off("data-event", handler);
130
130
  if (event.status === "success" && event.outputs) {
131
- logger.log(`[SEND_MESSAGE_TOOL] ✅ Send message response received`);
132
- logger.log(`[SEND_MESSAGE_TOOL] - outputs:`, JSON.stringify(event.outputs));
133
- // Check for error code in outputs
134
- const code = event.outputs.code !== undefined ? event.outputs.code : null;
135
- if (code !== null && code !== 0) {
136
- logger.error(`[SEND_MESSAGE_TOOL] ❌ Device returned error`);
137
- logger.error(`[SEND_MESSAGE_TOOL] - code: ${code}`);
138
- const errorMsg = event.outputs.errorMsg || event.outputs.errMsg || "未知错误";
139
- logger.error(`[SEND_MESSAGE_TOOL] - errorMsg: ${errorMsg}`);
140
- reject(new Error(`发送短信失败: ${errorMsg} (错误代码: ${code})`));
141
- return;
142
- }
143
- // Extract result with safe checks
144
- const result = event.outputs.result || {};
145
- logger.log(`[SEND_MESSAGE_TOOL] 🎉 Message sent successfully`);
131
+ logger.log(`[SEND_MESSAGE_TOOL] ✅ Message sent successfully`);
146
132
  logger.log(`[SEND_MESSAGE_TOOL] - phoneNumber: ${phoneNumber}`);
147
- logger.log(`[SEND_MESSAGE_TOOL] - result:`, JSON.stringify(result));
133
+ logger.log(`[SEND_MESSAGE_TOOL] - outputs:`, JSON.stringify(event.outputs));
134
+ // 成功,直接返回完整的 event.outputs JSON 字符串
148
135
  resolve({
149
136
  content: [
150
137
  {
151
138
  type: "text",
152
- text: JSON.stringify(result),
153
- },
154
- ],
139
+ text: JSON.stringify(event.outputs),
140
+ }
141
+ ]
155
142
  });
156
143
  }
157
144
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi-channel",
3
- "version": "0.0.47-beta",
3
+ "version": "0.0.49-beta",
4
4
  "description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",