@aiscene/aiserver 1.9.8 → 1.9.9
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/api/callback.d.ts +3 -0
- package/dist/api/callback.d.ts.map +1 -1
- package/dist/api/callback.js +48 -1
- package/dist/api/callback.js.map +1 -1
- package/dist/config/cli.d.ts +2 -0
- package/dist/config/cli.d.ts.map +1 -1
- package/dist/config/cli.js +10 -0
- package/dist/config/cli.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +8 -4
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +1 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/core/types.d.ts +5 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/debug/websocket-server.d.ts +4 -0
- package/dist/debug/websocket-server.d.ts.map +1 -1
- package/dist/debug/websocket-server.js +66 -13
- package/dist/debug/websocket-server.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/task/scheduler.d.ts.map +1 -1
- package/dist/task/scheduler.js +5 -1
- package/dist/task/scheduler.js.map +1 -1
- package/dist/web/server.d.ts +1 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +16 -2
- package/dist/web/server.js.map +1 -1
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@ import { fork } from 'child_process';
|
|
|
3
3
|
import { URL } from 'url';
|
|
4
4
|
import os from 'os';
|
|
5
5
|
import { randomUUID } from 'crypto';
|
|
6
|
-
import { uploadReportToServer, uploadCapturePackageFile } from '../api/callback.js';
|
|
6
|
+
import { saveCaptureDataToDatabase, uploadReportToServer, uploadCapturePackageFile } from '../api/callback.js';
|
|
7
7
|
import fs from 'fs';
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import { createLogger } from '../core/logger.js';
|
|
@@ -492,6 +492,46 @@ export class DebugWebSocketServer {
|
|
|
492
492
|
code: resolvedCode || actionParams.code,
|
|
493
493
|
};
|
|
494
494
|
}
|
|
495
|
+
pickNonEmptyString(...values) {
|
|
496
|
+
for (const value of values) {
|
|
497
|
+
if (typeof value === 'string' && value.trim())
|
|
498
|
+
return value.trim();
|
|
499
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
500
|
+
return String(value);
|
|
501
|
+
}
|
|
502
|
+
return undefined;
|
|
503
|
+
}
|
|
504
|
+
buildCaptureDataPersistenceMeta(fallbackBatchId, ...sources) {
|
|
505
|
+
let batchId;
|
|
506
|
+
let creator;
|
|
507
|
+
for (const source of sources) {
|
|
508
|
+
if (!source || typeof source !== 'object')
|
|
509
|
+
continue;
|
|
510
|
+
const data = source;
|
|
511
|
+
batchId = batchId || this.pickNonEmptyString(data.batchId, data.batch_id, data.executionBatchId);
|
|
512
|
+
creator = creator || this.pickNonEmptyString(data.creator, data.erp, data.ownerErp, data.ownerERP, data.userErp, data.username, data.userName, data.proxyAccount);
|
|
513
|
+
}
|
|
514
|
+
return {
|
|
515
|
+
batchId: batchId || fallbackBatchId,
|
|
516
|
+
creator: creator || '',
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
rememberCaptureDataPersistenceMeta(sessionId, meta) {
|
|
520
|
+
const session = sessionManager.get(sessionId);
|
|
521
|
+
if (!session)
|
|
522
|
+
return;
|
|
523
|
+
session.captureDataPersistence = {
|
|
524
|
+
...session.captureDataPersistence,
|
|
525
|
+
...meta,
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
getCaptureDataPersistenceMeta(sessionId) {
|
|
529
|
+
const session = sessionManager.get(sessionId);
|
|
530
|
+
return {
|
|
531
|
+
batchId: session?.captureDataPersistence?.batchId || sessionId,
|
|
532
|
+
creator: session?.captureDataPersistence?.creator || '',
|
|
533
|
+
};
|
|
534
|
+
}
|
|
495
535
|
async handleStartDebug(ws, request) {
|
|
496
536
|
// Web 分支:支持 sessionId 复用 + 主进程内嵌执行 + 投屏
|
|
497
537
|
if (request.platform === 'web') {
|
|
@@ -501,6 +541,7 @@ export class DebugWebSocketServer {
|
|
|
501
541
|
// 真机分支:保持原有 fork worker 逻辑
|
|
502
542
|
const sessionId = `debug-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
503
543
|
const session = sessionManager.create(sessionId, ws, request.deviceId);
|
|
544
|
+
this.rememberCaptureDataPersistenceMeta(sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
504
545
|
this.sendMessage(ws, { type: 'session_created', sessionId }, request.deviceId);
|
|
505
546
|
try {
|
|
506
547
|
request.naturalLanguage = await this.resolveScriptReferences(request.naturalLanguage) || request.naturalLanguage;
|
|
@@ -557,6 +598,7 @@ export class DebugWebSocketServer {
|
|
|
557
598
|
// 复用:更新 client 引用为最新的 ws(旧 ws 可能已断)
|
|
558
599
|
session.client = ws;
|
|
559
600
|
}
|
|
601
|
+
this.rememberCaptureDataPersistenceMeta(sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
560
602
|
// 复用时校验浏览器形态参数是否一致:mobileMode/deviceName 在 launch 阶段决定,无法热切
|
|
561
603
|
if (isReuse) {
|
|
562
604
|
const incomingMobile = !!request.mobileMode;
|
|
@@ -925,7 +967,7 @@ export class DebugWebSocketServer {
|
|
|
925
967
|
logger.info('[Debug] Captured ' + capturedRequests.length + ' requests during debug session');
|
|
926
968
|
// 将抓包数据保存到文件并上传到 OSS
|
|
927
969
|
try {
|
|
928
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId);
|
|
970
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
929
971
|
if (uploadResult) {
|
|
930
972
|
captureDataUrl = uploadResult;
|
|
931
973
|
logger.info('[Debug] Capture data uploaded: ' + captureDataUrl);
|
|
@@ -1069,7 +1111,7 @@ export class DebugWebSocketServer {
|
|
|
1069
1111
|
let workerCaptureDataUrl;
|
|
1070
1112
|
if (workerCapturedRequests.length > 0) {
|
|
1071
1113
|
try {
|
|
1072
|
-
const uploadResult = await this.saveAndUploadCaptureData(workerCapturedRequests, sessionId);
|
|
1114
|
+
const uploadResult = await this.saveAndUploadCaptureData(workerCapturedRequests, sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
1073
1115
|
if (uploadResult) {
|
|
1074
1116
|
workerCaptureDataUrl = uploadResult;
|
|
1075
1117
|
logger.info('[Debug-Worker] Capture data uploaded: ' + workerCaptureDataUrl);
|
|
@@ -1127,6 +1169,7 @@ export class DebugWebSocketServer {
|
|
|
1127
1169
|
async handleExecuteAction(ws, request) {
|
|
1128
1170
|
const sessionId = `action-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1129
1171
|
const session = sessionManager.create(sessionId, ws, request.deviceId);
|
|
1172
|
+
this.rememberCaptureDataPersistenceMeta(sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
1130
1173
|
const abortController = new AbortController();
|
|
1131
1174
|
session.abortController = abortController;
|
|
1132
1175
|
// 调试日志:打印收到的模型配置
|
|
@@ -1226,7 +1269,7 @@ export class DebugWebSocketServer {
|
|
|
1226
1269
|
if (capturedRequests.length > 0) {
|
|
1227
1270
|
logger.info('[Action] Captured ' + capturedRequests.length + ' requests during session');
|
|
1228
1271
|
try {
|
|
1229
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId);
|
|
1272
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
1230
1273
|
if (uploadResult) {
|
|
1231
1274
|
captureDataUrl = uploadResult;
|
|
1232
1275
|
logger.info('[Action] Capture data uploaded: ' + captureDataUrl);
|
|
@@ -1285,7 +1328,7 @@ export class DebugWebSocketServer {
|
|
|
1285
1328
|
if (capturedRequests.length > 0) {
|
|
1286
1329
|
logger.info('[Action] Captured ' + capturedRequests.length + ' requests (error path)');
|
|
1287
1330
|
try {
|
|
1288
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId);
|
|
1331
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
1289
1332
|
if (uploadResult)
|
|
1290
1333
|
captureDataUrl = uploadResult;
|
|
1291
1334
|
}
|
|
@@ -1332,6 +1375,7 @@ export class DebugWebSocketServer {
|
|
|
1332
1375
|
async handleExecuteAiAct(ws, request) {
|
|
1333
1376
|
const sessionId = `aiact-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1334
1377
|
const session = sessionManager.create(sessionId, ws, request.deviceId);
|
|
1378
|
+
this.rememberCaptureDataPersistenceMeta(sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
1335
1379
|
const abortController = new AbortController();
|
|
1336
1380
|
session.abortController = abortController;
|
|
1337
1381
|
// 将前端传来的 modelConfig 应用到环境变量,并获取补全后的 modelConfig(含 Planning/Insight)
|
|
@@ -1498,7 +1542,7 @@ export class DebugWebSocketServer {
|
|
|
1498
1542
|
if (capturedRequests.length > 0) {
|
|
1499
1543
|
logger.info('[AiAct] Captured ' + capturedRequests.length + ' requests during session');
|
|
1500
1544
|
try {
|
|
1501
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId);
|
|
1545
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
1502
1546
|
if (uploadResult) {
|
|
1503
1547
|
captureDataUrl = uploadResult;
|
|
1504
1548
|
logger.info('[AiAct] Capture data uploaded: ' + captureDataUrl);
|
|
@@ -1545,7 +1589,7 @@ export class DebugWebSocketServer {
|
|
|
1545
1589
|
if (capturedRequests.length > 0) {
|
|
1546
1590
|
logger.info('[AiAct] Captured ' + capturedRequests.length + ' requests (error path)');
|
|
1547
1591
|
try {
|
|
1548
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId);
|
|
1592
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
1549
1593
|
if (uploadResult)
|
|
1550
1594
|
captureDataUrl = uploadResult;
|
|
1551
1595
|
}
|
|
@@ -1766,6 +1810,7 @@ export class DebugWebSocketServer {
|
|
|
1766
1810
|
session = sessionManager.create(sessionId, ws);
|
|
1767
1811
|
session.platform = 'web';
|
|
1768
1812
|
}
|
|
1813
|
+
this.rememberCaptureDataPersistenceMeta(sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
1769
1814
|
try {
|
|
1770
1815
|
this.sendMessage(ws, { type: 'web_action_started', sessionId, actionType: request.actionType });
|
|
1771
1816
|
const resolvedNaturalLanguage = await this.resolveScriptReferences(request.naturalLanguage);
|
|
@@ -2111,7 +2156,7 @@ export class DebugWebSocketServer {
|
|
|
2111
2156
|
if (capturedRequests.length > 0) {
|
|
2112
2157
|
logger.info('[WebAction] Captured ' + capturedRequests.length + ' requests during session');
|
|
2113
2158
|
try {
|
|
2114
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId);
|
|
2159
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
2115
2160
|
if (uploadResult) {
|
|
2116
2161
|
captureDataUrl = uploadResult;
|
|
2117
2162
|
logger.info('[WebAction] Capture data uploaded: ' + captureDataUrl);
|
|
@@ -2178,7 +2223,7 @@ export class DebugWebSocketServer {
|
|
|
2178
2223
|
if (capturedRequests.length > 0) {
|
|
2179
2224
|
logger.info('[WebAction] Captured ' + capturedRequests.length + ' requests (error path)');
|
|
2180
2225
|
try {
|
|
2181
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId);
|
|
2226
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, sessionId, this.buildCaptureDataPersistenceMeta(sessionId, request));
|
|
2182
2227
|
if (uploadResult)
|
|
2183
2228
|
captureDataUrl = uploadResult;
|
|
2184
2229
|
}
|
|
@@ -2524,6 +2569,7 @@ export class DebugWebSocketServer {
|
|
|
2524
2569
|
webActionRequest.sessionId = sharedSessionId;
|
|
2525
2570
|
}
|
|
2526
2571
|
const sessionId = sharedSessionId;
|
|
2572
|
+
this.rememberCaptureDataPersistenceMeta(sessionId, this.buildCaptureDataPersistenceMeta(request.batchId, tc, request));
|
|
2527
2573
|
const reportGroupName = tc.title || tc.id || `batch-${request.batchId}-case-${caseIndex + 1}`;
|
|
2528
2574
|
const caseMemorySource = this.pickBatchAiMemorySource(request, tc);
|
|
2529
2575
|
let session = sessionManager.get(sessionId);
|
|
@@ -2532,6 +2578,7 @@ export class DebugWebSocketServer {
|
|
|
2532
2578
|
if (!session)
|
|
2533
2579
|
session = sessionManager.create(sessionId, ws);
|
|
2534
2580
|
session.platform = 'web';
|
|
2581
|
+
this.rememberCaptureDataPersistenceMeta(sessionId, this.buildCaptureDataPersistenceMeta(request.batchId, tc, request));
|
|
2535
2582
|
// 并发上限保护
|
|
2536
2583
|
if (this.webSessionsActivity.size >= this.webSessionMaxConcurrency) {
|
|
2537
2584
|
throw new Error(`Web 调试会话数已达上限 (${this.webSessionMaxConcurrency}),请稍后重试`);
|
|
@@ -2646,7 +2693,7 @@ export class DebugWebSocketServer {
|
|
|
2646
2693
|
try {
|
|
2647
2694
|
const capturedRequests = await whistleManager.stopCapture(sessionId);
|
|
2648
2695
|
if (capturedRequests.length > 0) {
|
|
2649
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, `${request.batchId}-${tc.id}
|
|
2696
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, `${request.batchId}-${tc.id}`, this.buildCaptureDataPersistenceMeta(request.batchId, tc, request));
|
|
2650
2697
|
if (uploadResult)
|
|
2651
2698
|
caseCaptureDataUrl = uploadResult;
|
|
2652
2699
|
}
|
|
@@ -2737,6 +2784,7 @@ export class DebugWebSocketServer {
|
|
|
2737
2784
|
const caseMemorySource = this.pickBatchAiMemorySource(request, tc);
|
|
2738
2785
|
const caseSessionId = `batch-${batchId}-case-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2739
2786
|
const session = sessionManager.create(caseSessionId, ws, effectiveDeviceId);
|
|
2787
|
+
this.rememberCaptureDataPersistenceMeta(caseSessionId, this.buildCaptureDataPersistenceMeta(batchId, tc, request));
|
|
2740
2788
|
this.activeBatchSessionIds.add(caseSessionId);
|
|
2741
2789
|
const caseAbortController = new AbortController();
|
|
2742
2790
|
session.abortController = caseAbortController;
|
|
@@ -2841,7 +2889,7 @@ export class DebugWebSocketServer {
|
|
|
2841
2889
|
try {
|
|
2842
2890
|
const capturedRequests = await whistleManager.stopCapture(caseSessionId);
|
|
2843
2891
|
if (capturedRequests.length > 0) {
|
|
2844
|
-
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, `${batchId}-${tc.id}
|
|
2892
|
+
const uploadResult = await this.saveAndUploadCaptureData(capturedRequests, `${batchId}-${tc.id}`, this.buildCaptureDataPersistenceMeta(batchId, tc, request));
|
|
2845
2893
|
if (uploadResult)
|
|
2846
2894
|
caseCaptureDataUrl = uploadResult;
|
|
2847
2895
|
}
|
|
@@ -3077,7 +3125,7 @@ export class DebugWebSocketServer {
|
|
|
3077
3125
|
let stopCaptureDataUrl;
|
|
3078
3126
|
if (stopCapturedRequests.length > 0) {
|
|
3079
3127
|
try {
|
|
3080
|
-
const uploadResult = await this.saveAndUploadCaptureData(stopCapturedRequests, request.sessionId);
|
|
3128
|
+
const uploadResult = await this.saveAndUploadCaptureData(stopCapturedRequests, request.sessionId, this.getCaptureDataPersistenceMeta(request.sessionId));
|
|
3081
3129
|
if (uploadResult) {
|
|
3082
3130
|
stopCaptureDataUrl = uploadResult;
|
|
3083
3131
|
logger.info('[StopDebug] Capture data uploaded: ' + stopCaptureDataUrl);
|
|
@@ -3363,10 +3411,15 @@ export class DebugWebSocketServer {
|
|
|
3363
3411
|
* 将抓包数据保存到本地文件并上传到 OSS
|
|
3364
3412
|
* 返回 OSS URL,失败则返回 undefined
|
|
3365
3413
|
*/
|
|
3366
|
-
async saveAndUploadCaptureData(capturedRequests, sessionId) {
|
|
3414
|
+
async saveAndUploadCaptureData(capturedRequests, sessionId, metadata) {
|
|
3367
3415
|
if (!capturedRequests || capturedRequests.length === 0)
|
|
3368
3416
|
return undefined;
|
|
3369
3417
|
try {
|
|
3418
|
+
const effectiveMetadata = metadata || this.getCaptureDataPersistenceMeta(sessionId);
|
|
3419
|
+
const saveOk = await saveCaptureDataToDatabase(capturedRequests, effectiveMetadata.batchId || sessionId, effectiveMetadata.creator || '');
|
|
3420
|
+
if (!saveOk) {
|
|
3421
|
+
logger.warn(`[CaptureUpload] Save capture data to database failed, continue OSS upload (sessionId=${sessionId})`);
|
|
3422
|
+
}
|
|
3370
3423
|
// 保存到本地临时文件
|
|
3371
3424
|
const tmpDir = path.join(process.cwd(), 'tmp', 'captures');
|
|
3372
3425
|
if (!fs.existsSync(tmpDir)) {
|