@ynhcj/xiaoyi-channel 0.0.32-next → 0.0.33-next
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 -11
- package/dist/src/monitor.js +3 -0
- package/dist/src/reply-dispatcher.d.ts +4 -0
- package/dist/src/reply-dispatcher.js +12 -8
- package/package.json +1 -1
package/dist/src/bot.js
CHANGED
|
@@ -2,6 +2,7 @@ import { getXYRuntime } from "./runtime.js";
|
|
|
2
2
|
import { setCachedContext } from "./steer-injector.js";
|
|
3
3
|
import { createXYReplyDispatcher } from "./reply-dispatcher.js";
|
|
4
4
|
import { parseA2AMessage, extractTextFromParts, extractFileParts, extractPushId, extractTriggerData } from "./parser.js";
|
|
5
|
+
import { downloadFilesFromParts } from "./file-download.js";
|
|
5
6
|
import { resolveXYConfig } from "./config.js";
|
|
6
7
|
import { sendStatusUpdate, sendClearContextResponse, sendTasksCancelResponse, sendA2AResponse } from "./formatter.js";
|
|
7
8
|
import { registerSession, unregisterSession, runWithSessionContext } from "./tools/session-manager.js";
|
|
@@ -161,8 +162,9 @@ export async function handleXYMessage(params) {
|
|
|
161
162
|
// Extract text and files from parts
|
|
162
163
|
const text = extractTextFromParts(parsed.parts);
|
|
163
164
|
const fileParts = extractFileParts(parsed.parts);
|
|
164
|
-
//
|
|
165
|
-
const
|
|
165
|
+
// Download files to local disk
|
|
166
|
+
const downloadedFiles = await downloadFilesFromParts(fileParts);
|
|
167
|
+
const mediaPayload = buildXYMediaPayload(downloadedFiles);
|
|
166
168
|
// Resolve envelope format options (following feishu pattern)
|
|
167
169
|
const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg);
|
|
168
170
|
// Build message body with speaker prefix (following feishu pattern)
|
|
@@ -294,19 +296,19 @@ export async function handleXYMessage(params) {
|
|
|
294
296
|
}
|
|
295
297
|
}
|
|
296
298
|
/**
|
|
297
|
-
* Build media payload for inbound context
|
|
298
|
-
*
|
|
299
|
+
* Build media payload for inbound context.
|
|
300
|
+
* Following feishu pattern: buildFeishuMediaPayload().
|
|
299
301
|
*
|
|
300
|
-
* @param
|
|
302
|
+
* @param mediaList - Downloaded files with local paths
|
|
301
303
|
*/
|
|
302
|
-
function buildXYMediaPayload(
|
|
303
|
-
const first =
|
|
304
|
-
const
|
|
305
|
-
const mediaTypes =
|
|
304
|
+
function buildXYMediaPayload(mediaList) {
|
|
305
|
+
const first = mediaList[0];
|
|
306
|
+
const mediaPaths = mediaList.map((media) => media.path);
|
|
307
|
+
const mediaTypes = mediaList.map((media) => media.mimeType).filter(Boolean);
|
|
306
308
|
return {
|
|
307
|
-
|
|
309
|
+
MediaPath: first?.path,
|
|
308
310
|
MediaType: first?.mimeType,
|
|
309
|
-
|
|
311
|
+
MediaPaths: mediaPaths.length > 0 ? mediaPaths : undefined,
|
|
310
312
|
MediaTypes: mediaTypes.length > 0 ? mediaTypes : undefined,
|
|
311
313
|
};
|
|
312
314
|
}
|
package/dist/src/monitor.js
CHANGED
|
@@ -4,6 +4,7 @@ import { handleXYMessage } from "./bot.js";
|
|
|
4
4
|
import { parseA2AMessage } from "./parser.js";
|
|
5
5
|
import { hasActiveTask } from "./task-manager.js";
|
|
6
6
|
import { handleTriggerEvent } from "./trigger-handler.js";
|
|
7
|
+
import { cleanupStaleTempFiles } from "./reply-dispatcher.js";
|
|
7
8
|
/**
|
|
8
9
|
* Per-session serial queue that ensures messages from the same session are processed
|
|
9
10
|
* in arrival order while allowing different sessions to run concurrently.
|
|
@@ -211,6 +212,8 @@ export async function monitorXYProvider(opts = {}) {
|
|
|
211
212
|
if (cleaned > 0) {
|
|
212
213
|
console.log(`🧹 [HEALTH CHECK] Auto-cleaned ${cleaned} manager(s) with orphan connections`);
|
|
213
214
|
}
|
|
215
|
+
// Cleanup stale temp files (older than 24 hours)
|
|
216
|
+
void cleanupStaleTempFiles();
|
|
214
217
|
}, 6 * 60 * 60 * 1000); // 6 hours
|
|
215
218
|
// Connect to WebSocket servers
|
|
216
219
|
wsManager.connect()
|
|
@@ -8,6 +8,10 @@ export interface CreateXYReplyDispatcherParams {
|
|
|
8
8
|
accountId: string;
|
|
9
9
|
isSteerFollower?: boolean;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* 清理 /tmp/xy_channel 目录中超过 24 小时的旧文件
|
|
13
|
+
*/
|
|
14
|
+
export declare function cleanupStaleTempFiles(tempDir?: string): Promise<void>;
|
|
11
15
|
/**
|
|
12
16
|
* Create a reply dispatcher for XY channel messages.
|
|
13
17
|
* Follows feishu pattern with status updates and streaming support.
|
|
@@ -4,29 +4,34 @@ import { resolveXYConfig } from "./config.js";
|
|
|
4
4
|
import { getCurrentTaskId, getCurrentMessageId } from "./task-manager.js";
|
|
5
5
|
import fs from "fs/promises";
|
|
6
6
|
import path from "path";
|
|
7
|
+
const TEMP_FILE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
7
8
|
/**
|
|
8
|
-
* 清理 /tmp/xy_channel
|
|
9
|
+
* 清理 /tmp/xy_channel 目录中超过 24 小时的旧文件
|
|
9
10
|
*/
|
|
10
|
-
async function
|
|
11
|
+
export async function cleanupStaleTempFiles(tempDir = "/tmp/xy_channel") {
|
|
11
12
|
try {
|
|
12
13
|
const stats = await fs.stat(tempDir).catch(() => null);
|
|
13
14
|
if (!stats?.isDirectory()) {
|
|
14
|
-
return;
|
|
15
|
+
return;
|
|
15
16
|
}
|
|
16
17
|
const files = await fs.readdir(tempDir);
|
|
18
|
+
const now = Date.now();
|
|
17
19
|
let cleanedCount = 0;
|
|
18
20
|
for (const file of files) {
|
|
19
21
|
const filePath = path.join(tempDir, file);
|
|
20
22
|
try {
|
|
21
|
-
await fs.
|
|
22
|
-
|
|
23
|
+
const fileStat = await fs.stat(filePath);
|
|
24
|
+
if (now - fileStat.mtimeMs > TEMP_FILE_TTL_MS) {
|
|
25
|
+
await fs.unlink(filePath);
|
|
26
|
+
cleanedCount++;
|
|
27
|
+
}
|
|
23
28
|
}
|
|
24
29
|
catch (err) {
|
|
25
|
-
//
|
|
30
|
+
// 忽略单个文件处理失败
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
if (cleanedCount > 0) {
|
|
29
|
-
console.log(`[CLEANUP] 🧹 Cleaned ${cleanedCount} files from ${tempDir}`);
|
|
34
|
+
console.log(`[CLEANUP] 🧹 Cleaned ${cleanedCount} stale files (>${TEMP_FILE_TTL_MS / 1000 / 3600}h) from ${tempDir}`);
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
37
|
catch (err) {
|
|
@@ -239,7 +244,6 @@ export function createXYReplyDispatcher(params) {
|
|
|
239
244
|
}
|
|
240
245
|
}
|
|
241
246
|
stopStatusInterval();
|
|
242
|
-
void cleanupTempDir();
|
|
243
247
|
},
|
|
244
248
|
onCleanup: () => {
|
|
245
249
|
const currentTaskId = getActiveTaskId();
|