acp-ts 1.2.2 → 1.2.4
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/agentcp.js +40 -33
- package/dist/agentws.d.ts +8 -2
- package/dist/agentws.js +22 -4
- package/dist/api.js +8 -8
- package/dist/cert.js +3 -2
- package/dist/cli.js +16 -15
- package/dist/datamanager.js +27 -11
- package/dist/filesync.js +11 -10
- package/dist/group/client.js +44 -36
- package/dist/group/cursor_store.d.ts +4 -9
- package/dist/group/cursor_store.js +12 -40
- package/dist/group/events.d.ts +2 -1
- package/dist/group/events.js +7 -3
- package/dist/group/index.d.ts +1 -1
- package/dist/group/index.js +2 -1
- package/dist/group/message_store.d.ts +5 -6
- package/dist/group/message_store.js +64 -72
- package/dist/group/operations.d.ts +24 -6
- package/dist/group/operations.js +55 -6
- package/dist/group/types.d.ts +30 -1
- package/dist/group/types.js +11 -1
- package/dist/heartbeat.js +24 -24
- package/dist/messagestore.js +9 -8
- package/dist/server.js +2288 -1661
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +19 -2
- package/dist/websocket.d.ts +12 -1
- package/dist/websocket.js +61 -28
- package/package.json +1 -1
package/dist/agentcp.js
CHANGED
|
@@ -96,7 +96,7 @@ class AgentCP {
|
|
|
96
96
|
await (0, cert_1.preloadCrypto)();
|
|
97
97
|
}
|
|
98
98
|
catch (error) {
|
|
99
|
-
|
|
99
|
+
utils_1.logger.warn('AgentCP 加密模块预热失败:', error);
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
/// 导入本地用户信息
|
|
@@ -226,11 +226,11 @@ class AgentCP {
|
|
|
226
226
|
this.agentMdUploaded = true;
|
|
227
227
|
}
|
|
228
228
|
else {
|
|
229
|
-
|
|
229
|
+
utils_1.logger.warn('agent.md 上传失败:', result.error);
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
catch (err) {
|
|
233
|
-
|
|
233
|
+
utils_1.logger.warn('agent.md 上传异常:', err);
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
// 自动生成并上传 agent.md(仅当未设置自定义路径且启用了自动生成时)
|
|
@@ -245,14 +245,14 @@ class AgentCP {
|
|
|
245
245
|
const result = await fileSync.uploadAgentMd(content);
|
|
246
246
|
if (result.success) {
|
|
247
247
|
this.saveAgentMdMarker(aid);
|
|
248
|
-
|
|
248
|
+
utils_1.logger.log(`agent.md 自动生成并上传成功: ${aid}`);
|
|
249
249
|
}
|
|
250
250
|
else {
|
|
251
|
-
|
|
251
|
+
utils_1.logger.warn('agent.md 自动上传失败:', result.error);
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
catch (err) {
|
|
255
|
-
|
|
255
|
+
utils_1.logger.warn('agent.md 自动生成异常:', err);
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
return {
|
|
@@ -304,7 +304,7 @@ class AgentCP {
|
|
|
304
304
|
fs.writeFileSync(this.getAgentMdMarkerPath(aid), new Date().toISOString(), 'utf-8');
|
|
305
305
|
}
|
|
306
306
|
catch (err) {
|
|
307
|
-
|
|
307
|
+
utils_1.logger.warn('保存 agent.md 标记文件失败:', err);
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
310
|
// ============================================================
|
|
@@ -368,7 +368,7 @@ class AgentCP {
|
|
|
368
368
|
handleGroupMessage(message) {
|
|
369
369
|
var _a, _b;
|
|
370
370
|
if (this.groupClient == null || !this._groupTargetAid) {
|
|
371
|
-
|
|
371
|
+
utils_1.logger.log(`[Group] handleGroupMessage skipped: groupClient=${this.groupClient != null}, targetAid=${this._groupTargetAid}`);
|
|
372
372
|
return false;
|
|
373
373
|
}
|
|
374
374
|
const data = message.data || message;
|
|
@@ -377,15 +377,16 @@ class AgentCP {
|
|
|
377
377
|
try {
|
|
378
378
|
const rawMsg = (_b = data.message) !== null && _b !== void 0 ? _b : "";
|
|
379
379
|
if (typeof rawMsg === 'string' && rawMsg) {
|
|
380
|
+
utils_1.logger.log(`[Group] handleGroupMessage: routing to groupClient, sender=${sender} msgLen=${rawMsg.length}`);
|
|
380
381
|
this.groupClient.handleIncoming(rawMsg);
|
|
381
382
|
}
|
|
382
383
|
else {
|
|
383
|
-
|
|
384
|
+
utils_1.logger.warn(`[Group] rawMsg is not a non-empty string, skipping handleIncoming. type=${typeof rawMsg}`);
|
|
384
385
|
}
|
|
385
386
|
return true;
|
|
386
387
|
}
|
|
387
388
|
catch (e) {
|
|
388
|
-
|
|
389
|
+
utils_1.logger.error("[Group] handleIncoming error:", e);
|
|
389
390
|
return true;
|
|
390
391
|
}
|
|
391
392
|
}
|
|
@@ -408,20 +409,20 @@ class AgentCP {
|
|
|
408
409
|
_createDefaultGroupEventHandler() {
|
|
409
410
|
return {
|
|
410
411
|
onNewMessage(groupId, latestMsgId, sender, preview) {
|
|
411
|
-
|
|
412
|
+
utils_1.logger.log(`[Group][DefaultHandler] onNewMessage: group=${groupId} msgId=${latestMsgId} sender=${sender} preview=${preview}`);
|
|
412
413
|
},
|
|
413
414
|
onNewEvent(groupId, latestEventId, eventType, summary) {
|
|
414
|
-
|
|
415
|
+
utils_1.logger.log(`[Group][DefaultHandler] onNewEvent: group=${groupId} eventId=${latestEventId} type=${eventType}`);
|
|
415
416
|
},
|
|
416
417
|
onGroupInvite(groupId, groupAddress, invitedBy) {
|
|
417
|
-
|
|
418
|
+
utils_1.logger.log(`[Group][DefaultHandler] onGroupInvite: group=${groupId} address=${groupAddress} invitedBy=${invitedBy}`);
|
|
418
419
|
},
|
|
419
420
|
onJoinApproved: (groupId, groupAddress) => {
|
|
420
|
-
|
|
421
|
+
utils_1.logger.log(`[Group][DefaultHandler] onJoinApproved: group=${groupId} address=${groupAddress}`);
|
|
421
422
|
(async () => {
|
|
422
423
|
try {
|
|
423
424
|
if (!this.groupOps || !this._groupTargetAid) {
|
|
424
|
-
|
|
425
|
+
utils_1.logger.warn(`[Group][DefaultHandler] onJoinApproved skipped: groupOps or targetAid not available`);
|
|
425
426
|
return;
|
|
426
427
|
}
|
|
427
428
|
let groupName = groupId;
|
|
@@ -433,24 +434,24 @@ class AgentCP {
|
|
|
433
434
|
this.addGroupToStore(groupId, groupName);
|
|
434
435
|
}
|
|
435
436
|
catch (e) {
|
|
436
|
-
|
|
437
|
+
utils_1.logger.error(`[Group][DefaultHandler] onJoinApproved processing failed: group=${groupId}`, e.message);
|
|
437
438
|
}
|
|
438
439
|
})();
|
|
439
440
|
},
|
|
440
441
|
onJoinRejected(groupId, reason) {
|
|
441
|
-
|
|
442
|
+
utils_1.logger.log(`[Group][DefaultHandler] onJoinRejected: group=${groupId} reason=${reason}`);
|
|
442
443
|
},
|
|
443
444
|
onJoinRequestReceived(groupId, agentId, message) {
|
|
444
|
-
|
|
445
|
+
utils_1.logger.log(`[Group][DefaultHandler] onJoinRequestReceived: group=${groupId} agent=${agentId}`);
|
|
445
446
|
},
|
|
446
447
|
onGroupMessageBatch: (groupId, batch) => {
|
|
447
|
-
|
|
448
|
+
utils_1.logger.log(`[Group][DefaultHandler] onGroupMessageBatch: group=${groupId} count=${batch.count} range=[${batch.start_msg_id}, ${batch.latest_msg_id}]`);
|
|
448
449
|
this.processAndAckBatch(groupId, batch).catch(e => {
|
|
449
|
-
|
|
450
|
+
utils_1.logger.error(`[Group][DefaultHandler] processAndAckBatch failed: group=${groupId}`, e);
|
|
450
451
|
});
|
|
451
452
|
},
|
|
452
453
|
onGroupEvent(groupId, evt) {
|
|
453
|
-
|
|
454
|
+
utils_1.logger.log(`[Group][DefaultHandler] onGroupEvent: group=${groupId} event=${evt.event_type}`);
|
|
454
455
|
},
|
|
455
456
|
};
|
|
456
457
|
}
|
|
@@ -460,6 +461,10 @@ class AgentCP {
|
|
|
460
461
|
*/
|
|
461
462
|
async processAndAckBatch(groupId, batch) {
|
|
462
463
|
const sorted = [...batch.messages].sort((a, b) => a.msg_id - b.msg_id);
|
|
464
|
+
utils_1.logger.log(`[AgentCP] processAndAckBatch: group=${groupId} batchCount=${batch.messages.length} sortedCount=${sorted.length} msgIds=[${sorted.map(m => m.msg_id).join(',')}]`);
|
|
465
|
+
const storeExists = !!this.groupMessageStore;
|
|
466
|
+
const storeGroupExists = storeExists ? !!this.groupMessageStore.getGroup(groupId) : false;
|
|
467
|
+
utils_1.logger.log(`[AgentCP] processAndAckBatch: storeExists=${storeExists} storeGroupExists=${storeGroupExists} lastMsgId=${this.getGroupLastMsgId(groupId)}`);
|
|
463
468
|
await this.addGroupMessagesToStore(groupId, sorted);
|
|
464
469
|
// ACK batch 中最后一条消息
|
|
465
470
|
if (sorted.length > 0) {
|
|
@@ -475,7 +480,7 @@ class AgentCP {
|
|
|
475
480
|
if (!this.groupOps || !this._groupTargetAid)
|
|
476
481
|
return;
|
|
477
482
|
this.groupOps.ackMessages(this._groupTargetAid, groupId, msgId).catch(e => {
|
|
478
|
-
|
|
483
|
+
utils_1.logger.warn(`[Group] ack failed: group=${groupId} msgId=${msgId}`, e.message || e);
|
|
479
484
|
});
|
|
480
485
|
}
|
|
481
486
|
/**
|
|
@@ -498,7 +503,7 @@ class AgentCP {
|
|
|
498
503
|
this.groupClient.close();
|
|
499
504
|
}
|
|
500
505
|
catch (e) {
|
|
501
|
-
|
|
506
|
+
utils_1.logger.error("[Group] group_client close error:", e);
|
|
502
507
|
}
|
|
503
508
|
this.groupClient = null;
|
|
504
509
|
this.groupOps = null;
|
|
@@ -519,7 +524,7 @@ class AgentCP {
|
|
|
519
524
|
await this.groupMessageStore.loadGroupsForAid(this.activeAid);
|
|
520
525
|
}
|
|
521
526
|
catch (e) {
|
|
522
|
-
|
|
527
|
+
utils_1.logger.warn('[AgentCP] 加载群消息存储失败:', e);
|
|
523
528
|
}
|
|
524
529
|
}
|
|
525
530
|
}
|
|
@@ -570,7 +575,7 @@ class AgentCP {
|
|
|
570
575
|
for (const local of localGroups) {
|
|
571
576
|
if (!serverGroupIds.has(local.groupId)) {
|
|
572
577
|
await this.groupMessageStore.deleteGroup(local.groupId);
|
|
573
|
-
|
|
578
|
+
utils_1.logger.log(`[Group] syncGroupList: 清理本地已退出群组 ${local.groupId}`);
|
|
574
579
|
}
|
|
575
580
|
}
|
|
576
581
|
}
|
|
@@ -627,8 +632,10 @@ class AgentCP {
|
|
|
627
632
|
* 批量添加群消息到本地存储
|
|
628
633
|
*/
|
|
629
634
|
async addGroupMessagesToStore(groupId, msgs) {
|
|
630
|
-
if (!this.groupMessageStore)
|
|
635
|
+
if (!this.groupMessageStore) {
|
|
636
|
+
utils_1.logger.warn(`[AgentCP] addGroupMessagesToStore: groupMessageStore is NULL! group=${groupId} msgs=${msgs.length} — 消息将丢失!`);
|
|
631
637
|
return;
|
|
638
|
+
}
|
|
632
639
|
await this.groupMessageStore.addMessages(groupId, msgs);
|
|
633
640
|
}
|
|
634
641
|
/**
|
|
@@ -684,7 +691,7 @@ class AgentCP {
|
|
|
684
691
|
}
|
|
685
692
|
}
|
|
686
693
|
catch (e) {
|
|
687
|
-
|
|
694
|
+
utils_1.logger.warn('[AgentCP] pullAndStoreGroupMessages error:', e.message);
|
|
688
695
|
}
|
|
689
696
|
return this.getLocalGroupMessages(groupId);
|
|
690
697
|
}
|
|
@@ -704,14 +711,14 @@ class AgentCP {
|
|
|
704
711
|
// Step 1: register_online(仅通知 group.ap 在线,不再返回游标)
|
|
705
712
|
await this.groupOps.registerOnline(this._groupTargetAid);
|
|
706
713
|
this._onlineGroups.add(groupId);
|
|
707
|
-
|
|
714
|
+
utils_1.logger.log(`[Group] joinGroupSession: group=${groupId}`);
|
|
708
715
|
// Step 2: 冷启动同步 — 拉取历史消息对齐,再进入批推送接收
|
|
709
716
|
try {
|
|
710
717
|
const lastMsgId = this.getGroupLastMsgId(groupId);
|
|
711
718
|
await this.pullAndStoreGroupMessages(groupId, lastMsgId, 50);
|
|
712
719
|
}
|
|
713
720
|
catch (e) {
|
|
714
|
-
|
|
721
|
+
utils_1.logger.warn(`[Group] cold-start sync failed: group=${groupId}`, e.message || e);
|
|
715
722
|
}
|
|
716
723
|
// Step 3: 启动心跳定时器(首次加入群组时启动)
|
|
717
724
|
this._ensureHeartbeat();
|
|
@@ -731,7 +738,7 @@ class AgentCP {
|
|
|
731
738
|
await this.groupOps.unregisterOnline(this._groupTargetAid);
|
|
732
739
|
}
|
|
733
740
|
catch (e) {
|
|
734
|
-
|
|
741
|
+
utils_1.logger.warn(`[Group] unregisterOnline failed`, e.message || e);
|
|
735
742
|
}
|
|
736
743
|
this._stopHeartbeat();
|
|
737
744
|
}
|
|
@@ -773,7 +780,7 @@ class AgentCP {
|
|
|
773
780
|
this._heartbeatTimer = setInterval(() => {
|
|
774
781
|
this._sendHeartbeats();
|
|
775
782
|
}, this._heartbeatIntervalMs);
|
|
776
|
-
|
|
783
|
+
utils_1.logger.log(`[Group] heartbeat started: interval=${this._heartbeatIntervalMs}ms`);
|
|
777
784
|
}
|
|
778
785
|
/**
|
|
779
786
|
* 停止心跳定时器
|
|
@@ -782,7 +789,7 @@ class AgentCP {
|
|
|
782
789
|
if (this._heartbeatTimer) {
|
|
783
790
|
clearInterval(this._heartbeatTimer);
|
|
784
791
|
this._heartbeatTimer = null;
|
|
785
|
-
|
|
792
|
+
utils_1.logger.log(`[Group] heartbeat stopped`);
|
|
786
793
|
}
|
|
787
794
|
}
|
|
788
795
|
/**
|
|
@@ -792,7 +799,7 @@ class AgentCP {
|
|
|
792
799
|
if (!this.groupOps || !this._groupTargetAid)
|
|
793
800
|
return;
|
|
794
801
|
this.groupOps.heartbeat(this._groupTargetAid).catch(e => {
|
|
795
|
-
|
|
802
|
+
utils_1.logger.warn(`[Group] heartbeat failed`, e.message || e);
|
|
796
803
|
});
|
|
797
804
|
}
|
|
798
805
|
/**
|
package/dist/agentws.d.ts
CHANGED
|
@@ -85,9 +85,15 @@ declare class AgentWS implements IAgentWS {
|
|
|
85
85
|
*/
|
|
86
86
|
disconnect(): void;
|
|
87
87
|
/**
|
|
88
|
-
*
|
|
88
|
+
* 注册"快速重连全部失败"回调,透传 WSClient 的回调
|
|
89
89
|
*/
|
|
90
|
-
|
|
90
|
+
onReconnectNeeded(cb: () => void): void;
|
|
91
|
+
/**
|
|
92
|
+
* 重连 WebSocket
|
|
93
|
+
* @param newServer 新的消息服务器地址(可选,重新鉴权后传入)
|
|
94
|
+
* @param newSignature 新的签名(可选,重新鉴权后传入)
|
|
95
|
+
*/
|
|
96
|
+
reconnect(newServer?: string, newSignature?: string): Promise<void>;
|
|
91
97
|
/**
|
|
92
98
|
* 接受来自心跳通道的邀请
|
|
93
99
|
* 当心跳客户端收到邀请时,调用此方法通过 WebSocket 加入会话
|
package/dist/agentws.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AgentWS = void 0;
|
|
4
4
|
const websocket_1 = require("./websocket");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
5
6
|
/**
|
|
6
7
|
* AgentWS类
|
|
7
8
|
* 提供基于WebSocket的智能体通信功能,封装了WebSocket连接、会话创建和消息传递等操作
|
|
@@ -69,7 +70,7 @@ class AgentWS {
|
|
|
69
70
|
this.invite(receiver, sessionRes.sessionId, sessionRes.identifyingCode, onInviteStatus);
|
|
70
71
|
}
|
|
71
72
|
else {
|
|
72
|
-
|
|
73
|
+
utils_1.logger.error("会话创建成功但未返回sessionId或identifyingCode");
|
|
73
74
|
}
|
|
74
75
|
});
|
|
75
76
|
}
|
|
@@ -145,10 +146,27 @@ class AgentWS {
|
|
|
145
146
|
this.msgClient.disconnect();
|
|
146
147
|
}
|
|
147
148
|
/**
|
|
148
|
-
*
|
|
149
|
+
* 注册"快速重连全部失败"回调,透传 WSClient 的回调
|
|
149
150
|
*/
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
onReconnectNeeded(cb) {
|
|
152
|
+
this.msgClient.onReconnectNeeded(cb);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 重连 WebSocket
|
|
156
|
+
* @param newServer 新的消息服务器地址(可选,重新鉴权后传入)
|
|
157
|
+
* @param newSignature 新的签名(可选,重新鉴权后传入)
|
|
158
|
+
*/
|
|
159
|
+
async reconnect(newServer, newSignature) {
|
|
160
|
+
let newUrl;
|
|
161
|
+
if (newServer && newSignature) {
|
|
162
|
+
this.messageServer = newServer;
|
|
163
|
+
this.messageSignature = newSignature;
|
|
164
|
+
let url = newServer.replace("https://", "wss://").replace("http://", "ws://");
|
|
165
|
+
const encodedAid = encodeURIComponent(this.aid);
|
|
166
|
+
const encodedSignature = encodeURIComponent(newSignature);
|
|
167
|
+
newUrl = `${url}/session?agent_id=${encodedAid}&signature=${encodedSignature}`;
|
|
168
|
+
}
|
|
169
|
+
await this.msgClient.reconnect(newUrl);
|
|
152
170
|
}
|
|
153
171
|
/**
|
|
154
172
|
* 接受来自心跳通道的邀请
|
package/dist/api.js
CHANGED
|
@@ -35,7 +35,7 @@ async function getGuestAid(apiUrl, seedPassword) {
|
|
|
35
35
|
return null;
|
|
36
36
|
}
|
|
37
37
|
catch (error) {
|
|
38
|
-
|
|
38
|
+
utils_1.logger.error('获取访客证书失败:', error);
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -57,7 +57,7 @@ async function getEntryPointConfig(aid, apiUrl) {
|
|
|
57
57
|
return null;
|
|
58
58
|
}
|
|
59
59
|
catch (error) {
|
|
60
|
-
|
|
60
|
+
utils_1.logger.error('获取接入点配置失败:', error);
|
|
61
61
|
return null;
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -78,7 +78,7 @@ async function signCert(agentId, apiUrl, csr) {
|
|
|
78
78
|
return null;
|
|
79
79
|
}
|
|
80
80
|
catch (error) {
|
|
81
|
-
|
|
81
|
+
utils_1.logger.error('sign_cert接口异常:', error, data);
|
|
82
82
|
return null;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
@@ -107,7 +107,7 @@ async function signIn(agentId, apiUrl, privateKey, publicKeyPem, certPem) {
|
|
|
107
107
|
certificate = certificate || keyInfo.certPem;
|
|
108
108
|
}
|
|
109
109
|
if (!publicKey || !certificate) {
|
|
110
|
-
|
|
110
|
+
utils_1.logger.error('signIn 失败: 无法获取公钥或证书');
|
|
111
111
|
return null;
|
|
112
112
|
}
|
|
113
113
|
const signatureHex = await (0, cert_1.signPrivate)(nonce, privateKey);
|
|
@@ -128,15 +128,15 @@ async function signIn(agentId, apiUrl, privateKey, publicKeyPem, certPem) {
|
|
|
128
128
|
signData
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
-
|
|
131
|
+
utils_1.logger.error('signIn 第二步失败:', res.status, res.data);
|
|
132
132
|
return null;
|
|
133
133
|
}
|
|
134
|
-
|
|
134
|
+
utils_1.logger.error('signIn 第一步失败:', response.status, response.data);
|
|
135
135
|
return null;
|
|
136
136
|
}
|
|
137
137
|
catch (error) {
|
|
138
138
|
const errMsg = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || error.message || error;
|
|
139
|
-
|
|
139
|
+
utils_1.logger.error('登录异常:', errMsg);
|
|
140
140
|
return null;
|
|
141
141
|
}
|
|
142
142
|
}
|
|
@@ -158,7 +158,7 @@ async function signOut(agentId, apiUrl) {
|
|
|
158
158
|
return false;
|
|
159
159
|
}
|
|
160
160
|
catch (error) {
|
|
161
|
-
|
|
161
|
+
utils_1.logger.error('退出登录异常:', error);
|
|
162
162
|
return false;
|
|
163
163
|
}
|
|
164
164
|
}
|
package/dist/cert.js
CHANGED
|
@@ -8,6 +8,7 @@ exports.signPrivate = signPrivate;
|
|
|
8
8
|
exports.preloadCrypto = preloadCrypto;
|
|
9
9
|
const jsrsasign_1 = require("jsrsasign");
|
|
10
10
|
const datamanager_1 = require("./datamanager");
|
|
11
|
+
const utils_1 = require("./utils");
|
|
11
12
|
function createSignedCertificate(aid = '') {
|
|
12
13
|
const { pubKeyObj, prvKeyObj } = jsrsasign_1.KEYUTIL.generateKeypair("EC", "secp384r1");
|
|
13
14
|
const prvKeyPEM = jsrsasign_1.KEYUTIL.getPEM(prvKeyObj, "PKCS8PRV");
|
|
@@ -61,7 +62,7 @@ async function getPublicKeyPem(agentId) {
|
|
|
61
62
|
};
|
|
62
63
|
}
|
|
63
64
|
catch (error) {
|
|
64
|
-
|
|
65
|
+
utils_1.logger.error('获取公钥 PEM 格式失败:', error);
|
|
65
66
|
throw new Error('获取公钥失败');
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -215,7 +216,7 @@ async function preloadCrypto() {
|
|
|
215
216
|
require('jsrsasign');
|
|
216
217
|
}
|
|
217
218
|
catch (error) {
|
|
218
|
-
|
|
219
|
+
utils_1.logger.warn('Crypto preload failed:', error);
|
|
219
220
|
}
|
|
220
221
|
}
|
|
221
222
|
function createCSR(commonName, prvKeyPEM, pubKeyPEM) {
|
package/dist/cli.js
CHANGED
|
@@ -38,6 +38,7 @@ const server_1 = require("./server");
|
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const fs = __importStar(require("fs"));
|
|
40
40
|
const child_process_1 = require("child_process");
|
|
41
|
+
const utils_1 = require("./utils");
|
|
41
42
|
// 判断是否为 Windows 平台
|
|
42
43
|
const isWindows = process.platform === 'win32';
|
|
43
44
|
// 获取 npm 命令(Windows 需要使用 npm.cmd)
|
|
@@ -57,7 +58,7 @@ function getVersion() {
|
|
|
57
58
|
}
|
|
58
59
|
// 更新到最新版本
|
|
59
60
|
function update() {
|
|
60
|
-
|
|
61
|
+
utils_1.logger.log('正在检查更新...');
|
|
61
62
|
const npm = getNpmCommand();
|
|
62
63
|
try {
|
|
63
64
|
// 获取最新版本号
|
|
@@ -74,33 +75,33 @@ function update() {
|
|
|
74
75
|
const latestVersion = result.stdout.trim();
|
|
75
76
|
const currentVersion = getVersion();
|
|
76
77
|
if (latestVersion === currentVersion) {
|
|
77
|
-
|
|
78
|
+
utils_1.logger.log(`当前已是最新版本 v${currentVersion}`);
|
|
78
79
|
return;
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
utils_1.logger.log(`发现新版本 v${latestVersion},当前版本 v${currentVersion}`);
|
|
82
|
+
utils_1.logger.log('正在更新...');
|
|
82
83
|
// 执行全局更新
|
|
83
84
|
const installResult = (0, child_process_1.spawnSync)(npm, ['install', '-g', 'acp-ts@latest'], {
|
|
84
85
|
stdio: 'inherit',
|
|
85
86
|
shell: true
|
|
86
87
|
});
|
|
87
88
|
if (installResult.status === 0) {
|
|
88
|
-
|
|
89
|
+
utils_1.logger.log(`更新成功!已更新到 v${latestVersion}`);
|
|
89
90
|
}
|
|
90
91
|
else {
|
|
91
92
|
// 可能是权限问题
|
|
92
93
|
if (!isWindows) {
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
utils_1.logger.log('\n更新失败,可能需要管理员权限,请尝试运行:');
|
|
95
|
+
utils_1.logger.log(' sudo npm install -g acp-ts@latest');
|
|
95
96
|
}
|
|
96
97
|
else {
|
|
97
|
-
|
|
98
|
+
utils_1.logger.log('\n更新失败,请尝试以管理员身份运行命令提示符后重试');
|
|
98
99
|
}
|
|
99
100
|
process.exit(1);
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
catch (error) {
|
|
103
|
-
|
|
104
|
+
utils_1.logger.error('更新失败:', error.message);
|
|
104
105
|
process.exit(1);
|
|
105
106
|
}
|
|
106
107
|
}
|
|
@@ -115,18 +116,18 @@ for (let i = 0; i < args.length; i++) {
|
|
|
115
116
|
process.exit(0);
|
|
116
117
|
}
|
|
117
118
|
else if (args[i] === '-v' || args[i] === '--version') {
|
|
118
|
-
|
|
119
|
+
utils_1.logger.log(`acp-ts v${getVersion()}`);
|
|
119
120
|
process.exit(0);
|
|
120
121
|
}
|
|
121
122
|
else if (args[i] === '-p' || args[i] === '--port') {
|
|
122
123
|
const portArg = args[i + 1];
|
|
123
124
|
if (!portArg || portArg.startsWith('-')) {
|
|
124
|
-
|
|
125
|
+
utils_1.logger.error('错误: -p 参数需要指定端口号');
|
|
125
126
|
process.exit(1);
|
|
126
127
|
}
|
|
127
128
|
const parsedPort = parseInt(portArg, 10);
|
|
128
129
|
if (isNaN(parsedPort) || parsedPort < 1 || parsedPort > 65535) {
|
|
129
|
-
|
|
130
|
+
utils_1.logger.error('错误: 端口号必须是 1-65535 之间的数字');
|
|
130
131
|
process.exit(1);
|
|
131
132
|
}
|
|
132
133
|
port = parsedPort;
|
|
@@ -135,7 +136,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
135
136
|
else if (args[i] === '-u' || args[i] === '--url') {
|
|
136
137
|
const urlArg = args[i + 1];
|
|
137
138
|
if (!urlArg || urlArg.startsWith('-')) {
|
|
138
|
-
|
|
139
|
+
utils_1.logger.error('错误: -u 参数需要指定 URL');
|
|
139
140
|
process.exit(1);
|
|
140
141
|
}
|
|
141
142
|
apiUrl = urlArg;
|
|
@@ -144,14 +145,14 @@ for (let i = 0; i < args.length; i++) {
|
|
|
144
145
|
else if (args[i] === '-d' || args[i] === '--data-dir') {
|
|
145
146
|
const dirArg = args[i + 1];
|
|
146
147
|
if (!dirArg || dirArg.startsWith('-')) {
|
|
147
|
-
|
|
148
|
+
utils_1.logger.error('错误: -d 参数需要指定数据目录路径');
|
|
148
149
|
process.exit(1);
|
|
149
150
|
}
|
|
150
151
|
dataDir = dirArg;
|
|
151
152
|
i++;
|
|
152
153
|
}
|
|
153
154
|
else if (args[i] === '-h' || args[i] === '--help') {
|
|
154
|
-
|
|
155
|
+
utils_1.logger.log(`
|
|
155
156
|
acp-ts - 智能体通信调试工具 v${getVersion()}
|
|
156
157
|
|
|
157
158
|
用法:
|
package/dist/datamanager.js
CHANGED
|
@@ -36,6 +36,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.CertAndKeyStore = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
|
+
// 本地 logger(避免与 utils.ts 循环依赖)
|
|
40
|
+
function _ts() {
|
|
41
|
+
const n = new Date();
|
|
42
|
+
const y = n.getFullYear();
|
|
43
|
+
const m = String(n.getMonth() + 1).padStart(2, '0');
|
|
44
|
+
const d = String(n.getDate()).padStart(2, '0');
|
|
45
|
+
const h = String(n.getHours()).padStart(2, '0');
|
|
46
|
+
const min = String(n.getMinutes()).padStart(2, '0');
|
|
47
|
+
const s = String(n.getSeconds()).padStart(2, '0');
|
|
48
|
+
return `${y}/${m}/${d} ${h}:${min}:${s}`;
|
|
49
|
+
}
|
|
50
|
+
const logger = {
|
|
51
|
+
log: (...args) => console.log(`[${_ts()}]`, ...args),
|
|
52
|
+
warn: (...args) => console.warn(`[${_ts()}]`, ...args),
|
|
53
|
+
error: (...args) => console.error(`[${_ts()}]`, ...args),
|
|
54
|
+
};
|
|
39
55
|
// 统一的环境检测函数
|
|
40
56
|
const isNodeEnvironment = typeof process !== 'undefined' &&
|
|
41
57
|
process.versions != null &&
|
|
@@ -56,7 +72,7 @@ class NodeStorage {
|
|
|
56
72
|
this.initialized = true;
|
|
57
73
|
}
|
|
58
74
|
catch (e) {
|
|
59
|
-
|
|
75
|
+
logger.error('NodeStorage init error:', e);
|
|
60
76
|
this.cache = {};
|
|
61
77
|
this.initialized = true;
|
|
62
78
|
}
|
|
@@ -66,7 +82,7 @@ class NodeStorage {
|
|
|
66
82
|
fs.writeFileSync(this.dataFile, JSON.stringify(this.cache, null, 2));
|
|
67
83
|
}
|
|
68
84
|
catch (e) {
|
|
69
|
-
|
|
85
|
+
logger.error('NodeStorage save error:', e);
|
|
70
86
|
}
|
|
71
87
|
}
|
|
72
88
|
static async setItem(key, value) {
|
|
@@ -96,7 +112,7 @@ else {
|
|
|
96
112
|
}
|
|
97
113
|
catch (e) {
|
|
98
114
|
// 如果加载失败,使用内存存储作为后备
|
|
99
|
-
|
|
115
|
+
logger.warn('AsyncStorage not available, using memory storage');
|
|
100
116
|
const memoryStore = {};
|
|
101
117
|
AsyncStorage = {
|
|
102
118
|
setItem: async (key, value) => { memoryStore[key] = value; },
|
|
@@ -117,7 +133,7 @@ class CertAndKeyStore {
|
|
|
117
133
|
await AsyncStorage.setItem(key, JSON.stringify(value));
|
|
118
134
|
}
|
|
119
135
|
catch (e) {
|
|
120
|
-
|
|
136
|
+
logger.error(e);
|
|
121
137
|
}
|
|
122
138
|
}
|
|
123
139
|
// 获取数据(仍用 storage.json,用于会话/消息)
|
|
@@ -136,7 +152,7 @@ class CertAndKeyStore {
|
|
|
136
152
|
return parsed;
|
|
137
153
|
}
|
|
138
154
|
catch (e) {
|
|
139
|
-
|
|
155
|
+
logger.error(e);
|
|
140
156
|
return null;
|
|
141
157
|
}
|
|
142
158
|
}
|
|
@@ -152,7 +168,7 @@ class CertAndKeyStore {
|
|
|
152
168
|
return null;
|
|
153
169
|
}
|
|
154
170
|
catch (e) {
|
|
155
|
-
|
|
171
|
+
logger.error('获取访客ID失败:', e);
|
|
156
172
|
return null;
|
|
157
173
|
}
|
|
158
174
|
}
|
|
@@ -173,7 +189,7 @@ class CertAndKeyStore {
|
|
|
173
189
|
}).map(e => e.name);
|
|
174
190
|
}
|
|
175
191
|
catch (e) {
|
|
176
|
-
|
|
192
|
+
logger.error('扫描 AIDs 目录失败:', e);
|
|
177
193
|
return [];
|
|
178
194
|
}
|
|
179
195
|
}
|
|
@@ -189,7 +205,7 @@ class CertAndKeyStore {
|
|
|
189
205
|
}
|
|
190
206
|
}
|
|
191
207
|
catch (e) {
|
|
192
|
-
|
|
208
|
+
logger.error('创建 AID 目录失败:', e);
|
|
193
209
|
}
|
|
194
210
|
}
|
|
195
211
|
static async getCertificate(aid) {
|
|
@@ -201,7 +217,7 @@ class CertAndKeyStore {
|
|
|
201
217
|
return null;
|
|
202
218
|
}
|
|
203
219
|
catch (e) {
|
|
204
|
-
|
|
220
|
+
logger.error('读取证书失败:', e);
|
|
205
221
|
return null;
|
|
206
222
|
}
|
|
207
223
|
}
|
|
@@ -219,7 +235,7 @@ class CertAndKeyStore {
|
|
|
219
235
|
return null;
|
|
220
236
|
}
|
|
221
237
|
catch (e) {
|
|
222
|
-
|
|
238
|
+
logger.error('读取 CSR 失败:', e);
|
|
223
239
|
return null;
|
|
224
240
|
}
|
|
225
241
|
}
|
|
@@ -242,7 +258,7 @@ class CertAndKeyStore {
|
|
|
242
258
|
return null;
|
|
243
259
|
}
|
|
244
260
|
catch (error) {
|
|
245
|
-
|
|
261
|
+
logger.error('获取私钥失败:', error);
|
|
246
262
|
throw new Error('获取私钥失败');
|
|
247
263
|
}
|
|
248
264
|
}
|