@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.
- package/dist/src/channel.js +2 -2
- package/dist/src/tools/create-alarm-tool.js +0 -10
- package/dist/src/tools/delete-alarm-tool.js +0 -11
- package/dist/src/tools/image-reading-tool.js +23 -1
- package/dist/src/tools/modify-alarm-tool.js +0 -10
- package/dist/src/tools/search-alarm-tool.js +9 -57
- package/dist/src/tools/search-calendar-tool.js +3 -43
- package/dist/src/tools/search-contact-tool.js +2 -25
- package/dist/src/tools/search-file-tool.js +5 -29
- package/dist/src/tools/search-message-tool.js +3 -27
- package/dist/src/tools/search-note-tool.js +27 -20
- package/dist/src/tools/search-photo-gallery-tool.js +8 -28
- package/dist/src/tools/send-message-tool.js +6 -19
- package/package.json +1 -1
package/dist/src/channel.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
|
180
|
+
logger.log(`[SEARCH_CALENDAR_TOOL] ✅ Calendar events retrieved successfully`);
|
|
192
181
|
logger.log(`[SEARCH_CALENDAR_TOOL] - outputs:`, JSON.stringify(event.outputs));
|
|
193
|
-
//
|
|
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:
|
|
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
|
-
//
|
|
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(
|
|
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
|
|
117
|
+
logger.log(`[SEARCH_FILE_TOOL] ✅ File search completed successfully`);
|
|
118
118
|
logger.log(`[SEARCH_FILE_TOOL] - outputs:`, JSON.stringify(event.outputs));
|
|
119
|
-
//
|
|
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(
|
|
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
|
|
105
|
+
logger.log(`[SEARCH_MESSAGE_TOOL] ✅ Message search completed successfully`);
|
|
106
106
|
logger.log(`[SEARCH_MESSAGE_TOOL] - outputs:`, JSON.stringify(event.outputs));
|
|
107
|
-
//
|
|
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(
|
|
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.
|
|
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.
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
|
95
|
-
|
|
96
|
-
|
|
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
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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] ✅
|
|
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] -
|
|
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(
|
|
153
|
-
}
|
|
154
|
-
]
|
|
139
|
+
text: JSON.stringify(event.outputs),
|
|
140
|
+
}
|
|
141
|
+
]
|
|
155
142
|
});
|
|
156
143
|
}
|
|
157
144
|
else {
|