acp-ts 1.1.6 → 1.1.7
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.d.ts +4 -0
- package/dist/agentcp.js +35 -1
- package/dist/server.js +108 -13
- package/package.json +1 -1
package/dist/agentcp.d.ts
CHANGED
|
@@ -132,6 +132,10 @@ declare class AgentCP implements IAgentCP {
|
|
|
132
132
|
* 添加群组到本地存储
|
|
133
133
|
*/
|
|
134
134
|
addGroupToStore(groupId: string, name: string): void;
|
|
135
|
+
/**
|
|
136
|
+
* 将加入的群组注册到 Home AP(内部方法)
|
|
137
|
+
*/
|
|
138
|
+
registerGroupToHomeAP(groupId: string, groupUrl: string, role?: string): Promise<void>;
|
|
135
139
|
/**
|
|
136
140
|
* 从本地存储删除群组
|
|
137
141
|
*/
|
package/dist/agentcp.js
CHANGED
|
@@ -412,8 +412,28 @@ class AgentCP {
|
|
|
412
412
|
onGroupInvite(groupId, groupAddress, invitedBy) {
|
|
413
413
|
console.log(`[Group][DefaultHandler] onGroupInvite: group=${groupId} address=${groupAddress} invitedBy=${invitedBy}`);
|
|
414
414
|
},
|
|
415
|
-
onJoinApproved(groupId, groupAddress) {
|
|
415
|
+
onJoinApproved: (groupId, groupAddress) => {
|
|
416
416
|
console.log(`[Group][DefaultHandler] onJoinApproved: group=${groupId} address=${groupAddress}`);
|
|
417
|
+
(async () => {
|
|
418
|
+
try {
|
|
419
|
+
if (!this.groupOps || !this._groupTargetAid) {
|
|
420
|
+
console.warn(`[Group][DefaultHandler] onJoinApproved skipped: groupOps or targetAid not available`);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
let groupName = groupId;
|
|
424
|
+
try {
|
|
425
|
+
const info = await this.groupOps.getGroupInfo(this._groupTargetAid, groupId);
|
|
426
|
+
groupName = info.name || groupId;
|
|
427
|
+
}
|
|
428
|
+
catch (_) { }
|
|
429
|
+
this.addGroupToStore(groupId, groupName);
|
|
430
|
+
const groupUrl = groupAddress || `https://${this._groupTargetAid}/${groupId}`;
|
|
431
|
+
await this.registerGroupToHomeAP(groupId, groupUrl);
|
|
432
|
+
}
|
|
433
|
+
catch (e) {
|
|
434
|
+
console.error(`[Group][DefaultHandler] onJoinApproved processing failed: group=${groupId}`, e.message);
|
|
435
|
+
}
|
|
436
|
+
})();
|
|
417
437
|
},
|
|
418
438
|
onJoinRejected(groupId, reason) {
|
|
419
439
|
console.log(`[Group][DefaultHandler] onJoinRejected: group=${groupId} reason=${reason}`);
|
|
@@ -533,6 +553,20 @@ class AgentCP {
|
|
|
533
553
|
return;
|
|
534
554
|
this.groupMessageStore.getOrCreateGroup(groupId, this._groupTargetAid, name);
|
|
535
555
|
}
|
|
556
|
+
/**
|
|
557
|
+
* 将加入的群组注册到 Home AP(内部方法)
|
|
558
|
+
*/
|
|
559
|
+
async registerGroupToHomeAP(groupId, groupUrl, role = 'member') {
|
|
560
|
+
if (!this.groupOps || !this._groupTargetAid)
|
|
561
|
+
return;
|
|
562
|
+
try {
|
|
563
|
+
await this.groupOps.registerMembership(this._groupTargetAid, groupId, groupUrl, this._groupTargetAid, this._groupSessionId, role);
|
|
564
|
+
console.log(`[Group] registerGroupToHomeAP success: group=${groupId}`);
|
|
565
|
+
}
|
|
566
|
+
catch (e) {
|
|
567
|
+
console.error(`[Group] registerGroupToHomeAP failed: group=${groupId}`, e.message);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
536
570
|
/**
|
|
537
571
|
* 从本地存储删除群组
|
|
538
572
|
*/
|
package/dist/server.js
CHANGED
|
@@ -241,6 +241,27 @@ async function ensureGroupClient(instance) {
|
|
|
241
241
|
},
|
|
242
242
|
onJoinApproved(groupId, groupAddress) {
|
|
243
243
|
console.log(`[Group] onJoinApproved: group=${groupId} address=${groupAddress}`);
|
|
244
|
+
// 审核通过:获取群信息、添加本地存储、注册到 Home AP
|
|
245
|
+
(async () => {
|
|
246
|
+
try {
|
|
247
|
+
if (!instance.agentCP.groupOps) {
|
|
248
|
+
console.warn(`[Group] onJoinApproved skipped: groupOps not available`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
let groupName = groupId;
|
|
252
|
+
try {
|
|
253
|
+
const info = await instance.agentCP.groupOps.getGroupInfo(instance.groupTargetAid, groupId);
|
|
254
|
+
groupName = info.name || groupId;
|
|
255
|
+
}
|
|
256
|
+
catch (_) { }
|
|
257
|
+
instance.agentCP.addGroupToStore(groupId, groupName);
|
|
258
|
+
const groupUrl = groupAddress || `https://${instance.groupTargetAid}/${groupId}`;
|
|
259
|
+
await instance.agentCP.registerGroupToHomeAP(groupId, groupUrl);
|
|
260
|
+
}
|
|
261
|
+
catch (e) {
|
|
262
|
+
console.error(`[Group] onJoinApproved processing failed: group=${groupId}`, e.message);
|
|
263
|
+
}
|
|
264
|
+
})();
|
|
244
265
|
},
|
|
245
266
|
onJoinRejected(groupId, reason) {
|
|
246
267
|
console.log(`[Group] onJoinRejected: group=${groupId} reason=${reason}`);
|
|
@@ -453,19 +474,19 @@ const indexHtml = `<!DOCTYPE html>
|
|
|
453
474
|
.container { background: white; padding: 32px; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); max-width: 560px; width: 100%; }
|
|
454
475
|
h1 { color: #333; margin-bottom: 24px; text-align: center; font-size: 22px; }
|
|
455
476
|
.hint { text-align: center; color: #999; font-size: 13px; margin-bottom: 20px; }
|
|
456
|
-
.create-section { margin-bottom: 24px; }
|
|
457
|
-
.create-section .aid-input-row { display: flex; gap: 8px;
|
|
477
|
+
.create-section { margin-bottom: 24px; display: flex; flex-direction: column; gap: 12px; }
|
|
478
|
+
.create-section .aid-input-row { display: flex; gap: 8px; align-items: center; }
|
|
458
479
|
.create-section .aid-input-row input { flex: 1; padding: 10px 14px; border: 1px solid #ddd; border-radius: 8px; font-size: 14px; min-width: 0; }
|
|
459
480
|
.create-section .aid-input-row input:focus { outline: none; border-color: #007bff; }
|
|
460
481
|
.create-section .aid-input-row .dot-separator { color: #999; font-size: 16px; flex-shrink: 0; }
|
|
461
|
-
.create-section .aid-input-row select {
|
|
462
|
-
padding: 10px 30px 10px 14px;
|
|
463
|
-
border: 1px solid #ddd;
|
|
464
|
-
border-radius: 8px;
|
|
465
|
-
font-size: 14px;
|
|
466
|
-
background: white;
|
|
467
|
-
flex-shrink: 0;
|
|
468
|
-
cursor: pointer;
|
|
482
|
+
.create-section .aid-input-row select {
|
|
483
|
+
padding: 10px 30px 10px 14px;
|
|
484
|
+
border: 1px solid #ddd;
|
|
485
|
+
border-radius: 8px;
|
|
486
|
+
font-size: 14px;
|
|
487
|
+
background: white;
|
|
488
|
+
flex-shrink: 0;
|
|
489
|
+
cursor: pointer;
|
|
469
490
|
appearance: none;
|
|
470
491
|
-webkit-appearance: none;
|
|
471
492
|
-moz-appearance: none;
|
|
@@ -475,6 +496,9 @@ const indexHtml = `<!DOCTYPE html>
|
|
|
475
496
|
background-size: 10px auto;
|
|
476
497
|
}
|
|
477
498
|
.create-section .aid-input-row select:focus { outline: none; border-color: #007bff; }
|
|
499
|
+
.create-section .extra-fields { display: flex; gap: 8px; }
|
|
500
|
+
.create-section .extra-fields input { flex: 1; padding: 10px 14px; border: 1px solid #ddd; border-radius: 8px; font-size: 14px; min-width: 0; }
|
|
501
|
+
.create-section .extra-fields input:focus { outline: none; border-color: #007bff; }
|
|
478
502
|
.btn { display: block; width: 100%; padding: 12px; border: none; border-radius: 8px; font-size: 15px; cursor: pointer; transition: background 0.2s; }
|
|
479
503
|
.btn-primary { background: #007bff; color: white; }
|
|
480
504
|
.btn-primary:hover { background: #0056b3; }
|
|
@@ -520,9 +544,9 @@ const indexHtml = `<!DOCTYPE html>
|
|
|
520
544
|
<span class="dot-separator">.</span>
|
|
521
545
|
<select id="apSelect"></select>
|
|
522
546
|
</div>
|
|
523
|
-
<div
|
|
524
|
-
<input type="text" id="aidNickname" placeholder="昵称(选填)"
|
|
525
|
-
<input type="text" id="aidDescription" placeholder="描述(选填)" style="flex:2;
|
|
547
|
+
<div class="extra-fields">
|
|
548
|
+
<input type="text" id="aidNickname" placeholder="昵称(选填)">
|
|
549
|
+
<input type="text" id="aidDescription" placeholder="描述(选填)" style="flex:2;">
|
|
526
550
|
</div>
|
|
527
551
|
<button class="btn btn-primary" onclick="createAid()">注册 AID</button>
|
|
528
552
|
</div>
|
|
@@ -901,6 +925,7 @@ const chatHtml = `<!DOCTYPE html>
|
|
|
901
925
|
<div class="group-actions">
|
|
902
926
|
<div class="gbtn" onclick="showCreateGroupModal()">创建群组</div>
|
|
903
927
|
<div class="gbtn" onclick="showJoinGroupModal()">加入群组</div>
|
|
928
|
+
<div class="gbtn" onclick="showMyGroups()">我的群</div>
|
|
904
929
|
</div>
|
|
905
930
|
<div class="group-list" id="groupList"><div style="padding:20px;text-align:center;color:#999;font-size:12px;">暂无群组</div></div>
|
|
906
931
|
</div>
|
|
@@ -1003,6 +1028,15 @@ const chatHtml = `<!DOCTYPE html>
|
|
|
1003
1028
|
</div>
|
|
1004
1029
|
</div>
|
|
1005
1030
|
</div>
|
|
1031
|
+
<div class="modal-overlay" id="myGroupsModal">
|
|
1032
|
+
<div class="modal" style="max-width:560px;">
|
|
1033
|
+
<h3>我的群</h3>
|
|
1034
|
+
<div id="myGroupsContent" style="max-height:420px;overflow-y:auto;margin-bottom:16px;font-size:13px;"></div>
|
|
1035
|
+
<div class="modal-btns">
|
|
1036
|
+
<button class="mbtn mbtn-cancel" onclick="hideMyGroupsModal()">关闭</button>
|
|
1037
|
+
</div>
|
|
1038
|
+
</div>
|
|
1039
|
+
</div>
|
|
1006
1040
|
<script>
|
|
1007
1041
|
var S = { aid:'', sid:null, sessions:[], status:'disconnected', expanded:{}, sidebarOpen:true, aidList:[], closed:false, tab:'p2p', activeGroupId:null, groups:[], groupMsgs:[], groupTargetAid:'', isGroupCreator:false };
|
|
1008
1042
|
var D = {};
|
|
@@ -1782,6 +1816,39 @@ const chatHtml = `<!DOCTYPE html>
|
|
|
1782
1816
|
} catch(e){ alert('退出失败: '+e.message); }
|
|
1783
1817
|
}
|
|
1784
1818
|
|
|
1819
|
+
// ============================================================
|
|
1820
|
+
// 我的群 Functions
|
|
1821
|
+
// ============================================================
|
|
1822
|
+
function showMyGroupsModal(){ $('myGroupsModal').classList.add('show'); }
|
|
1823
|
+
function hideMyGroupsModal(){ $('myGroupsModal').classList.remove('show'); }
|
|
1824
|
+
async function showMyGroups(){
|
|
1825
|
+
showMyGroupsModal();
|
|
1826
|
+
$('myGroupsContent').innerHTML='<div style="text-align:center;padding:20px;color:#999;">加载中...</div>';
|
|
1827
|
+
try {
|
|
1828
|
+
var r=await fetch('/api/group/my-groups');
|
|
1829
|
+
var d=await r.json();
|
|
1830
|
+
if(!d.success){ $('myGroupsContent').innerHTML='<div style="text-align:center;padding:20px;color:#e74c3c;">'+escH(d.error||'获取失败')+'</div>'; return; }
|
|
1831
|
+
var groups=d.groups||[];
|
|
1832
|
+
if(!groups.length){ $('myGroupsContent').innerHTML='<div style="text-align:center;padding:20px;color:#999;">暂无群组</div>'; return; }
|
|
1833
|
+
var html='<table style="width:100%;border-collapse:collapse;font-size:12px;">';
|
|
1834
|
+
html+='<tr style="background:#f8fafc;"><th style="padding:8px 6px;text-align:left;border-bottom:1px solid #e2e8f0;">群名称</th><th style="padding:8px 6px;text-align:left;border-bottom:1px solid #e2e8f0;">群ID</th><th style="padding:8px 6px;text-align:center;border-bottom:1px solid #e2e8f0;">角色</th><th style="padding:8px 6px;text-align:center;border-bottom:1px solid #e2e8f0;">状态</th></tr>';
|
|
1835
|
+
groups.forEach(function(g){
|
|
1836
|
+
var statusText=g.status===1?'正常':g.status===0?'待审核':'未知('+g.status+')';
|
|
1837
|
+
var statusColor=g.status===1?'#10b981':g.status===0?'#f59e0b':'#94a3b8';
|
|
1838
|
+
var shortId=g.group_id.length>16?g.group_id.substring(0,16)+'...':g.group_id;
|
|
1839
|
+
html+='<tr style="border-bottom:1px solid #f1f5f9;cursor:pointer;" onmouseover="this.style.background=\\'#f0f9ff\\'" onmouseout="this.style.background=\\'\\'">';
|
|
1840
|
+
html+='<td style="padding:8px 6px;font-weight:500;">'+escH(g.name||g.group_id)+'</td>';
|
|
1841
|
+
html+='<td style="padding:8px 6px;color:#64748b;" title="'+escH(g.group_id)+'">'+escH(shortId)+'</td>';
|
|
1842
|
+
html+='<td style="padding:8px 6px;text-align:center;">'+escH(g.role||'-')+'</td>';
|
|
1843
|
+
html+='<td style="padding:8px 6px;text-align:center;"><span style="color:'+statusColor+';font-weight:500;">'+escH(statusText)+'</span></td>';
|
|
1844
|
+
html+='</tr>';
|
|
1845
|
+
});
|
|
1846
|
+
html+='</table>';
|
|
1847
|
+
html+='<div style="margin-top:8px;font-size:11px;color:#94a3b8;text-align:right;">共 '+d.total+' 个群组</div>';
|
|
1848
|
+
$('myGroupsContent').innerHTML=html;
|
|
1849
|
+
} catch(e){ $('myGroupsContent').innerHTML='<div style="text-align:center;padding:20px;color:#e74c3c;">请求失败: '+escH(e.message)+'</div>'; }
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1785
1852
|
// 扩展轮询:群组模式下也轮询群消息
|
|
1786
1853
|
var _origPoll=poll;
|
|
1787
1854
|
poll=async function(){
|
|
@@ -2389,6 +2456,9 @@ async function handleRequest(req, res) {
|
|
|
2389
2456
|
}
|
|
2390
2457
|
catch (_) { }
|
|
2391
2458
|
instance.agentCP.addGroupToStore(groupId, groupName);
|
|
2459
|
+
// 注册到 Home AP
|
|
2460
|
+
const registrationUrl = `https://${targetAid}/${groupId}`;
|
|
2461
|
+
await instance.agentCP.registerGroupToHomeAP(groupId, registrationUrl);
|
|
2392
2462
|
sendJson(res, { success: true, group_id: groupId });
|
|
2393
2463
|
}
|
|
2394
2464
|
else {
|
|
@@ -2454,6 +2524,31 @@ async function handleRequest(req, res) {
|
|
|
2454
2524
|
}
|
|
2455
2525
|
return;
|
|
2456
2526
|
}
|
|
2527
|
+
if (pathname === '/api/group/my-groups' && method === 'GET') {
|
|
2528
|
+
try {
|
|
2529
|
+
const instance = await ensureOnline();
|
|
2530
|
+
await ensureGroupClient(instance);
|
|
2531
|
+
const ops = instance.agentCP.groupOps;
|
|
2532
|
+
const target = instance.groupTargetAid;
|
|
2533
|
+
const result = await ops.listMyGroups(target);
|
|
2534
|
+
// 尝试获取每个群的详细信息(名称等)
|
|
2535
|
+
const groups = [];
|
|
2536
|
+
for (const m of result.groups) {
|
|
2537
|
+
let name = m.group_id;
|
|
2538
|
+
try {
|
|
2539
|
+
const info = await ops.getGroupInfo(target, m.group_id);
|
|
2540
|
+
name = info.name || m.group_id;
|
|
2541
|
+
}
|
|
2542
|
+
catch (_) { }
|
|
2543
|
+
groups.push(Object.assign(Object.assign({}, m), { name }));
|
|
2544
|
+
}
|
|
2545
|
+
sendJson(res, { success: true, groups, total: result.total });
|
|
2546
|
+
}
|
|
2547
|
+
catch (e) {
|
|
2548
|
+
sendJson(res, { success: false, error: e.message, groups: [] });
|
|
2549
|
+
}
|
|
2550
|
+
return;
|
|
2551
|
+
}
|
|
2457
2552
|
if (pathname === '/api/group/leave' && method === 'POST') {
|
|
2458
2553
|
try {
|
|
2459
2554
|
const body = await parseBody(req);
|