@ynhcj/xiaoyi-channel 0.0.26-beta → 0.0.28-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/bot.js +13 -3
- package/dist/src/channel.js +11 -1
- package/dist/src/outbound.js +88 -76
- package/dist/src/tools/calendar-tool.js +2 -2
- package/dist/src/tools/call-phone-tool.d.ts +5 -0
- package/dist/src/tools/call-phone-tool.js +183 -0
- package/dist/src/tools/create-alarm-tool.d.ts +7 -0
- package/dist/src/tools/create-alarm-tool.js +444 -0
- package/dist/src/tools/delete-alarm-tool.d.ts +11 -0
- package/dist/src/tools/delete-alarm-tool.js +238 -0
- package/dist/src/tools/location-tool.js +2 -2
- package/dist/src/tools/modify-alarm-tool.d.ts +9 -0
- package/dist/src/tools/modify-alarm-tool.js +474 -0
- package/dist/src/tools/modify-note-tool.js +2 -2
- package/dist/src/tools/note-tool.js +2 -2
- package/dist/src/tools/search-alarm-tool.d.ts +8 -0
- package/dist/src/tools/search-alarm-tool.js +389 -0
- package/dist/src/tools/search-calendar-tool.js +2 -2
- package/dist/src/tools/search-contact-tool.js +2 -2
- package/dist/src/tools/search-file-tool.d.ts +5 -0
- package/dist/src/tools/search-file-tool.js +173 -0
- package/dist/src/tools/search-message-tool.d.ts +5 -0
- package/dist/src/tools/search-message-tool.js +173 -0
- package/dist/src/tools/search-note-tool.js +2 -2
- package/dist/src/tools/search-photo-gallery-tool.js +2 -2
- package/dist/src/tools/send-file-to-user-tool.d.ts +5 -0
- package/dist/src/tools/send-file-to-user-tool.js +290 -0
- package/dist/src/tools/send-message-tool.d.ts +5 -0
- package/dist/src/tools/send-message-tool.js +189 -0
- package/dist/src/tools/session-manager.d.ts +12 -0
- package/dist/src/tools/session-manager.js +33 -0
- package/dist/src/tools/upload-file-tool.d.ts +13 -0
- package/dist/src/tools/upload-file-tool.js +265 -0
- package/dist/src/tools/upload-photo-tool.js +2 -2
- package/dist/src/tools/xiaoyi-gui-tool.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { getXYWebSocketManager } from "../client.js";
|
|
2
|
+
import { sendCommand } from "../formatter.js";
|
|
3
|
+
import { getCurrentSessionContext } from "./session-manager.js";
|
|
4
|
+
import { logger } from "../utils/logger.js";
|
|
5
|
+
/**
|
|
6
|
+
* XY delete alarm tool - deletes existing alarms on user's device.
|
|
7
|
+
* Requires entityId(s) from search_alarm or create_alarm tool as prerequisite.
|
|
8
|
+
*
|
|
9
|
+
* Prerequisites:
|
|
10
|
+
* 1. Call search_alarm or create_alarm tool first to get entityId(s) of alarms
|
|
11
|
+
* 2. Use the entityId(s) to delete those alarms
|
|
12
|
+
*
|
|
13
|
+
* Supports deleting single or multiple alarms in one call.
|
|
14
|
+
*/
|
|
15
|
+
export const deleteAlarmTool = {
|
|
16
|
+
name: "delete_alarm",
|
|
17
|
+
label: "Delete Alarm",
|
|
18
|
+
description: `删除用户设备上的闹钟。使用前必须先调用 search_alarm 或 create_alarm 工具获取闹钟的 entityId。
|
|
19
|
+
|
|
20
|
+
工具参数:
|
|
21
|
+
- items: 要删除的闹钟列表,每个元素包含 entityId 字段。支持数组或 JSON 字符串格式。entityId 是闹钟的唯一标识符(从 search_alarm 或 create_alarm 工具获取)。
|
|
22
|
+
|
|
23
|
+
使用示例:
|
|
24
|
+
- 删除单个闹钟:{"items": [{"entityId": "6"}]}
|
|
25
|
+
- 删除多个闹钟:{"items": [{"entityId": "6"}, {"entityId": "8"}]}
|
|
26
|
+
|
|
27
|
+
注意事项:
|
|
28
|
+
1. 操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。
|
|
29
|
+
2. 删除操作不可撤销,请确认 entityId 正确后再删除。
|
|
30
|
+
3. items 参数支持数组或 JSON 字符串格式,代码会自动解析。`,
|
|
31
|
+
parameters: {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
items: {
|
|
35
|
+
// 不指定 type,允许传入数组或 JSON 字符串
|
|
36
|
+
// 具体的类型验证和转换在 execute 函数内部进行
|
|
37
|
+
description: "要删除的闹钟列表,每个元素包含 entityId 字段。支持数组或 JSON 字符串格式。",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
required: ["items"],
|
|
41
|
+
},
|
|
42
|
+
async execute(toolCallId, params) {
|
|
43
|
+
logger.log(`[DELETE_ALARM_TOOL] 🚀 Starting execution`);
|
|
44
|
+
logger.log(`[DELETE_ALARM_TOOL] - toolCallId: ${toolCallId}`);
|
|
45
|
+
logger.log(`[DELETE_ALARM_TOOL] - params (raw):`, JSON.stringify(params));
|
|
46
|
+
logger.log(`[DELETE_ALARM_TOOL] - params.items type:`, typeof params.items);
|
|
47
|
+
logger.log(`[DELETE_ALARM_TOOL] - timestamp: ${new Date().toISOString()}`);
|
|
48
|
+
// ===== 参数规范化:兼容数组和 JSON 字符串 =====
|
|
49
|
+
let items = null;
|
|
50
|
+
if (!params.items) {
|
|
51
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ Missing parameter: items`);
|
|
52
|
+
throw new Error("Missing required parameter: items");
|
|
53
|
+
}
|
|
54
|
+
// 情况1: 已经是数组
|
|
55
|
+
if (Array.isArray(params.items)) {
|
|
56
|
+
logger.log(`[DELETE_ALARM_TOOL] ✅ items is already an array`);
|
|
57
|
+
items = params.items;
|
|
58
|
+
}
|
|
59
|
+
// 情况2: 是字符串,尝试解析为 JSON 数组
|
|
60
|
+
else if (typeof params.items === 'string') {
|
|
61
|
+
logger.log(`[DELETE_ALARM_TOOL] 🔄 items is a string, attempting to parse as JSON...`);
|
|
62
|
+
try {
|
|
63
|
+
const parsed = JSON.parse(params.items);
|
|
64
|
+
if (Array.isArray(parsed)) {
|
|
65
|
+
logger.log(`[DELETE_ALARM_TOOL] ✅ Successfully parsed JSON string to array`);
|
|
66
|
+
items = parsed;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ Parsed JSON is not an array:`, typeof parsed);
|
|
70
|
+
throw new Error("items must be an array or a JSON string representing an array");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (parseError) {
|
|
74
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ Failed to parse items as JSON:`, parseError);
|
|
75
|
+
throw new Error(`items must be a valid JSON array string. Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// 情况3: 其他类型,报错
|
|
79
|
+
else {
|
|
80
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ Invalid items type:`, typeof params.items);
|
|
81
|
+
throw new Error(`items must be an array or a JSON string, got ${typeof params.items}`);
|
|
82
|
+
}
|
|
83
|
+
// 验证数组非空
|
|
84
|
+
if (!items || items.length === 0) {
|
|
85
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ items array is empty`);
|
|
86
|
+
throw new Error("items array cannot be empty");
|
|
87
|
+
}
|
|
88
|
+
logger.log(`[DELETE_ALARM_TOOL] ✅ Normalized items:`, JSON.stringify(items));
|
|
89
|
+
// 验证每个 item 是否有有效的 entityId
|
|
90
|
+
for (let i = 0; i < items.length; i++) {
|
|
91
|
+
const item = items[i];
|
|
92
|
+
if (!item || typeof item !== 'object') {
|
|
93
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ Item at index ${i} is not an object`);
|
|
94
|
+
throw new Error(`items[${i}] must be an object with entityId property`);
|
|
95
|
+
}
|
|
96
|
+
if (!item.entityId || typeof item.entityId !== 'string') {
|
|
97
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ Item at index ${i} missing or invalid entityId`);
|
|
98
|
+
throw new Error(`items[${i}] must have a valid entityId string property`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
logger.log(`[DELETE_ALARM_TOOL] - items count: ${items.length}`);
|
|
102
|
+
logger.log(`[DELETE_ALARM_TOOL] - entityIds:`, items.map(item => item.entityId).join(", "));
|
|
103
|
+
// Get session context
|
|
104
|
+
logger.log(`[DELETE_ALARM_TOOL] 🔍 Attempting to get session context...`);
|
|
105
|
+
const sessionContext = getCurrentSessionContext();
|
|
106
|
+
if (!sessionContext) {
|
|
107
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ FAILED: No active session found!`);
|
|
108
|
+
logger.error(`[DELETE_ALARM_TOOL] - toolCallId: ${toolCallId}`);
|
|
109
|
+
throw new Error("No active XY session found. Delete alarm tool can only be used during an active conversation.");
|
|
110
|
+
}
|
|
111
|
+
logger.log(`[DELETE_ALARM_TOOL] ✅ Session context found`);
|
|
112
|
+
logger.log(`[DELETE_ALARM_TOOL] - sessionId: ${sessionContext.sessionId}`);
|
|
113
|
+
logger.log(`[DELETE_ALARM_TOOL] - taskId: ${sessionContext.taskId}`);
|
|
114
|
+
logger.log(`[DELETE_ALARM_TOOL] - messageId: ${sessionContext.messageId}`);
|
|
115
|
+
const { config, sessionId, taskId, messageId } = sessionContext;
|
|
116
|
+
// Get WebSocket manager
|
|
117
|
+
logger.log(`[DELETE_ALARM_TOOL] 🔌 Getting WebSocket manager...`);
|
|
118
|
+
const wsManager = getXYWebSocketManager(config);
|
|
119
|
+
logger.log(`[DELETE_ALARM_TOOL] ✅ WebSocket manager obtained`);
|
|
120
|
+
// Build DeleteAlarm command
|
|
121
|
+
logger.log(`[DELETE_ALARM_TOOL] 📦 Building DeleteAlarm command...`);
|
|
122
|
+
const command = {
|
|
123
|
+
header: {
|
|
124
|
+
namespace: "Common",
|
|
125
|
+
name: "Action",
|
|
126
|
+
},
|
|
127
|
+
payload: {
|
|
128
|
+
cardParam: {},
|
|
129
|
+
executeParam: {
|
|
130
|
+
executeMode: "background",
|
|
131
|
+
intentName: "DeleteAlarm",
|
|
132
|
+
bundleName: "com.huawei.hmos.clock",
|
|
133
|
+
needUnlock: true,
|
|
134
|
+
actionResponse: true,
|
|
135
|
+
appType: "OHOS_APP",
|
|
136
|
+
timeOut: 5,
|
|
137
|
+
intentParam: {
|
|
138
|
+
items: items,
|
|
139
|
+
},
|
|
140
|
+
permissionId: [],
|
|
141
|
+
achieveType: "INTENT",
|
|
142
|
+
},
|
|
143
|
+
responses: [
|
|
144
|
+
{
|
|
145
|
+
resultCode: "",
|
|
146
|
+
displayText: "",
|
|
147
|
+
ttsText: "",
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
needUploadResult: true,
|
|
151
|
+
noHalfPage: false,
|
|
152
|
+
pageControlRelated: false,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
// Send command and wait for response (60 second timeout)
|
|
156
|
+
logger.log(`[DELETE_ALARM_TOOL] ⏳ Setting up promise to wait for alarm deletion response...`);
|
|
157
|
+
logger.log(`[DELETE_ALARM_TOOL] - Timeout: 60 seconds`);
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
const timeout = setTimeout(() => {
|
|
160
|
+
logger.error(`[DELETE_ALARM_TOOL] ⏰ Timeout: No response received within 60 seconds`);
|
|
161
|
+
wsManager.off("data-event", handler);
|
|
162
|
+
reject(new Error("删除闹钟超时(60秒)"));
|
|
163
|
+
}, 60000);
|
|
164
|
+
// Listen for data events from WebSocket
|
|
165
|
+
const handler = (event) => {
|
|
166
|
+
logger.log(`[DELETE_ALARM_TOOL] 📨 Received data event:`, JSON.stringify(event));
|
|
167
|
+
if (event.intentName === "DeleteAlarm") {
|
|
168
|
+
logger.log(`[DELETE_ALARM_TOOL] 🎯 DeleteAlarm event received`);
|
|
169
|
+
logger.log(`[DELETE_ALARM_TOOL] - status: ${event.status}`);
|
|
170
|
+
clearTimeout(timeout);
|
|
171
|
+
wsManager.off("data-event", handler);
|
|
172
|
+
if (event.status === "success" && event.outputs) {
|
|
173
|
+
logger.log(`[DELETE_ALARM_TOOL] ✅ Alarm deletion completed successfully`);
|
|
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
|
+
// Extract result with safe navigation
|
|
186
|
+
const result = event.outputs.result || {};
|
|
187
|
+
logger.log(`[DELETE_ALARM_TOOL] 📋 Deletion result:`, JSON.stringify(result));
|
|
188
|
+
// Build response with safe navigation
|
|
189
|
+
const response = {
|
|
190
|
+
success: true,
|
|
191
|
+
entityName: result.entityName || "Alarm",
|
|
192
|
+
message: result.message || "Alarm deleted successfully",
|
|
193
|
+
deletedCount: items.length,
|
|
194
|
+
};
|
|
195
|
+
// Add entityIds from request for reference
|
|
196
|
+
response.deletedIds = items.map(item => item.entityId);
|
|
197
|
+
logger.log(`[DELETE_ALARM_TOOL] 🎉 Successfully deleted ${items.length} alarm(s)`);
|
|
198
|
+
resolve({
|
|
199
|
+
content: [
|
|
200
|
+
{
|
|
201
|
+
type: "text",
|
|
202
|
+
text: JSON.stringify(response),
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ Alarm deletion failed`);
|
|
209
|
+
logger.error(`[DELETE_ALARM_TOOL] - status: ${event.status}`);
|
|
210
|
+
logger.error(`[DELETE_ALARM_TOOL] - outputs:`, JSON.stringify(event.outputs || {}));
|
|
211
|
+
reject(new Error(`删除闹钟失败: ${event.status}`));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
// Register event handler
|
|
216
|
+
logger.log(`[DELETE_ALARM_TOOL] 📡 Registering data-event handler on WebSocket manager`);
|
|
217
|
+
wsManager.on("data-event", handler);
|
|
218
|
+
// Send the command
|
|
219
|
+
logger.log(`[DELETE_ALARM_TOOL] 📤 Sending DeleteAlarm command...`);
|
|
220
|
+
sendCommand({
|
|
221
|
+
config,
|
|
222
|
+
sessionId,
|
|
223
|
+
taskId,
|
|
224
|
+
messageId,
|
|
225
|
+
command,
|
|
226
|
+
})
|
|
227
|
+
.then(() => {
|
|
228
|
+
logger.log(`[DELETE_ALARM_TOOL] ✅ Command sent successfully, waiting for response...`);
|
|
229
|
+
})
|
|
230
|
+
.catch((error) => {
|
|
231
|
+
logger.error(`[DELETE_ALARM_TOOL] ❌ Failed to send command:`, error);
|
|
232
|
+
clearTimeout(timeout);
|
|
233
|
+
wsManager.off("data-event", handler);
|
|
234
|
+
reject(error);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
},
|
|
238
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getXYWebSocketManager } from "../client.js";
|
|
2
2
|
import { sendCommand } from "../formatter.js";
|
|
3
|
-
import {
|
|
3
|
+
import { getCurrentSessionContext } from "./session-manager.js";
|
|
4
4
|
import { logger } from "../utils/logger.js";
|
|
5
5
|
/**
|
|
6
6
|
* XY location tool - gets user's current location.
|
|
@@ -22,7 +22,7 @@ export const locationTool = {
|
|
|
22
22
|
logger.log(`[LOCATION_TOOL] - timestamp: ${new Date().toISOString()}`);
|
|
23
23
|
// Get session context
|
|
24
24
|
logger.log(`[LOCATION_TOOL] 🔍 Attempting to get session context...`);
|
|
25
|
-
const sessionContext =
|
|
25
|
+
const sessionContext = getCurrentSessionContext();
|
|
26
26
|
if (!sessionContext) {
|
|
27
27
|
logger.error(`[LOCATION_TOOL] ❌ FAILED: No active session found!`);
|
|
28
28
|
logger.error(`[LOCATION_TOOL] - toolCallId: ${toolCallId}`);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XY modify alarm tool - modifies an existing alarm on user's device.
|
|
3
|
+
* Requires entityId from search_alarm or create_alarm tool.
|
|
4
|
+
*
|
|
5
|
+
* Prerequisites:
|
|
6
|
+
* 1. Call search_alarm or create_alarm tool first to get entityId
|
|
7
|
+
* 2. Use the entityId to identify which alarm to modify
|
|
8
|
+
*/
|
|
9
|
+
export declare const modifyAlarmTool: any;
|