@ynhcj/xiaoyi-channel 0.0.149-beta → 0.0.151-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/index.js +3 -69
- package/dist/src/approval-bridge.d.ts +48 -0
- package/dist/src/approval-bridge.js +382 -0
- package/dist/src/bot.js +64 -68
- package/dist/src/client.js +13 -23
- package/dist/src/cspl/call_api.d.ts +2 -0
- package/dist/src/cspl/call_api.js +107 -0
- package/dist/src/cspl/config.d.ts +4 -17
- package/dist/src/cspl/config.js +80 -70
- package/dist/src/cspl/configs.json +10 -0
- package/dist/src/cspl/constants.d.ts +46 -24
- package/dist/src/cspl/constants.js +41 -16
- package/dist/src/cspl/sentinel_hook.d.ts +2 -0
- package/dist/src/cspl/sentinel_hook.js +84 -0
- package/dist/src/cspl/steer-context.js +1 -1
- package/dist/src/cspl/upload_file.d.ts +1 -0
- package/dist/src/cspl/upload_file.js +211 -0
- package/dist/src/cspl/utils.d.ts +11 -2
- package/dist/src/cspl/utils.js +265 -15
- package/dist/src/formatter.js +92 -37
- package/dist/src/monitor.js +18 -21
- package/dist/src/outbound.js +8 -9
- package/dist/src/push.js +8 -15
- package/dist/src/reply-dispatcher.js +39 -48
- package/dist/src/self-evolution-handler.js +1 -1
- package/dist/src/sensitive-redactor.d.ts +4 -0
- package/dist/src/sensitive-redactor.js +364 -0
- package/dist/src/task-manager.js +6 -10
- package/dist/src/tools/agent-as-skill-tool.d.ts +7 -0
- package/dist/src/tools/agent-as-skill-tool.js +138 -0
- package/dist/src/tools/calendar-tool.js +1 -1
- package/dist/src/tools/call-device-tool.js +3 -0
- package/dist/src/tools/call-phone-tool.js +1 -1
- package/dist/src/tools/create-alarm-tool.js +1 -1
- package/dist/src/tools/create-all-tools.js +5 -1
- package/dist/src/tools/delete-alarm-tool.js +1 -1
- package/dist/src/tools/find-pc-devices-tool.d.ts +2 -1
- package/dist/src/tools/find-pc-devices-tool.js +84 -88
- package/dist/src/tools/get-device-file-tool-schema.js +3 -2
- package/dist/src/tools/image-reading-tool.js +4 -4
- package/dist/src/tools/location-tool.js +1 -1
- package/dist/src/tools/modify-alarm-tool.js +1 -1
- package/dist/src/tools/modify-note-tool.js +1 -1
- package/dist/src/tools/note-tool.js +1 -1
- package/dist/src/tools/query-app-message-tool.js +1 -1
- package/dist/src/tools/query-memory-data-tool.js +1 -1
- package/dist/src/tools/query-todo-task-tool.js +1 -1
- package/dist/src/tools/save-file-to-phone-tool.js +1 -1
- package/dist/src/tools/save-media-to-gallery-tool.js +1 -1
- package/dist/src/tools/search-alarm-tool.js +1 -1
- package/dist/src/tools/search-calendar-tool.js +1 -1
- package/dist/src/tools/search-contact-tool.js +1 -1
- package/dist/src/tools/search-email-tool.js +1 -1
- package/dist/src/tools/search-file-tool.js +11 -8
- package/dist/src/tools/search-message-tool.js +1 -1
- package/dist/src/tools/search-note-tool.js +1 -1
- package/dist/src/tools/search-photo-gallery-tool.js +1 -1
- package/dist/src/tools/send-email-tool.js +1 -1
- package/dist/src/tools/send-file-to-user-tool.js +2 -2
- package/dist/src/tools/send-message-tool.js +1 -1
- package/dist/src/tools/session-manager.js +5 -0
- package/dist/src/tools/upload-file-tool.js +15 -5
- package/dist/src/tools/upload-photo-tool.js +1 -1
- package/dist/src/tools/xiaoyi-add-collection-tool.js +1 -1
- package/dist/src/tools/xiaoyi-collection-tool.js +1 -1
- package/dist/src/tools/xiaoyi-delete-collection-tool.js +1 -1
- package/dist/src/tools/xiaoyi-gui-tool.js +1 -1
- package/dist/src/trigger-handler.js +4 -7
- package/dist/src/utils/config-manager.js +3 -6
- package/dist/src/utils/logger.d.ts +8 -0
- package/dist/src/utils/logger.js +69 -34
- package/dist/src/utils/pushdata-manager.js +1 -5
- package/dist/src/utils/pushid-manager.js +1 -2
- package/dist/src/utils/runtime-manager.js +1 -4
- package/dist/src/websocket.js +37 -25
- package/package.json +1 -1
|
@@ -1,98 +1,94 @@
|
|
|
1
1
|
import { getXYWebSocketManager } from "../client.js";
|
|
2
2
|
import { sendCommand } from "../formatter.js";
|
|
3
|
-
import { getCurrentSessionContext } from "./session-manager.js";
|
|
4
3
|
/**
|
|
5
4
|
* XY find PC devices tool - finds all PC devices associated with the user.
|
|
6
5
|
* Returns device IDs for use in subsequent file search operations.
|
|
7
6
|
*/
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const command = {
|
|
28
|
-
header: {
|
|
29
|
-
namespace: "Common",
|
|
30
|
-
name: "Action",
|
|
31
|
-
},
|
|
32
|
-
payload: {
|
|
33
|
-
cardParam: {},
|
|
34
|
-
executeParam: {
|
|
35
|
-
achieveType: "INTENT",
|
|
36
|
-
actionResponse: true,
|
|
37
|
-
bundleName: "com.huawei.hmos.aidispatchservice",
|
|
38
|
-
dimension: "",
|
|
39
|
-
executeMode: "background",
|
|
40
|
-
intentName: "GetAllDevice",
|
|
41
|
-
intentParam: {},
|
|
42
|
-
needUnlock: true,
|
|
43
|
-
permissionId: [],
|
|
44
|
-
timeOut: 5,
|
|
7
|
+
export function createFindPcDevicesTool(ctx) {
|
|
8
|
+
const { config, sessionId, taskId, messageId } = ctx;
|
|
9
|
+
return {
|
|
10
|
+
name: "find_pc_devices",
|
|
11
|
+
label: "Find PC Devices",
|
|
12
|
+
description: `查找用户所有PC/电脑设备,获取设备ID列表。当用户说"帮我找一下PC/电脑上的xxx文件"、"帮我搜索电脑上的xxx"等涉及PC设备的请求时,先调用此工具获取设备ID,再进行后续操作。注意:操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。回复约束:如果工具返回没有授权或者其他报错,只需要完整描述没有授权或者其他报错内容即可,不需要主动给用户提供解决方案,请严格遵守。`,
|
|
13
|
+
parameters: {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {},
|
|
16
|
+
required: [],
|
|
17
|
+
},
|
|
18
|
+
async execute(toolCallId, params) {
|
|
19
|
+
// Get WebSocket manager
|
|
20
|
+
const wsManager = getXYWebSocketManager(config);
|
|
21
|
+
// Build GetAllDevice command
|
|
22
|
+
const command = {
|
|
23
|
+
header: {
|
|
24
|
+
namespace: "Common",
|
|
25
|
+
name: "Action",
|
|
45
26
|
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
27
|
+
payload: {
|
|
28
|
+
cardParam: {},
|
|
29
|
+
executeParam: {
|
|
30
|
+
achieveType: "INTENT",
|
|
31
|
+
actionResponse: true,
|
|
32
|
+
bundleName: "com.huawei.hmos.aidispatchservice",
|
|
33
|
+
dimension: "",
|
|
34
|
+
executeMode: "background",
|
|
35
|
+
intentName: "GetAllDevice",
|
|
36
|
+
intentParam: {},
|
|
37
|
+
needUnlock: true,
|
|
38
|
+
permissionId: [],
|
|
39
|
+
timeOut: 5,
|
|
40
|
+
},
|
|
41
|
+
needUploadResult: true,
|
|
42
|
+
pageControlRelated: false,
|
|
43
|
+
responses: [{
|
|
44
|
+
displayText: "",
|
|
45
|
+
resultCode: "",
|
|
46
|
+
ttsText: "",
|
|
47
|
+
}],
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
// Send command and wait for response (60 second timeout)
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
const timeout = setTimeout(() => {
|
|
65
53
|
wsManager.off("data-event", handler);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
54
|
+
reject(new Error("查找PC设备超时(60秒)"));
|
|
55
|
+
}, 60000);
|
|
56
|
+
// Listen for data events from WebSocket
|
|
57
|
+
const handler = (event) => {
|
|
58
|
+
if (event.intentName === "GetAllDevice") {
|
|
59
|
+
clearTimeout(timeout);
|
|
60
|
+
wsManager.off("data-event", handler);
|
|
61
|
+
if (event.status === "success" && event.outputs) {
|
|
62
|
+
resolve({
|
|
63
|
+
content: [
|
|
64
|
+
{
|
|
65
|
+
type: "text",
|
|
66
|
+
text: JSON.stringify(event.outputs),
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
reject(new Error(`查找PC设备失败: ${event.status}`));
|
|
73
|
+
}
|
|
78
74
|
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
75
|
+
};
|
|
76
|
+
// Register event handler
|
|
77
|
+
wsManager.on("data-event", handler);
|
|
78
|
+
// Send the command
|
|
79
|
+
sendCommand({
|
|
80
|
+
config,
|
|
81
|
+
sessionId,
|
|
82
|
+
taskId,
|
|
83
|
+
messageId,
|
|
84
|
+
command,
|
|
85
|
+
}).then(() => {
|
|
86
|
+
}).catch((error) => {
|
|
87
|
+
clearTimeout(timeout);
|
|
88
|
+
wsManager.off("data-event", handler);
|
|
89
|
+
reject(error);
|
|
90
|
+
});
|
|
95
91
|
});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -2,13 +2,14 @@ import { createSchemaTool } from "./schema-tool-factory.js";
|
|
|
2
2
|
import { createSearchFileTool } from "./search-file-tool.js";
|
|
3
3
|
import { createUploadFileTool } from "./upload-file-tool.js";
|
|
4
4
|
import { createSaveFileToPhoneTool } from "./save-file-to-phone-tool.js";
|
|
5
|
+
import { createFindPcDevicesTool } from "./find-pc-devices-tool.js";
|
|
5
6
|
export function createGetDeviceFileToolSchemaTool(ctx) {
|
|
6
7
|
const searchFileTool = createSearchFileTool(ctx);
|
|
7
8
|
const saveFileToPhoneTool = createSaveFileToPhoneTool(ctx);
|
|
8
9
|
return createSchemaTool({
|
|
9
10
|
name: "get_device_file_tool_schema",
|
|
10
11
|
label: "Get Device File Tool Schema",
|
|
11
|
-
description: "
|
|
12
|
-
tools: [searchFileTool, createUploadFileTool(ctx), saveFileToPhoneTool],
|
|
12
|
+
description: "获取可在用户设备上搜索文件系统的文件、将用户设备本地文件上传到公网并获取链接、保存文件到文件管理器、查找PC设备的相关端工具列表。",
|
|
13
|
+
tools: [searchFileTool, createUploadFileTool(ctx), saveFileToPhoneTool, createFindPcDevicesTool(ctx)],
|
|
13
14
|
});
|
|
14
15
|
}
|
|
@@ -51,7 +51,7 @@ async function processImageInput(imageInput, uploadService) {
|
|
|
51
51
|
* Call image understanding API with streaming response
|
|
52
52
|
* Supports both single image and multiple images (imageUrls array)
|
|
53
53
|
*/
|
|
54
|
-
async function callImageUnderstandingAPI(imageUrls, text, apiKey, uid, fileUploadUrl) {
|
|
54
|
+
async function callImageUnderstandingAPI(imageUrls, text, apiKey, uid, fileUploadUrl, sessionId) {
|
|
55
55
|
const apiUrl = `${fileUploadUrl}/celia-claw/v1/sse-api/skill/execute`;
|
|
56
56
|
const traceId = `${createHash("sha256").update(uid).digest("hex").slice(0, 32)}_${Date.now()}`;
|
|
57
57
|
const headers = {
|
|
@@ -68,7 +68,7 @@ async function callImageUnderstandingAPI(imageUrls, text, apiKey, uid, fileUploa
|
|
|
68
68
|
version: "1.0",
|
|
69
69
|
session: {
|
|
70
70
|
isNew: false,
|
|
71
|
-
sessionId
|
|
71
|
+
sessionId,
|
|
72
72
|
interactionId: 0,
|
|
73
73
|
},
|
|
74
74
|
endpoint: {
|
|
@@ -166,7 +166,7 @@ async function callImageUnderstandingAPI(imageUrls, text, apiKey, uid, fileUploa
|
|
|
166
166
|
* Supports both local file paths and remote URLs, up to 10 images at once.
|
|
167
167
|
*/
|
|
168
168
|
export function createImageReadingTool(ctx) {
|
|
169
|
-
const { config } = ctx;
|
|
169
|
+
const { config, sessionId } = ctx;
|
|
170
170
|
return {
|
|
171
171
|
name: "image_reading",
|
|
172
172
|
label: "Image Reading",
|
|
@@ -210,7 +210,7 @@ export function createImageReadingTool(ctx) {
|
|
|
210
210
|
allImageUrls.push(await processImageInput(imageInput, uploadService));
|
|
211
211
|
}
|
|
212
212
|
// Call image understanding API with all image URLs
|
|
213
|
-
const caption = await callImageUnderstandingAPI(allImageUrls, prompt, config.apiKey, config.uid, config.fileUploadUrl);
|
|
213
|
+
const caption = await callImageUnderstandingAPI(allImageUrls, prompt, config.apiKey, config.uid, config.fileUploadUrl, sessionId);
|
|
214
214
|
return {
|
|
215
215
|
content: [
|
|
216
216
|
{
|
|
@@ -55,7 +55,7 @@ export function createLocationTool(ctx) {
|
|
|
55
55
|
return new Promise((resolve, reject) => {
|
|
56
56
|
const timeout = setTimeout(() => {
|
|
57
57
|
wsManager.off("data-event", handler);
|
|
58
|
-
logger.error("超时: 获取位置超时(60秒)", {
|
|
58
|
+
logger.error("超时: 获取位置超时(60秒)", { toolCallId });
|
|
59
59
|
reject(new Error("获取位置超时(60秒)"));
|
|
60
60
|
}, 60000);
|
|
61
61
|
// Listen for data events from WebSocket
|
|
@@ -236,7 +236,7 @@ export function createModifyAlarmTool(ctx) {
|
|
|
236
236
|
return new Promise((resolve, reject) => {
|
|
237
237
|
const timeout = setTimeout(() => {
|
|
238
238
|
wsManager.off("data-event", handler);
|
|
239
|
-
logger.error("超时: 修改闹钟超时(60秒)", {
|
|
239
|
+
logger.error("超时: 修改闹钟超时(60秒)", { toolCallId });
|
|
240
240
|
reject(new Error("修改闹钟超时(60秒)"));
|
|
241
241
|
}, 60000);
|
|
242
242
|
// Listen for data events from WebSocket
|
|
@@ -77,7 +77,7 @@ export function createModifyNoteTool(ctx) {
|
|
|
77
77
|
return new Promise((resolve, reject) => {
|
|
78
78
|
const timeout = setTimeout(() => {
|
|
79
79
|
wsManager.off("data-event", handler);
|
|
80
|
-
logger.error("超时: 修改备忘录超时(60秒)", {
|
|
80
|
+
logger.error("超时: 修改备忘录超时(60秒)", { toolCallId });
|
|
81
81
|
reject(new Error("修改备忘录超时(60秒)"));
|
|
82
82
|
}, 60000);
|
|
83
83
|
// Listen for data events from WebSocket
|
|
@@ -94,7 +94,7 @@ export function createNoteTool(ctx) {
|
|
|
94
94
|
return new Promise((resolve, reject) => {
|
|
95
95
|
const timeout = setTimeout(() => {
|
|
96
96
|
wsManager.off("data-event", handler);
|
|
97
|
-
logger.error("超时: 创建备忘录超时(60秒)", {
|
|
97
|
+
logger.error("超时: 创建备忘录超时(60秒)", { toolCallId });
|
|
98
98
|
reject(new Error("创建备忘录超时(60秒)"));
|
|
99
99
|
}, 60000);
|
|
100
100
|
// Listen for data events from WebSocket
|
|
@@ -96,7 +96,7 @@ c. 调用工具前需认真检查调用参数是否满足工具要求
|
|
|
96
96
|
return new Promise((resolve, reject) => {
|
|
97
97
|
const timeout = setTimeout(() => {
|
|
98
98
|
wsManager.off("data-event", handler);
|
|
99
|
-
logger.error("超时: 查询通知消息超时(60秒)", {
|
|
99
|
+
logger.error("超时: 查询通知消息超时(60秒)", { toolCallId: _toolCallId });
|
|
100
100
|
reject(new Error("查询通知消息超时(60秒)"));
|
|
101
101
|
}, 60000);
|
|
102
102
|
const handler = (event) => {
|
|
@@ -112,7 +112,7 @@ c. 调用工具前需认真检查调用参数是否满足工具要求
|
|
|
112
112
|
return new Promise((resolve, reject) => {
|
|
113
113
|
const timeout = setTimeout(() => {
|
|
114
114
|
wsManager.off("data-event", handler);
|
|
115
|
-
logger.error("超时: 查询记忆数据超时(60秒)", {
|
|
115
|
+
logger.error("超时: 查询记忆数据超时(60秒)", { toolCallId: _toolCallId });
|
|
116
116
|
reject(new Error("查询记忆数据超时(60秒)"));
|
|
117
117
|
}, 60000);
|
|
118
118
|
const handler = (event) => {
|
|
@@ -91,7 +91,7 @@ d. 当只传入 startTime 时,返回该时间点之后的所有任务;当只
|
|
|
91
91
|
return new Promise((resolve, reject) => {
|
|
92
92
|
const timeout = setTimeout(() => {
|
|
93
93
|
wsManager.off("data-event", handler);
|
|
94
|
-
logger.error("超时: 查询待办任务超时(60秒)", {
|
|
94
|
+
logger.error("超时: 查询待办任务超时(60秒)", { toolCallId: _toolCallId });
|
|
95
95
|
reject(new Error("查询待办任务超时(60秒)"));
|
|
96
96
|
}, 60000);
|
|
97
97
|
const handler = (event) => {
|
|
@@ -119,7 +119,7 @@ export function createSaveFileToPhoneTool(ctx) {
|
|
|
119
119
|
return new Promise((resolve, reject) => {
|
|
120
120
|
const timeout = setTimeout(() => {
|
|
121
121
|
wsManager.off("data-event", handler);
|
|
122
|
-
logger.error("超时: 保存文件到手机超时(60秒)", {
|
|
122
|
+
logger.error("超时: 保存文件到手机超时(60秒)", { toolCallId });
|
|
123
123
|
reject(new Error("保存文件到手机超时(60秒)"));
|
|
124
124
|
}, 60000);
|
|
125
125
|
// Listen for data events from WebSocket
|
|
@@ -127,7 +127,7 @@ export function createSaveMediaToGalleryTool(ctx) {
|
|
|
127
127
|
return new Promise((resolve, reject) => {
|
|
128
128
|
const timeout = setTimeout(() => {
|
|
129
129
|
wsManager.off("data-event", handler);
|
|
130
|
-
logger.error("超时: 保存媒体到图库超时(60秒)", {
|
|
130
|
+
logger.error("超时: 保存媒体到图库超时(60秒)", { toolCallId });
|
|
131
131
|
reject(new Error("保存媒体到图库超时(60秒)"));
|
|
132
132
|
}, 60000);
|
|
133
133
|
// Listen for data events from WebSocket
|
|
@@ -168,7 +168,7 @@ b. 使用该工具之前需获取当前真实时间
|
|
|
168
168
|
return new Promise((resolve, reject) => {
|
|
169
169
|
const timeout = setTimeout(() => {
|
|
170
170
|
wsManager.off("data-event", handler);
|
|
171
|
-
logger.error("超时: 检索闹钟超时(60秒)", {
|
|
171
|
+
logger.error("超时: 检索闹钟超时(60秒)", { toolCallId });
|
|
172
172
|
reject(new Error("检索闹钟超时(60秒)"));
|
|
173
173
|
}, 60000);
|
|
174
174
|
// Listen for data events from WebSocket
|
|
@@ -139,7 +139,7 @@ d. 如果查询结果返回-303,代表查询结果为空
|
|
|
139
139
|
return new Promise((resolve, reject) => {
|
|
140
140
|
const timeout = setTimeout(() => {
|
|
141
141
|
wsManager.off("data-event", handler);
|
|
142
|
-
logger.error("超时: 检索日程超时(60秒)", {
|
|
142
|
+
logger.error("超时: 检索日程超时(60秒)", { toolCallId });
|
|
143
143
|
reject(new Error("检索日程超时(60秒)"));
|
|
144
144
|
}, 60000);
|
|
145
145
|
// Listen for data events from WebSocket
|
|
@@ -67,7 +67,7 @@ export function createSearchContactTool(ctx) {
|
|
|
67
67
|
return new Promise((resolve, reject) => {
|
|
68
68
|
const timeout = setTimeout(() => {
|
|
69
69
|
wsManager.off("data-event", handler);
|
|
70
|
-
logger.error("超时: 搜索联系人超时(60秒)", {
|
|
70
|
+
logger.error("超时: 搜索联系人超时(60秒)", { toolCallId });
|
|
71
71
|
reject(new Error("搜索联系人超时(60秒)"));
|
|
72
72
|
}, 60000);
|
|
73
73
|
// Listen for data events from WebSocket
|
|
@@ -91,7 +91,7 @@ b. 使用该工具之前需获取当前真实时间
|
|
|
91
91
|
return new Promise((resolve, reject) => {
|
|
92
92
|
const timeout = setTimeout(() => {
|
|
93
93
|
wsManager.off("data-event", handler);
|
|
94
|
-
logger.error("超时: 检索邮件超时(60秒)", {
|
|
94
|
+
logger.error("超时: 检索邮件超时(60秒)", { toolCallId: _toolCallId });
|
|
95
95
|
reject(new Error("检索邮件超时(60秒)"));
|
|
96
96
|
}, 60000);
|
|
97
97
|
// Listen for data events from WebSocket
|
|
@@ -11,15 +11,13 @@ export function createSearchFileTool(ctx) {
|
|
|
11
11
|
return {
|
|
12
12
|
name: "search_file",
|
|
13
13
|
label: "Search File",
|
|
14
|
-
description:
|
|
14
|
+
description: `搜索手机或PC/电脑文件系统的文件。
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- "在手机上查找文件xxxx"
|
|
20
|
-
- "搜索手机里的文件"
|
|
16
|
+
【重要】使用场景与调用流程:
|
|
17
|
+
1. 搜索手机文件:当用户明确说明要从手机搜索时(如"从手机里面搜索xxxx"、"在手机上查找文件xxxx"),直接调用此工具,无需传入 udid。
|
|
18
|
+
2. 搜索PC/电脑文件:当用户要求搜索PC/电脑上的文件时(如"帮我找一下PC上的xxx文件"、"搜索电脑上的xxx"),必须先调用 find_pc_devices 工具获取设备ID(udid),然后将 udid 传入此工具进行搜索。
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
如果用户没有明确说明从手机或PC搜索(如仅说"搜索文件"、"找一下xxxx"),应默认从当前runtime运行环境的本地文件系统查询,不要调用此工具。
|
|
23
21
|
|
|
24
22
|
功能说明:根据关键词搜索文件名称或内容,返回匹配的文件列表(包括文件名、路径、大小、修改时间等信息)。
|
|
25
23
|
|
|
@@ -31,6 +29,10 @@ export function createSearchFileTool(ctx) {
|
|
|
31
29
|
type: "string",
|
|
32
30
|
description: "搜索关键词,用于匹配文件名称、后缀名或文件内容",
|
|
33
31
|
},
|
|
32
|
+
udid: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "PC/电脑设备ID。当搜索PC/电脑上的文件时,需要先通过 find_pc_devices 工具获取设备ID后传入。搜索手机文件时不需要传入此参数。",
|
|
35
|
+
},
|
|
34
36
|
},
|
|
35
37
|
required: ["query"],
|
|
36
38
|
},
|
|
@@ -59,6 +61,7 @@ export function createSearchFileTool(ctx) {
|
|
|
59
61
|
timeOut: 5,
|
|
60
62
|
intentParam: {
|
|
61
63
|
query: params.query.trim(),
|
|
64
|
+
...(params.udid ? { udid: params.udid } : {}),
|
|
62
65
|
},
|
|
63
66
|
permissionId: [],
|
|
64
67
|
achieveType: "INTENT",
|
|
@@ -79,7 +82,7 @@ export function createSearchFileTool(ctx) {
|
|
|
79
82
|
return new Promise((resolve, reject) => {
|
|
80
83
|
const timeout = setTimeout(() => {
|
|
81
84
|
wsManager.off("data-event", handler);
|
|
82
|
-
logger.error("超时: 搜索文件超时(60秒)", {
|
|
85
|
+
logger.error("超时: 搜索文件超时(60秒)", { toolCallId });
|
|
83
86
|
reject(new Error("搜索文件超时(60秒)"));
|
|
84
87
|
}, 60000);
|
|
85
88
|
// Listen for data events from WebSocket
|
|
@@ -68,7 +68,7 @@ export function createSearchMessageTool(ctx) {
|
|
|
68
68
|
return new Promise((resolve, reject) => {
|
|
69
69
|
const timeout = setTimeout(() => {
|
|
70
70
|
wsManager.off("data-event", handler);
|
|
71
|
-
logger.error("超时: 搜索短信超时(60秒)", {
|
|
71
|
+
logger.error("超时: 搜索短信超时(60秒)", { toolCallId });
|
|
72
72
|
reject(new Error("搜索短信超时(60秒)"));
|
|
73
73
|
}, 60000);
|
|
74
74
|
// Listen for data events from WebSocket
|
|
@@ -66,7 +66,7 @@ export function createSearchNoteTool(ctx) {
|
|
|
66
66
|
return new Promise((resolve, reject) => {
|
|
67
67
|
const timeout = setTimeout(() => {
|
|
68
68
|
wsManager.off("data-event", handler);
|
|
69
|
-
logger.error("超时: 搜索备忘录超时(60秒)", {
|
|
69
|
+
logger.error("超时: 搜索备忘录超时(60秒)", { toolCallId });
|
|
70
70
|
reject(new Error("搜索备忘录超时(60秒)"));
|
|
71
71
|
}, 60000);
|
|
72
72
|
// Listen for data events from WebSocket
|
|
@@ -128,7 +128,7 @@ async function searchPhotos(wsManager, config, sessionId, taskId, messageId, que
|
|
|
128
128
|
return new Promise((resolve, reject) => {
|
|
129
129
|
const timeout = setTimeout(() => {
|
|
130
130
|
wsManager.off("data-event", handler);
|
|
131
|
-
logger.error("超时: 搜索照片超时(60秒)"
|
|
131
|
+
logger.error("超时: 搜索照片超时(60秒)");
|
|
132
132
|
reject(new Error("搜索照片超时(60秒)"));
|
|
133
133
|
}, 60000);
|
|
134
134
|
const handler = (event) => {
|
|
@@ -92,7 +92,7 @@ c. 调用工具前需认真检查调用参数是否满足工具要求
|
|
|
92
92
|
return new Promise((resolve, reject) => {
|
|
93
93
|
const timeout = setTimeout(() => {
|
|
94
94
|
wsManager.off("data-event", handler);
|
|
95
|
-
logger.error("超时: 发送邮件超时(60秒)", {
|
|
95
|
+
logger.error("超时: 发送邮件超时(60秒)", { toolCallId: _toolCallId });
|
|
96
96
|
reject(new Error("发送邮件超时(60秒)"));
|
|
97
97
|
}, 60000);
|
|
98
98
|
const handler = (event) => {
|
|
@@ -240,10 +240,10 @@ b. 操作超时时间为2分钟(120秒),请勿重复调用此工具,如
|
|
|
240
240
|
error: { code: 0 },
|
|
241
241
|
}),
|
|
242
242
|
};
|
|
243
|
-
logger.log(`[SEND-FILE-TO-USER]
|
|
243
|
+
logger.log(`[SEND-FILE-TO-USER] EXEC sending, fileName=${fileName}`);
|
|
244
244
|
// Send WebSocket message
|
|
245
245
|
await wsManager.sendMessage(sessionId, agentResponse);
|
|
246
|
-
logger.log(`send ${fileName} file to user success`);
|
|
246
|
+
logger.log(`[SEND-FILE-TO-USER] send ${fileName} file to user success`);
|
|
247
247
|
sentFiles.push({ fileName, fileId });
|
|
248
248
|
}
|
|
249
249
|
return {
|
|
@@ -89,7 +89,7 @@ export function createSendMessageTool(ctx) {
|
|
|
89
89
|
return new Promise((resolve, reject) => {
|
|
90
90
|
const timeout = setTimeout(() => {
|
|
91
91
|
wsManager.off("data-event", handler);
|
|
92
|
-
logger.error("超时: 发送短信超时(60秒)", {
|
|
92
|
+
logger.error("超时: 发送短信超时(60秒)", { toolCallId });
|
|
93
93
|
reject(new Error("发送短信超时(60秒)"));
|
|
94
94
|
}, 60000);
|
|
95
95
|
// Listen for data events from WebSocket
|
|
@@ -27,6 +27,11 @@ const getLastRegisteredKey = () => _g.__xyLastRegisteredSessionKey;
|
|
|
27
27
|
const setLastRegisteredKey = (key) => { _g.__xyLastRegisteredSessionKey = key; };
|
|
28
28
|
// AsyncLocalStorage for thread-safe session context isolation
|
|
29
29
|
export const asyncLocalStorage = new AsyncLocalStorage();
|
|
30
|
+
// Export AsyncLocalStorage to globalThis so logger.ts can access it
|
|
31
|
+
// without creating a circular dependency (session-manager imports logger)
|
|
32
|
+
if (!_g.__xyAsyncLocalStorage) {
|
|
33
|
+
_g.__xyAsyncLocalStorage = asyncLocalStorage;
|
|
34
|
+
}
|
|
30
35
|
/**
|
|
31
36
|
* Register a session context for tool access.
|
|
32
37
|
* Should be called when starting to process a message.
|
|
@@ -19,14 +19,19 @@ export function createUploadFileTool(ctx) {
|
|
|
19
19
|
return {
|
|
20
20
|
name: "upload_file",
|
|
21
21
|
label: "Upload File",
|
|
22
|
-
description:
|
|
22
|
+
description: `工具能力描述:将手机或PC/电脑本地文件上传并获取可公网访问的 URL。
|
|
23
23
|
|
|
24
24
|
前置工具调用:此工具使用前必须先通过call_device_tool调用 search_file 或者 query_collection 工具获取文件的 uri
|
|
25
25
|
|
|
26
|
+
使用场景与调用流程:
|
|
27
|
+
1. 上传手机文件:直接调用此工具,无需传入 udid。
|
|
28
|
+
2. 上传PC/电脑文件:当用户要求上传PC/电脑上的文件时,需要先通过 find_pc_devices 工具获取设备ID(udid),然后将 udid 传入此工具。
|
|
29
|
+
|
|
26
30
|
工具参数说明:
|
|
27
31
|
a. 入参中的fileInfos数组,每个元素必须包含mediaUri字段(对应于search_file工具或者query_collection返回结果中的uri),必须与search_file或者query_collection结果中对应的uri完全保持一致,不要自行修改。
|
|
28
32
|
b. fileInfos中的timeout字段是可选的,表示上传文件超时时间,单位是毫秒,默认是20000(20秒)。
|
|
29
|
-
c. fileInfos
|
|
33
|
+
c. fileInfos 是文件在本地的信息数组(从 search_file 工具或者query_collection 工具响应中获取)。限制:每次最多支持传入 5 条文件信息。
|
|
34
|
+
d. udid 是PC/电脑设备ID,仅在上传PC/电脑文件时需要传入(通过 find_pc_devices 工具获取)。
|
|
30
35
|
|
|
31
36
|
注意事项:
|
|
32
37
|
a. 操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。
|
|
@@ -39,6 +44,10 @@ export function createUploadFileTool(ctx) {
|
|
|
39
44
|
// 具体的类型验证和转换在 execute 函数内部进行
|
|
40
45
|
description: "文件信息数组,每个元素包含mediaUri(必需)和timeout(可选,默认20000)。必须先通过 search_file 工具获取。每次最多支持 5 条文件信息。",
|
|
41
46
|
},
|
|
47
|
+
udid: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "PC/电脑设备ID。当上传PC/电脑上的文件时,需要先通过 find_pc_devices 工具获取设备ID后传入。上传手机文件时不需要传入此参数。",
|
|
50
|
+
},
|
|
42
51
|
},
|
|
43
52
|
required: ["fileInfos"],
|
|
44
53
|
},
|
|
@@ -97,7 +106,7 @@ export function createUploadFileTool(ctx) {
|
|
|
97
106
|
const wsManager = getXYWebSocketManager(config);
|
|
98
107
|
// Get public URLs for the files
|
|
99
108
|
const currentTaskId = getCurrentTaskId(sessionId) ?? taskId;
|
|
100
|
-
const fileUrls = await getFileUrls(wsManager, config, sessionId, currentTaskId, messageId, fileInfos);
|
|
109
|
+
const fileUrls = await getFileUrls(wsManager, config, sessionId, currentTaskId, messageId, fileInfos, params.udid);
|
|
101
110
|
return {
|
|
102
111
|
content: [
|
|
103
112
|
{
|
|
@@ -117,7 +126,7 @@ export function createUploadFileTool(ctx) {
|
|
|
117
126
|
* Get public URLs for files using fileInfos
|
|
118
127
|
* Returns array of publicly accessible file URLs
|
|
119
128
|
*/
|
|
120
|
-
async function getFileUrls(wsManager, config, sessionId, taskId, messageId, fileInfos) {
|
|
129
|
+
async function getFileUrls(wsManager, config, sessionId, taskId, messageId, fileInfos, udid) {
|
|
121
130
|
const command = {
|
|
122
131
|
header: {
|
|
123
132
|
namespace: "Common",
|
|
@@ -135,6 +144,7 @@ async function getFileUrls(wsManager, config, sessionId, taskId, messageId, file
|
|
|
135
144
|
timeOut: 5,
|
|
136
145
|
intentParam: {
|
|
137
146
|
fileInfos: fileInfos,
|
|
147
|
+
...(udid ? { udid } : {}),
|
|
138
148
|
},
|
|
139
149
|
permissionId: [],
|
|
140
150
|
achieveType: "INTENT",
|
|
@@ -154,7 +164,7 @@ async function getFileUrls(wsManager, config, sessionId, taskId, messageId, file
|
|
|
154
164
|
return new Promise((resolve, reject) => {
|
|
155
165
|
const timeout = setTimeout(() => {
|
|
156
166
|
wsManager.off("data-event", handler);
|
|
157
|
-
logger.error("超时: 获取文件URL超时(60秒)"
|
|
167
|
+
logger.error("超时: 获取文件URL超时(60秒)");
|
|
158
168
|
reject(new Error("获取文件URL超时(60秒)"));
|
|
159
169
|
}, 60000);
|
|
160
170
|
const handler = (event) => {
|
|
@@ -137,7 +137,7 @@ async function getPhotoUrls(wsManager, config, sessionId, taskId, messageId, med
|
|
|
137
137
|
return new Promise((resolve, reject) => {
|
|
138
138
|
const timeout = setTimeout(() => {
|
|
139
139
|
wsManager.off("data-event", handler);
|
|
140
|
-
logger.error("超时: 获取照片URL超时(60秒)"
|
|
140
|
+
logger.error("超时: 获取照片URL超时(60秒)");
|
|
141
141
|
reject(new Error("获取照片URL超时(60秒)"));
|
|
142
142
|
}, 60000);
|
|
143
143
|
const handler = (event) => {
|
|
@@ -145,7 +145,7 @@ export function createXiaoyiAddCollectionTool(ctx) {
|
|
|
145
145
|
return new Promise((resolve, reject) => {
|
|
146
146
|
const timeout = setTimeout(() => {
|
|
147
147
|
wsManager.off("data-event", handler);
|
|
148
|
-
logger.error("超时: 添加小艺收藏超时(60秒)", {
|
|
148
|
+
logger.error("超时: 添加小艺收藏超时(60秒)", { toolCallId });
|
|
149
149
|
reject(new Error("添加小艺收藏超时(60秒)"));
|
|
150
150
|
}, 60000);
|
|
151
151
|
// Listen for data events from WebSocket
|
|
@@ -100,7 +100,7 @@ export function createXiaoyiCollectionTool(ctx) {
|
|
|
100
100
|
return new Promise((resolve, reject) => {
|
|
101
101
|
const timeout = setTimeout(() => {
|
|
102
102
|
wsManager.off("data-event", handler);
|
|
103
|
-
logger.error("超时: 查询小艺收藏超时(60秒)", {
|
|
103
|
+
logger.error("超时: 查询小艺收藏超时(60秒)", { toolCallId });
|
|
104
104
|
reject(new Error("查询小艺收藏超时(60秒)"));
|
|
105
105
|
}, 60000);
|
|
106
106
|
// Listen for data events from WebSocket
|
|
@@ -116,7 +116,7 @@ export function createXiaoyiDeleteCollectionTool(ctx) {
|
|
|
116
116
|
return new Promise((resolve, reject) => {
|
|
117
117
|
const timeout = setTimeout(() => {
|
|
118
118
|
wsManager.off("data-event", handler);
|
|
119
|
-
logger.error("超时: 删除小艺收藏超时(60秒)", {
|
|
119
|
+
logger.error("超时: 删除小艺收藏超时(60秒)", { toolCallId });
|
|
120
120
|
reject(new Error("删除小艺收藏超时(60秒)"));
|
|
121
121
|
}, 60000);
|
|
122
122
|
// Listen for data events from WebSocket
|
|
@@ -64,7 +64,7 @@ export function createXiaoyiGuiTool(ctx) {
|
|
|
64
64
|
return new Promise((resolve, reject) => {
|
|
65
65
|
const timeout = setTimeout(() => {
|
|
66
66
|
wsManager.off("gui-agent-response", handler);
|
|
67
|
-
logger.error("超时: XiaoYi GUI Agent 操作超时(5分钟)", {
|
|
67
|
+
logger.error("超时: XiaoYi GUI Agent 操作超时(5分钟)", { toolCallId });
|
|
68
68
|
reject(new Error("XiaoYi GUI Agent 操作超时(5分钟)"));
|
|
69
69
|
}, 180000); // 5 minutes timeout
|
|
70
70
|
// Listen for GUI agent response events
|