@ynhcj/xiaoyi-channel 0.0.55-beta → 0.0.56-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/push.d.ts +0 -1
- package/dist/src/push.js +1 -2
- package/dist/src/tools/create-alarm-tool.js +3 -7
- package/dist/src/tools/image-reading-tool.js +3 -3
- package/dist/src/tools/modify-alarm-tool.js +3 -7
- package/dist/src/tools/timestamp-to-utc8-tool.d.ts +12 -0
- package/dist/src/tools/timestamp-to-utc8-tool.js +104 -0
- package/package.json +1 -1
package/dist/src/channel.js
CHANGED
|
@@ -21,9 +21,9 @@ import { searchAlarmTool } from "./tools/search-alarm-tool.js";
|
|
|
21
21
|
import { modifyAlarmTool } from "./tools/modify-alarm-tool.js";
|
|
22
22
|
import { deleteAlarmTool } from "./tools/delete-alarm-tool.js";
|
|
23
23
|
import { sendFileToUserTool } from "./tools/send-file-to-user-tool.js";
|
|
24
|
-
import { xiaoyiCollectionTool } from "./tools/xiaoyi-collection-tool.js";
|
|
25
24
|
import { viewPushResultTool } from "./tools/view-push-result-tool.js";
|
|
26
25
|
import { imageReadingTool } from "./tools/image-reading-tool.js";
|
|
26
|
+
import { timestampToUtc8Tool } from "./tools/timestamp-to-utc8-tool.js";
|
|
27
27
|
/**
|
|
28
28
|
* Xiaoyi Channel Plugin for OpenClaw.
|
|
29
29
|
* Implements Xiaoyi A2A protocol with dual WebSocket connections.
|
|
@@ -62,7 +62,7 @@ export const xyPlugin = {
|
|
|
62
62
|
schema: xyConfigSchema,
|
|
63
63
|
},
|
|
64
64
|
outbound: xyOutbound,
|
|
65
|
-
agentTools: [locationTool, noteTool, searchNoteTool, modifyNoteTool, calendarTool, searchCalendarTool, searchContactTool, searchPhotoGalleryTool, uploadPhotoTool, xiaoyiGuiTool,
|
|
65
|
+
agentTools: [locationTool, noteTool, searchNoteTool, modifyNoteTool, calendarTool, searchCalendarTool, searchContactTool, searchPhotoGalleryTool, uploadPhotoTool, xiaoyiGuiTool, callPhoneTool, searchMessageTool, sendMessageTool, searchFileTool, uploadFileTool, createAlarmTool, searchAlarmTool, modifyAlarmTool, deleteAlarmTool, sendFileToUserTool, viewPushResultTool, imageReadingTool, timestampToUtc8Tool],
|
|
66
66
|
messaging: {
|
|
67
67
|
normalizeTarget: (raw) => {
|
|
68
68
|
const trimmed = raw.trim();
|
package/dist/src/push.d.ts
CHANGED
package/dist/src/push.js
CHANGED
|
@@ -7,7 +7,6 @@ import { randomUUID } from "crypto";
|
|
|
7
7
|
*/
|
|
8
8
|
export class XYPushService {
|
|
9
9
|
config;
|
|
10
|
-
DEFAULT_PUSH_URL = "https://hag.cloud.huawei.com/open-ability-agent/v1/agent-webhook";
|
|
11
10
|
REQUEST_FROM = "openclaw";
|
|
12
11
|
constructor(config) {
|
|
13
12
|
this.config = config;
|
|
@@ -29,7 +28,7 @@ export class XYPushService {
|
|
|
29
28
|
* @param pushId - Push ID to use (required)
|
|
30
29
|
*/
|
|
31
30
|
async sendPush(content, title, data, sessionId, pushDataId, pushId) {
|
|
32
|
-
const pushUrl = this.config.
|
|
31
|
+
const pushUrl = `${this.config.fileUploadUrl}/open-ability-agent/v1/agent-webhook`;
|
|
33
32
|
const traceId = this.generateTraceId();
|
|
34
33
|
// Use provided pushId or fall back to config pushId
|
|
35
34
|
const actualPushId = pushId || this.config.pushId;
|
|
@@ -6,7 +6,7 @@ const ALARM_SNOOZE_DURATION_VALUES = [5, 10, 15, 20, 25, 30];
|
|
|
6
6
|
const ALARM_SNOOZE_TOTAL_VALUES = [0, 1, 3, 5, 10];
|
|
7
7
|
const ALARM_RING_DURATION_VALUES = [1, 5, 10, 15, 20, 30];
|
|
8
8
|
const DAYS_OF_WAKE_TYPE_VALUES = [0, 1, 2, 3, 4];
|
|
9
|
-
const DAYS_OF_WEEK_VALUES = ["Mon", "
|
|
9
|
+
const DAYS_OF_WEEK_VALUES = ["Mon", "Tues", "Wed", "Thur", "Fri", "Sat", "Sun"];
|
|
10
10
|
/**
|
|
11
11
|
* XY create alarm tool - creates an alarm on user's device.
|
|
12
12
|
* Requires alarmTime parameter. Other parameters are optional with sensible defaults.
|
|
@@ -27,7 +27,7 @@ export const createAlarmTool = {
|
|
|
27
27
|
- alarmSnoozeTotal: 再响次数,枚举值:0,1,3,5,10,默认0(表示不再响)
|
|
28
28
|
- alarmRingDuration: 响铃时长(分钟),枚举值:1,5,10,15,20,30,默认5
|
|
29
29
|
- daysOfWakeType: 闹钟响铃类型,枚举值:0=单次响铃,1=法定节假日,2=每天,3=自定义时间,4=法定工作日,默认0
|
|
30
|
-
- daysOfWeek: 自定义响铃星期,仅当daysOfWakeType=3(自定义时间)时必需且有效,其他情况不要传递此参数。数组或JSON字符串,枚举值:Mon,
|
|
30
|
+
- daysOfWeek: 自定义响铃星期,仅当daysOfWakeType=3(自定义时间)时必需且有效,其他情况不要传递此参数。数组或JSON字符串,枚举值:Mon,Tues,Wed,Thur,Fri,Sat,Sun。
|
|
31
31
|
|
|
32
32
|
注意事项:
|
|
33
33
|
a. 操作超时时间为60秒,请勿重复调用此工具,如果超时或失败,最多重试一次。
|
|
@@ -64,7 +64,7 @@ b. 使用该工具之前需获取当前真实时间
|
|
|
64
64
|
daysOfWeek: {
|
|
65
65
|
// 不指定 type,允许传入数组或 JSON 字符串
|
|
66
66
|
// 具体的类型验证和转换在 execute 函数内部进行
|
|
67
|
-
description: "自定义响铃星期(仅当daysOfWakeType=3时需要,其他情况不要传递),数组或JSON字符串,枚举值:Mon,
|
|
67
|
+
description: "自定义响铃星期(仅当daysOfWakeType=3时需要,其他情况不要传递),数组或JSON字符串,枚举值:Mon,Tues,Wed,Thur,Fri,Sat,Sun。",
|
|
68
68
|
},
|
|
69
69
|
},
|
|
70
70
|
required: ["alarmTime"],
|
|
@@ -163,10 +163,6 @@ b. 使用该工具之前需获取当前真实时间
|
|
|
163
163
|
if (!normalizedDaysOfWeek || normalizedDaysOfWeek.length === 0) {
|
|
164
164
|
throw new Error("daysOfWeek array cannot be empty");
|
|
165
165
|
}
|
|
166
|
-
// 验证数组长度必须为1
|
|
167
|
-
if (normalizedDaysOfWeek.length !== 1) {
|
|
168
|
-
throw new Error("daysOfWeek 仅支持长度为1的数组。如果需要一周中不同的几天,需要多次调用此工具");
|
|
169
|
-
}
|
|
170
166
|
// Validate each day
|
|
171
167
|
for (const day of normalizedDaysOfWeek) {
|
|
172
168
|
if (typeof day !== "string" || !DAYS_OF_WEEK_VALUES.includes(day)) {
|
|
@@ -87,8 +87,8 @@ async function processImageInput(imageInput, uploadService) {
|
|
|
87
87
|
/**
|
|
88
88
|
* Call image understanding API with streaming response
|
|
89
89
|
*/
|
|
90
|
-
async function callImageUnderstandingAPI(imageUrl, text, apiKey, uid) {
|
|
91
|
-
const apiUrl =
|
|
90
|
+
async function callImageUnderstandingAPI(imageUrl, text, apiKey, uid, fileUploadUrl) {
|
|
91
|
+
const apiUrl = `${fileUploadUrl}/celia-claw/v1/sse-api/skill/execute`;
|
|
92
92
|
const traceId = uuidv4();
|
|
93
93
|
const headers = {
|
|
94
94
|
"Content-Type": "application/json",
|
|
@@ -276,7 +276,7 @@ d. 返回图像理解的文本描述内容`,
|
|
|
276
276
|
downloadedFile = processedImage.localPath;
|
|
277
277
|
}
|
|
278
278
|
// Call image understanding API
|
|
279
|
-
const caption = await callImageUnderstandingAPI(processedImage.imageUrl, prompt, config.apiKey, config.uid);
|
|
279
|
+
const caption = await callImageUnderstandingAPI(processedImage.imageUrl, prompt, config.apiKey, config.uid, config.fileUploadUrl);
|
|
280
280
|
// Clean up downloaded file if any
|
|
281
281
|
if (downloadedFile) {
|
|
282
282
|
try {
|
|
@@ -6,7 +6,7 @@ const ALARM_SNOOZE_DURATION_VALUES = [5, 10, 15, 20, 25, 30];
|
|
|
6
6
|
const ALARM_SNOOZE_TOTAL_VALUES = [0, 1, 3, 5, 10];
|
|
7
7
|
const ALARM_RING_DURATION_VALUES = [1, 5, 10, 15, 20, 30];
|
|
8
8
|
const DAYS_OF_WAKE_TYPE_VALUES = [0, 1, 2, 3, 4];
|
|
9
|
-
const DAYS_OF_WEEK_VALUES = ["Mon", "
|
|
9
|
+
const DAYS_OF_WEEK_VALUES = ["Mon", "Tues", "Wed", "Thur", "Fri", "Sat", "Sun"];
|
|
10
10
|
/**
|
|
11
11
|
* XY modify alarm tool - modifies an existing alarm on user's device.
|
|
12
12
|
* Requires entityId from search_alarm or create_alarm tool.
|
|
@@ -31,7 +31,7 @@ export const modifyAlarmTool = {
|
|
|
31
31
|
- alarmSnoozeTotal: 再响次数,枚举值:0,1,3,5,10
|
|
32
32
|
- alarmRingDuration: 响铃时长(分钟),枚举值:1,5,10,15,20,30
|
|
33
33
|
- daysOfWakeType: 闹钟响铃类型,枚举值:0=单次,1=法定节假日,2=每天,3=自定义,4=法定工作日
|
|
34
|
-
- daysOfWeek: 自定义响铃星期,仅当daysOfWakeType=3(自定义时间)时必需且有效,其他情况不要传递此参数。数组或JSON字符串,枚举值:Mon,
|
|
34
|
+
- daysOfWeek: 自定义响铃星期,仅当daysOfWakeType=3(自定义时间)时必需且有效,其他情况不要传递此参数。数组或JSON字符串,枚举值:Mon,Tues,Wed,Thur,Fri,Sat,Sun。
|
|
35
35
|
|
|
36
36
|
使用流程:
|
|
37
37
|
1. 先调用 search_alarm 工具查询闹钟,获取 entityId,
|
|
@@ -79,7 +79,7 @@ export const modifyAlarmTool = {
|
|
|
79
79
|
daysOfWeek: {
|
|
80
80
|
// 不指定 type,允许传入数组或 JSON 字符串
|
|
81
81
|
// 具体的类型验证和转换在 execute 函数内部进行
|
|
82
|
-
description: "自定义响铃星期(仅当daysOfWakeType=3时需要,其他情况不要传递),数组或JSON字符串,枚举值:Mon,
|
|
82
|
+
description: "自定义响铃星期(仅当daysOfWakeType=3时需要,其他情况不要传递),数组或JSON字符串,枚举值:Mon,Tues,Wed,Thur,Fri,Sat,Sun。",
|
|
83
83
|
},
|
|
84
84
|
},
|
|
85
85
|
required: ["entityId"],
|
|
@@ -199,10 +199,6 @@ export const modifyAlarmTool = {
|
|
|
199
199
|
if (!normalizedDaysOfWeek || normalizedDaysOfWeek.length === 0) {
|
|
200
200
|
throw new Error("daysOfWeek array cannot be empty");
|
|
201
201
|
}
|
|
202
|
-
// 验证数组长度必须为1
|
|
203
|
-
if (normalizedDaysOfWeek.length !== 1) {
|
|
204
|
-
throw new Error("daysOfWeek 仅支持长度为1的数组。如果需要一周中不同的几天,需要多次调用此工具");
|
|
205
|
-
}
|
|
206
202
|
// Validate each day
|
|
207
203
|
for (const day of normalizedDaysOfWeek) {
|
|
208
204
|
if (typeof day !== "string" || !DAYS_OF_WEEK_VALUES.includes(day)) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XY timestamp to UTC+8 time tool - converts timestamp to UTC+8 time format.
|
|
3
|
+
* Supports both second-level and millisecond-level timestamps.
|
|
4
|
+
*
|
|
5
|
+
* This is a utility tool that doesn't require device communication.
|
|
6
|
+
* It converts Unix timestamp to UTC+8 time in YYYYMMDD hhmmss format.
|
|
7
|
+
*
|
|
8
|
+
* Important: The search_calendar_event and search_alarm tools return timestamps.
|
|
9
|
+
* Call this tool first to convert timestamps to readable UTC+8 time format before
|
|
10
|
+
* presenting results to users or performing further operations.
|
|
11
|
+
*/
|
|
12
|
+
export declare const timestampToUtc8Tool: any;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XY timestamp to UTC+8 time tool - converts timestamp to UTC+8 time format.
|
|
3
|
+
* Supports both second-level and millisecond-level timestamps.
|
|
4
|
+
*
|
|
5
|
+
* This is a utility tool that doesn't require device communication.
|
|
6
|
+
* It converts Unix timestamp to UTC+8 time in YYYYMMDD hhmmss format.
|
|
7
|
+
*
|
|
8
|
+
* Important: The search_calendar_event and search_alarm tools return timestamps.
|
|
9
|
+
* Call this tool first to convert timestamps to readable UTC+8 time format before
|
|
10
|
+
* presenting results to users or performing further operations.
|
|
11
|
+
*/
|
|
12
|
+
export const timestampToUtc8Tool = {
|
|
13
|
+
name: "convert_timestamp_to_utc8_time",
|
|
14
|
+
label: "Convert Timestamp to UTC+8 Time",
|
|
15
|
+
description: `将时间戳转换为标准 UTC+8 时间格式。支持秒级时间戳和毫秒级时间戳。
|
|
16
|
+
|
|
17
|
+
输入参数:
|
|
18
|
+
- timestamp: 时间戳(数字类型),可以是秒级(10位)或毫秒级(13位)
|
|
19
|
+
|
|
20
|
+
输出格式:
|
|
21
|
+
- YYYYMMDD hhmmss(例如:20240315 143000 表示 2024年3月15日 14:30:00 北京时间)
|
|
22
|
+
|
|
23
|
+
重要说明:
|
|
24
|
+
搜索日程工具(search_calendar_event)和搜索闹钟工具(search_alarm)等工具中返回结果如果包含时间戳。
|
|
25
|
+
建议优先调用本时间戳转换工具,将时间戳转换为标准北京时间格式,再基于标准时间进行用户回答或下一步操作。
|
|
26
|
+
|
|
27
|
+
示例:
|
|
28
|
+
- 输入:1710498600(秒级)或 1710498600000(毫秒级)
|
|
29
|
+
- 输出:20240315 143000`,
|
|
30
|
+
parameters: {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
timestamp: {
|
|
34
|
+
type: "number",
|
|
35
|
+
description: "时间戳,支持秒级(10位)或毫秒级(13位)时间戳",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
required: ["timestamp"],
|
|
39
|
+
},
|
|
40
|
+
async execute(toolCallId, params) {
|
|
41
|
+
// Validate timestamp parameter
|
|
42
|
+
if (params.timestamp === undefined || params.timestamp === null) {
|
|
43
|
+
throw new Error("缺少必需参数:timestamp");
|
|
44
|
+
}
|
|
45
|
+
const timestamp = params.timestamp;
|
|
46
|
+
// Validate it's a number
|
|
47
|
+
if (typeof timestamp !== "number") {
|
|
48
|
+
throw new Error("timestamp 必须是数字类型");
|
|
49
|
+
}
|
|
50
|
+
// Check if timestamp is valid
|
|
51
|
+
if (isNaN(timestamp)) {
|
|
52
|
+
throw new Error("timestamp 不是有效数字");
|
|
53
|
+
}
|
|
54
|
+
// Determine if it's seconds or milliseconds
|
|
55
|
+
// Millisecond timestamps are typically 13 digits (year 2024+)
|
|
56
|
+
// Second timestamps are typically 10 digits
|
|
57
|
+
let timestampInMs;
|
|
58
|
+
const timestampStr = Math.abs(timestamp).toString();
|
|
59
|
+
if (timestampStr.length === 13) {
|
|
60
|
+
// It's already in milliseconds
|
|
61
|
+
timestampInMs = timestamp;
|
|
62
|
+
}
|
|
63
|
+
else if (timestampStr.length === 10) {
|
|
64
|
+
// It's in seconds, convert to milliseconds
|
|
65
|
+
timestampInMs = timestamp * 1000;
|
|
66
|
+
}
|
|
67
|
+
else if (timestamp > 1000000000000) {
|
|
68
|
+
// Likely milliseconds (greater than year 2001 in milliseconds)
|
|
69
|
+
timestampInMs = timestamp;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Likely seconds, convert to milliseconds
|
|
73
|
+
timestampInMs = timestamp * 1000;
|
|
74
|
+
}
|
|
75
|
+
// Create Date object from timestamp
|
|
76
|
+
const date = new Date(timestampInMs);
|
|
77
|
+
// Check if date is valid
|
|
78
|
+
if (isNaN(date.getTime())) {
|
|
79
|
+
throw new Error("无效的时间戳,无法转换为日期");
|
|
80
|
+
}
|
|
81
|
+
// Convert to Beijing time (UTC+8)
|
|
82
|
+
const beijingTime = new Date(date.getTime() + (8 * 60 * 60 * 1000));
|
|
83
|
+
// Format: YYYYMMDD hhmmss
|
|
84
|
+
const year = beijingTime.getUTCFullYear();
|
|
85
|
+
const month = beijingTime.getUTCMonth() + 1; // Months are 0-indexed
|
|
86
|
+
const day = beijingTime.getUTCDate();
|
|
87
|
+
const hours = beijingTime.getUTCHours();
|
|
88
|
+
const minutes = beijingTime.getUTCMinutes();
|
|
89
|
+
const seconds = beijingTime.getUTCSeconds();
|
|
90
|
+
// Pad with leading zeros
|
|
91
|
+
const formattedDate = `${year}${String(month).padStart(2, '0')}${String(day).padStart(2, '0')}`;
|
|
92
|
+
const formattedTime = `${String(hours).padStart(2, '0')}${String(minutes).padStart(2, '0')}${String(seconds).padStart(2, '0')}`;
|
|
93
|
+
const result = `${formattedDate} ${formattedTime}`;
|
|
94
|
+
// Return the formatted time
|
|
95
|
+
return {
|
|
96
|
+
content: [
|
|
97
|
+
{
|
|
98
|
+
type: "text",
|
|
99
|
+
text: result,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
};
|