@ynhcj/xiaoyi-channel 0.0.13-beta → 0.0.14-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.
|
@@ -80,6 +80,17 @@ export const searchCalendarTool = {
|
|
|
80
80
|
const date = new Date(year, month, day, hours, minutes, seconds);
|
|
81
81
|
return date.getTime();
|
|
82
82
|
};
|
|
83
|
+
// Helper function to convert timestamp to YYYYMMDD hhmmss format
|
|
84
|
+
const formatTimestamp = (timestamp) => {
|
|
85
|
+
const date = new Date(timestamp);
|
|
86
|
+
const year = date.getFullYear();
|
|
87
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
88
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
89
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
90
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
91
|
+
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
92
|
+
return `${year}${month}${day} ${hours}${minutes}${seconds}`;
|
|
93
|
+
};
|
|
83
94
|
let startTimeMs;
|
|
84
95
|
let endTimeMs;
|
|
85
96
|
try {
|
|
@@ -190,6 +201,22 @@ export const searchCalendarTool = {
|
|
|
190
201
|
if (result === undefined) {
|
|
191
202
|
logger.warn(`[SEARCH_CALENDAR_TOOL] ⚠️ Result is undefined, returning empty result`);
|
|
192
203
|
}
|
|
204
|
+
// Convert dtStart and dtEnd from timestamps to YYYYMMDD hhmmss format
|
|
205
|
+
if (result && result.items && Array.isArray(result.items)) {
|
|
206
|
+
logger.log(`[SEARCH_CALENDAR_TOOL] 🔄 Converting timestamps to formatted dates...`);
|
|
207
|
+
result.items = result.items.map((item) => {
|
|
208
|
+
const formattedItem = { ...item };
|
|
209
|
+
if (item.dtStart) {
|
|
210
|
+
formattedItem.dtStart = formatTimestamp(item.dtStart);
|
|
211
|
+
logger.log(`[SEARCH_CALENDAR_TOOL] - dtStart: ${item.dtStart} -> ${formattedItem.dtStart}`);
|
|
212
|
+
}
|
|
213
|
+
if (item.dtEnd) {
|
|
214
|
+
formattedItem.dtEnd = formatTimestamp(item.dtEnd);
|
|
215
|
+
logger.log(`[SEARCH_CALENDAR_TOOL] - dtEnd: ${item.dtEnd} -> ${formattedItem.dtEnd}`);
|
|
216
|
+
}
|
|
217
|
+
return formattedItem;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
193
220
|
resolve({
|
|
194
221
|
content: [
|
|
195
222
|
{
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { getXYWebSocketManager } from "../client.js";
|
|
2
2
|
import { sendCommand } from "../formatter.js";
|
|
3
3
|
import { getLatestSessionContext } from "./session-manager.js";
|
|
4
|
-
import { logger } from "../utils/logger.js";
|
|
5
4
|
/**
|
|
6
5
|
* XY upload photo tool - uploads local photos to get publicly accessible URLs.
|
|
7
6
|
* Requires mediaUris from search_photo_gallery tool as prerequisite.
|
|
@@ -30,42 +29,42 @@ export const uploadPhotoTool = {
|
|
|
30
29
|
required: ["mediaUris"],
|
|
31
30
|
},
|
|
32
31
|
async execute(toolCallId, params) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 🚀 Starting execution`);
|
|
33
|
+
console.log(`[UPLOAD_PHOTO_TOOL] - toolCallId: ${toolCallId}`);
|
|
34
|
+
console.log(`[UPLOAD_PHOTO_TOOL] - params:`, JSON.stringify(params));
|
|
35
|
+
console.log(`[UPLOAD_PHOTO_TOOL] - timestamp: ${new Date().toISOString()}`);
|
|
37
36
|
// Validate parameters
|
|
38
37
|
if (!params.mediaUris || !Array.isArray(params.mediaUris) || params.mediaUris.length === 0) {
|
|
39
|
-
|
|
38
|
+
console.error(`[UPLOAD_PHOTO_TOOL] ❌ Missing or invalid parameter: mediaUris`);
|
|
40
39
|
throw new Error("Missing or invalid parameter: mediaUris must be a non-empty array");
|
|
41
40
|
}
|
|
42
41
|
// Validate maximum 5 URIs
|
|
43
42
|
if (params.mediaUris.length > 5) {
|
|
44
|
-
|
|
43
|
+
console.error(`[UPLOAD_PHOTO_TOOL] ❌ Too many mediaUris: ${params.mediaUris.length}`);
|
|
45
44
|
throw new Error(`最多支持 5 条 mediaUri,当前提供了 ${params.mediaUris.length} 条。请分批处理。`);
|
|
46
45
|
}
|
|
47
|
-
|
|
46
|
+
console.log(`[UPLOAD_PHOTO_TOOL] - mediaUris count: ${params.mediaUris.length}`);
|
|
48
47
|
// Get session context
|
|
49
|
-
|
|
48
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 🔍 Attempting to get session context...`);
|
|
50
49
|
const sessionContext = getLatestSessionContext();
|
|
51
50
|
if (!sessionContext) {
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
console.error(`[UPLOAD_PHOTO_TOOL] ❌ FAILED: No active session found!`);
|
|
52
|
+
console.error(`[UPLOAD_PHOTO_TOOL] - toolCallId: ${toolCallId}`);
|
|
54
53
|
throw new Error("No active XY session found. Upload photo tool can only be used during an active conversation.");
|
|
55
54
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
console.log(`[UPLOAD_PHOTO_TOOL] ✅ Session context found`);
|
|
56
|
+
console.log(`[UPLOAD_PHOTO_TOOL] - sessionId: ${sessionContext.sessionId}`);
|
|
57
|
+
console.log(`[UPLOAD_PHOTO_TOOL] - taskId: ${sessionContext.taskId}`);
|
|
58
|
+
console.log(`[UPLOAD_PHOTO_TOOL] - messageId: ${sessionContext.messageId}`);
|
|
60
59
|
const { config, sessionId, taskId, messageId } = sessionContext;
|
|
61
60
|
// Get WebSocket manager
|
|
62
|
-
|
|
61
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 🔌 Getting WebSocket manager...`);
|
|
63
62
|
const wsManager = getXYWebSocketManager(config);
|
|
64
|
-
|
|
63
|
+
console.log(`[UPLOAD_PHOTO_TOOL] ✅ WebSocket manager obtained`);
|
|
65
64
|
// Get public URLs for the photos
|
|
66
|
-
|
|
65
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 🌐 Getting public URLs for photos...`);
|
|
67
66
|
const imageUrls = await getPhotoUrls(wsManager, config, sessionId, taskId, messageId, params.mediaUris);
|
|
68
|
-
|
|
67
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 🎉 Successfully retrieved ${imageUrls.length} photo URLs`);
|
|
69
68
|
return {
|
|
70
69
|
content: [
|
|
71
70
|
{
|
|
@@ -85,7 +84,7 @@ export const uploadPhotoTool = {
|
|
|
85
84
|
* Returns array of publicly accessible image URLs
|
|
86
85
|
*/
|
|
87
86
|
async function getPhotoUrls(wsManager, config, sessionId, taskId, messageId, mediaUris) {
|
|
88
|
-
|
|
87
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 📦 Building ImageUploadForClaw command...`);
|
|
89
88
|
// Build imageInfos array from mediaUris
|
|
90
89
|
const imageInfos = mediaUris.map(mediaUri => ({ mediaUri }));
|
|
91
90
|
const command = {
|
|
@@ -123,19 +122,19 @@ async function getPhotoUrls(wsManager, config, sessionId, taskId, messageId, med
|
|
|
123
122
|
};
|
|
124
123
|
return new Promise((resolve, reject) => {
|
|
125
124
|
const timeout = setTimeout(() => {
|
|
126
|
-
|
|
125
|
+
console.error(`[UPLOAD_PHOTO_TOOL] ⏰ Timeout: No response for ImageUploadForClaw within 60 seconds`);
|
|
127
126
|
wsManager.off("data-event", handler);
|
|
128
127
|
reject(new Error("获取照片URL超时(60秒)"));
|
|
129
128
|
}, 60000);
|
|
130
129
|
const handler = (event) => {
|
|
131
|
-
|
|
130
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 📨 Received data event:`, JSON.stringify(event));
|
|
132
131
|
if (event.intentName === "ImageUploadForClaw") {
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 🎯 ImageUploadForClaw event received`);
|
|
133
|
+
console.log(`[UPLOAD_PHOTO_TOOL] - status: ${event.status}`);
|
|
135
134
|
clearTimeout(timeout);
|
|
136
135
|
wsManager.off("data-event", handler);
|
|
137
136
|
if (event.status === "success" && event.outputs) {
|
|
138
|
-
|
|
137
|
+
console.log(`[UPLOAD_PHOTO_TOOL] ✅ Image URL retrieval completed successfully`);
|
|
139
138
|
const result = event.outputs.result;
|
|
140
139
|
let imageUrls = result?.imageUrls || [];
|
|
141
140
|
// Decode Unicode escape sequences in URLs
|
|
@@ -144,22 +143,22 @@ async function getPhotoUrls(wsManager, config, sessionId, taskId, messageId, med
|
|
|
144
143
|
const decodedUrl = url
|
|
145
144
|
.replace(/\\u003d/g, '=')
|
|
146
145
|
.replace(/\\u0026/g, '&');
|
|
147
|
-
|
|
146
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 🔄 Decoded URL: ${url} -> ${decodedUrl}`);
|
|
148
147
|
return decodedUrl;
|
|
149
148
|
});
|
|
150
|
-
|
|
149
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 📊 Retrieved and decoded ${imageUrls.length} image URLs`);
|
|
151
150
|
resolve(imageUrls);
|
|
152
151
|
}
|
|
153
152
|
else {
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
console.error(`[UPLOAD_PHOTO_TOOL] ❌ Image URL retrieval failed`);
|
|
154
|
+
console.error(`[UPLOAD_PHOTO_TOOL] - status: ${event.status}`);
|
|
156
155
|
reject(new Error(`获取照片URL失败: ${event.status}`));
|
|
157
156
|
}
|
|
158
157
|
}
|
|
159
158
|
};
|
|
160
|
-
|
|
159
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 📡 Registering data-event handler for ImageUploadForClaw`);
|
|
161
160
|
wsManager.on("data-event", handler);
|
|
162
|
-
|
|
161
|
+
console.log(`[UPLOAD_PHOTO_TOOL] 📤 Sending ImageUploadForClaw command...`);
|
|
163
162
|
sendCommand({
|
|
164
163
|
config,
|
|
165
164
|
sessionId,
|
|
@@ -168,10 +167,10 @@ async function getPhotoUrls(wsManager, config, sessionId, taskId, messageId, med
|
|
|
168
167
|
command,
|
|
169
168
|
})
|
|
170
169
|
.then(() => {
|
|
171
|
-
|
|
170
|
+
console.log(`[UPLOAD_PHOTO_TOOL] ✅ ImageUploadForClaw command sent successfully`);
|
|
172
171
|
})
|
|
173
172
|
.catch((error) => {
|
|
174
|
-
|
|
173
|
+
console.error(`[UPLOAD_PHOTO_TOOL] ❌ Failed to send ImageUploadForClaw command:`, error);
|
|
175
174
|
clearTimeout(timeout);
|
|
176
175
|
wsManager.off("data-event", handler);
|
|
177
176
|
reject(error);
|