acp-ts 1.2.3 → 1.2.5
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 +49 -42
- 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.d.ts +2 -0
- package/dist/datamanager.js +34 -14
- 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 -2
- package/dist/group/events.js +7 -27
- package/dist/group/index.d.ts +1 -1
- package/dist/group/index.js +2 -2
- package/dist/group/message_store.d.ts +5 -6
- package/dist/group/message_store.js +66 -72
- package/dist/group/operations.d.ts +1 -5
- package/dist/group/operations.js +13 -18
- package/dist/group/types.d.ts +3 -29
- package/dist/group/types.js +2 -6
- package/dist/heartbeat.js +24 -24
- package/dist/messagestore.js +9 -8
- package/dist/server.js +2210 -1708
- 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/datamanager.js
CHANGED
|
@@ -33,9 +33,29 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.CertAndKeyStore = void 0;
|
|
36
|
+
exports.CertAndKeyStore = exports.DEFAULT_ACP_DIR = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
// 默认数据目录:用户主目录下的 acp 文件夹
|
|
41
|
+
const DEFAULT_ACP_DIR = path.join(os.homedir(), 'acp');
|
|
42
|
+
exports.DEFAULT_ACP_DIR = DEFAULT_ACP_DIR;
|
|
43
|
+
// 本地 logger(避免与 utils.ts 循环依赖)
|
|
44
|
+
function _ts() {
|
|
45
|
+
const n = new Date();
|
|
46
|
+
const y = n.getFullYear();
|
|
47
|
+
const m = String(n.getMonth() + 1).padStart(2, '0');
|
|
48
|
+
const d = String(n.getDate()).padStart(2, '0');
|
|
49
|
+
const h = String(n.getHours()).padStart(2, '0');
|
|
50
|
+
const min = String(n.getMinutes()).padStart(2, '0');
|
|
51
|
+
const s = String(n.getSeconds()).padStart(2, '0');
|
|
52
|
+
return `${y}/${m}/${d} ${h}:${min}:${s}`;
|
|
53
|
+
}
|
|
54
|
+
const logger = {
|
|
55
|
+
log: (...args) => console.log(`[${_ts()}]`, ...args),
|
|
56
|
+
warn: (...args) => console.warn(`[${_ts()}]`, ...args),
|
|
57
|
+
error: (...args) => console.error(`[${_ts()}]`, ...args),
|
|
58
|
+
};
|
|
39
59
|
// 统一的环境检测函数
|
|
40
60
|
const isNodeEnvironment = typeof process !== 'undefined' &&
|
|
41
61
|
process.versions != null &&
|
|
@@ -56,7 +76,7 @@ class NodeStorage {
|
|
|
56
76
|
this.initialized = true;
|
|
57
77
|
}
|
|
58
78
|
catch (e) {
|
|
59
|
-
|
|
79
|
+
logger.error('NodeStorage init error:', e);
|
|
60
80
|
this.cache = {};
|
|
61
81
|
this.initialized = true;
|
|
62
82
|
}
|
|
@@ -66,7 +86,7 @@ class NodeStorage {
|
|
|
66
86
|
fs.writeFileSync(this.dataFile, JSON.stringify(this.cache, null, 2));
|
|
67
87
|
}
|
|
68
88
|
catch (e) {
|
|
69
|
-
|
|
89
|
+
logger.error('NodeStorage save error:', e);
|
|
70
90
|
}
|
|
71
91
|
}
|
|
72
92
|
static async setItem(key, value) {
|
|
@@ -80,7 +100,7 @@ class NodeStorage {
|
|
|
80
100
|
return (_a = this.cache[key]) !== null && _a !== void 0 ? _a : null;
|
|
81
101
|
}
|
|
82
102
|
}
|
|
83
|
-
NodeStorage.dataDir = path.join(
|
|
103
|
+
NodeStorage.dataDir = path.join(DEFAULT_ACP_DIR, '.acp-data');
|
|
84
104
|
NodeStorage.dataFile = path.join(NodeStorage.dataDir, 'storage.json');
|
|
85
105
|
NodeStorage.cache = {};
|
|
86
106
|
NodeStorage.initialized = false;
|
|
@@ -96,7 +116,7 @@ else {
|
|
|
96
116
|
}
|
|
97
117
|
catch (e) {
|
|
98
118
|
// 如果加载失败,使用内存存储作为后备
|
|
99
|
-
|
|
119
|
+
logger.warn('AsyncStorage not available, using memory storage');
|
|
100
120
|
const memoryStore = {};
|
|
101
121
|
AsyncStorage = {
|
|
102
122
|
setItem: async (key, value) => { memoryStore[key] = value; },
|
|
@@ -117,7 +137,7 @@ class CertAndKeyStore {
|
|
|
117
137
|
await AsyncStorage.setItem(key, JSON.stringify(value));
|
|
118
138
|
}
|
|
119
139
|
catch (e) {
|
|
120
|
-
|
|
140
|
+
logger.error(e);
|
|
121
141
|
}
|
|
122
142
|
}
|
|
123
143
|
// 获取数据(仍用 storage.json,用于会话/消息)
|
|
@@ -136,7 +156,7 @@ class CertAndKeyStore {
|
|
|
136
156
|
return parsed;
|
|
137
157
|
}
|
|
138
158
|
catch (e) {
|
|
139
|
-
|
|
159
|
+
logger.error(e);
|
|
140
160
|
return null;
|
|
141
161
|
}
|
|
142
162
|
}
|
|
@@ -152,7 +172,7 @@ class CertAndKeyStore {
|
|
|
152
172
|
return null;
|
|
153
173
|
}
|
|
154
174
|
catch (e) {
|
|
155
|
-
|
|
175
|
+
logger.error('获取访客ID失败:', e);
|
|
156
176
|
return null;
|
|
157
177
|
}
|
|
158
178
|
}
|
|
@@ -173,7 +193,7 @@ class CertAndKeyStore {
|
|
|
173
193
|
}).map(e => e.name);
|
|
174
194
|
}
|
|
175
195
|
catch (e) {
|
|
176
|
-
|
|
196
|
+
logger.error('扫描 AIDs 目录失败:', e);
|
|
177
197
|
return [];
|
|
178
198
|
}
|
|
179
199
|
}
|
|
@@ -189,7 +209,7 @@ class CertAndKeyStore {
|
|
|
189
209
|
}
|
|
190
210
|
}
|
|
191
211
|
catch (e) {
|
|
192
|
-
|
|
212
|
+
logger.error('创建 AID 目录失败:', e);
|
|
193
213
|
}
|
|
194
214
|
}
|
|
195
215
|
static async getCertificate(aid) {
|
|
@@ -201,7 +221,7 @@ class CertAndKeyStore {
|
|
|
201
221
|
return null;
|
|
202
222
|
}
|
|
203
223
|
catch (e) {
|
|
204
|
-
|
|
224
|
+
logger.error('读取证书失败:', e);
|
|
205
225
|
return null;
|
|
206
226
|
}
|
|
207
227
|
}
|
|
@@ -219,7 +239,7 @@ class CertAndKeyStore {
|
|
|
219
239
|
return null;
|
|
220
240
|
}
|
|
221
241
|
catch (e) {
|
|
222
|
-
|
|
242
|
+
logger.error('读取 CSR 失败:', e);
|
|
223
243
|
return null;
|
|
224
244
|
}
|
|
225
245
|
}
|
|
@@ -242,11 +262,11 @@ class CertAndKeyStore {
|
|
|
242
262
|
return null;
|
|
243
263
|
}
|
|
244
264
|
catch (error) {
|
|
245
|
-
|
|
265
|
+
logger.error('获取私钥失败:', error);
|
|
246
266
|
throw new Error('获取私钥失败');
|
|
247
267
|
}
|
|
248
268
|
}
|
|
249
269
|
}
|
|
250
270
|
exports.CertAndKeyStore = CertAndKeyStore;
|
|
251
271
|
CertAndKeyStore.aidKey = 'currentAidKey';
|
|
252
|
-
CertAndKeyStore.basePath =
|
|
272
|
+
CertAndKeyStore.basePath = DEFAULT_ACP_DIR;
|
package/dist/filesync.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.FileSync = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const utils_1 = require("./utils");
|
|
8
9
|
// 环境检测(与项目其他模块保持一致)
|
|
9
10
|
const isNodeEnvironment = typeof process !== 'undefined' &&
|
|
10
11
|
process.versions != null &&
|
|
@@ -75,7 +76,7 @@ class FileSync {
|
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
78
|
catch (error) {
|
|
78
|
-
|
|
79
|
+
utils_1.logger.error(`处理文件 ${fullPath} 时出错:`, error);
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
}
|
|
@@ -112,7 +113,7 @@ class FileSync {
|
|
|
112
113
|
return { success: false };
|
|
113
114
|
}
|
|
114
115
|
catch (error) {
|
|
115
|
-
|
|
116
|
+
utils_1.logger.error(`上传文件失败 [${fileName}]:`, error);
|
|
116
117
|
return { success: false };
|
|
117
118
|
}
|
|
118
119
|
}
|
|
@@ -144,13 +145,13 @@ class FileSync {
|
|
|
144
145
|
return new Promise((resolve, reject) => {
|
|
145
146
|
writer.on('finish', () => resolve(true));
|
|
146
147
|
writer.on('error', (err) => {
|
|
147
|
-
|
|
148
|
+
utils_1.logger.error(`写入文件失败 [${fileName}]:`, err);
|
|
148
149
|
resolve(false);
|
|
149
150
|
});
|
|
150
151
|
});
|
|
151
152
|
}
|
|
152
153
|
catch (error) {
|
|
153
|
-
|
|
154
|
+
utils_1.logger.error(`下载文件失败 [${fileName}]:`, error);
|
|
154
155
|
return false;
|
|
155
156
|
}
|
|
156
157
|
}
|
|
@@ -224,11 +225,11 @@ class FileSync {
|
|
|
224
225
|
const uploadResult = await this.uploadFile(fullPath, fileName);
|
|
225
226
|
if (uploadResult.success) {
|
|
226
227
|
result.uploadedFiles.push(fileName);
|
|
227
|
-
|
|
228
|
+
utils_1.logger.log(`文件 ${fileName} 上传成功 => ${uploadResult.url}`);
|
|
228
229
|
}
|
|
229
230
|
else {
|
|
230
231
|
result.uploadFailedFiles.push(fileName);
|
|
231
|
-
|
|
232
|
+
utils_1.logger.error(`文件 ${fileName} 上传失败`);
|
|
232
233
|
}
|
|
233
234
|
}
|
|
234
235
|
// 4. 下载需要下载的文件
|
|
@@ -239,11 +240,11 @@ class FileSync {
|
|
|
239
240
|
const success = await this.downloadFile(fileName, savePath);
|
|
240
241
|
if (success) {
|
|
241
242
|
result.downloadedFiles.push(fileName);
|
|
242
|
-
|
|
243
|
+
utils_1.logger.log(`文件 ${fileName} 下载成功,保存路径: ${savePath}`);
|
|
243
244
|
}
|
|
244
245
|
else {
|
|
245
246
|
result.downloadFailedFiles.push(fileName);
|
|
246
|
-
|
|
247
|
+
utils_1.logger.error(`文件 ${fileName} 下载失败`);
|
|
247
248
|
}
|
|
248
249
|
}
|
|
249
250
|
// 判断最终状态
|
|
@@ -255,7 +256,7 @@ class FileSync {
|
|
|
255
256
|
result.status = 'error';
|
|
256
257
|
result.error = error.message || '同步过程中发生错误';
|
|
257
258
|
this.updateStatus('error');
|
|
258
|
-
|
|
259
|
+
utils_1.logger.error('sync_public_files 错误:', error);
|
|
259
260
|
}
|
|
260
261
|
return result;
|
|
261
262
|
}
|
|
@@ -322,7 +323,7 @@ class FileSync {
|
|
|
322
323
|
}
|
|
323
324
|
catch (error) {
|
|
324
325
|
const errorMsg = ((_c = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.message) || error.message || '上传 agent.md 失败';
|
|
325
|
-
|
|
326
|
+
utils_1.logger.error('uploadAgentMd 错误:', errorMsg);
|
|
326
327
|
return { success: false, error: errorMsg };
|
|
327
328
|
}
|
|
328
329
|
}
|
package/dist/group/client.js
CHANGED
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.ACPGroupClient = void 0;
|
|
11
11
|
const types_1 = require("./types");
|
|
12
12
|
const events_1 = require("./events");
|
|
13
|
+
const utils_1 = require("../utils");
|
|
13
14
|
class ACPGroupClient {
|
|
14
15
|
constructor(agentId, sendFunc) {
|
|
15
16
|
this._pendingReqs = new Map();
|
|
@@ -47,23 +48,23 @@ class ACPGroupClient {
|
|
|
47
48
|
const req = (0, types_1.buildGroupRequest)(action, reqId, groupId, params);
|
|
48
49
|
const payload = JSON.stringify(req);
|
|
49
50
|
const effectiveTimeout = timeout !== null && timeout !== void 0 ? timeout : this._reqTimeout;
|
|
50
|
-
//
|
|
51
|
-
//
|
|
51
|
+
// logger.log(`[GroupClient] >>> sendRequest: action=${action} group=${groupId} reqId=${reqId} target=${targetAid}`);
|
|
52
|
+
// logger.log(`[GroupClient] >>> payload: ${payload}`);
|
|
52
53
|
return new Promise((resolve, reject) => {
|
|
53
54
|
const timer = setTimeout(() => {
|
|
54
55
|
this._pendingReqs.delete(reqId);
|
|
55
|
-
|
|
56
|
+
utils_1.logger.error(`[GroupClient] !!! TIMEOUT: action=${action} group=${groupId} reqId=${reqId}, pendingReqs remaining: [${Array.from(this._pendingReqs.keys()).join(', ')}]`);
|
|
56
57
|
reject(new Error(`request timeout: action=${action} group=${groupId}`));
|
|
57
58
|
}, effectiveTimeout);
|
|
58
59
|
this._pendingReqs.set(reqId, { resolve, reject, timer });
|
|
59
60
|
try {
|
|
60
61
|
this._sendFunc(targetAid, payload);
|
|
61
|
-
//
|
|
62
|
+
// logger.log(`[GroupClient] >>> sendFunc called OK`);
|
|
62
63
|
}
|
|
63
64
|
catch (e) {
|
|
64
65
|
clearTimeout(timer);
|
|
65
66
|
this._pendingReqs.delete(reqId);
|
|
66
|
-
|
|
67
|
+
utils_1.logger.error(`[GroupClient] !!! sendFunc error:`, e);
|
|
67
68
|
reject(e instanceof Error ? e : new Error(String(e)));
|
|
68
69
|
}
|
|
69
70
|
});
|
|
@@ -74,13 +75,13 @@ class ACPGroupClient {
|
|
|
74
75
|
* Called by the message dispatch chain in AgentCP.
|
|
75
76
|
*/
|
|
76
77
|
handleIncoming(payload) {
|
|
77
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
78
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
78
79
|
let data;
|
|
79
80
|
try {
|
|
80
81
|
data = JSON.parse(payload);
|
|
81
82
|
}
|
|
82
83
|
catch (e) {
|
|
83
|
-
|
|
84
|
+
utils_1.logger.error(`[GroupClient] JSON.parse failed for incoming payload:`, e);
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
86
87
|
// Try as response (has request_id)
|
|
@@ -101,7 +102,7 @@ class ACPGroupClient {
|
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
103
104
|
else {
|
|
104
|
-
|
|
105
|
+
utils_1.logger.warn(`[GroupClient] !!! request_id=${requestId} NOT found in pendingReqs. Current pending: [${Array.from(this._pendingReqs.keys()).join(', ')}]`);
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
// Try as notification (has event field)
|
|
@@ -112,41 +113,50 @@ class ACPGroupClient {
|
|
|
112
113
|
(0, events_1.dispatchAcpNotify)(this._handler, notify);
|
|
113
114
|
}
|
|
114
115
|
else {
|
|
115
|
-
|
|
116
|
+
utils_1.logger.warn(`[GroupClient] !!! notification event="${event}" dropped: no event handler registered. Call setEventHandler() first.`);
|
|
116
117
|
}
|
|
117
118
|
return;
|
|
118
119
|
}
|
|
119
|
-
// Handle
|
|
120
|
+
// Handle action-based push messages from group.ap (e.g. message_push)
|
|
121
|
+
// These have action field but no event/request_id, need to be mapped to notification events
|
|
120
122
|
const action = (_d = data.action) !== null && _d !== void 0 ? _d : "";
|
|
121
|
-
if (action ===
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
count: (_h = batchData.count) !== null && _h !== void 0 ? _h : 0,
|
|
123
|
+
if (action === "message_push" && data.data) {
|
|
124
|
+
utils_1.logger.log(`[GroupClient] message_push -> group_message: group=${data.group_id} msg_id=${data.data.msg_id}`);
|
|
125
|
+
const msgData = data.data;
|
|
126
|
+
const notify = {
|
|
127
|
+
action: "group_notify",
|
|
128
|
+
group_id: (_e = data.group_id) !== null && _e !== void 0 ? _e : "",
|
|
129
|
+
event: types_1.NOTIFY_GROUP_MESSAGE,
|
|
130
|
+
data: {
|
|
131
|
+
msg_id: (_f = msgData.msg_id) !== null && _f !== void 0 ? _f : 0,
|
|
132
|
+
sender: (_g = msgData.sender) !== null && _g !== void 0 ? _g : "",
|
|
133
|
+
content: (_h = msgData.content) !== null && _h !== void 0 ? _h : "",
|
|
134
|
+
content_type: (_j = msgData.content_type) !== null && _j !== void 0 ? _j : "text",
|
|
135
|
+
timestamp: (_k = msgData.timestamp) !== null && _k !== void 0 ? _k : 0,
|
|
136
|
+
metadata: (_l = msgData.metadata) !== null && _l !== void 0 ? _l : null,
|
|
137
|
+
},
|
|
138
|
+
timestamp: (_m = msgData.timestamp) !== null && _m !== void 0 ? _m : 0,
|
|
138
139
|
};
|
|
139
|
-
const groupId = (_j = data.group_id) !== null && _j !== void 0 ? _j : "";
|
|
140
|
-
console.log(`[GroupClient] message_batch_push: group=${groupId} count=${batch.count} range=[${batch.start_msg_id}, ${batch.latest_msg_id}]`);
|
|
141
140
|
if (this._handler != null) {
|
|
142
|
-
this._handler
|
|
141
|
+
(0, events_1.dispatchAcpNotify)(this._handler, notify);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
utils_1.logger.warn(`[GroupClient] !!! message_push dropped: no event handler registered.`);
|
|
145
|
+
}
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (action === "message_batch_push" && data.data) {
|
|
149
|
+
const batch = data.data;
|
|
150
|
+
utils_1.logger.log(`[GroupClient] message_batch_push -> onGroupMessageBatch: group=${data.group_id} count=${batch.count} range=[${batch.start_msg_id}, ${batch.latest_msg_id}]`);
|
|
151
|
+
if (this._handler != null) {
|
|
152
|
+
this._handler.onGroupMessageBatch((_o = data.group_id) !== null && _o !== void 0 ? _o : "", batch);
|
|
143
153
|
}
|
|
144
154
|
else {
|
|
145
|
-
|
|
155
|
+
utils_1.logger.warn(`[GroupClient] !!! message_batch_push dropped: no event handler registered.`);
|
|
146
156
|
}
|
|
147
157
|
return;
|
|
148
158
|
}
|
|
149
|
-
|
|
159
|
+
utils_1.logger.warn(`[GroupClient] !!! unhandled incoming message: no request_id and no event field`, JSON.stringify(data).substring(0, 300));
|
|
150
160
|
}
|
|
151
161
|
// -- Lifecycle --
|
|
152
162
|
/**
|
|
@@ -160,12 +170,10 @@ class ACPGroupClient {
|
|
|
160
170
|
this._pendingReqs.clear();
|
|
161
171
|
if (this._cursorStore != null) {
|
|
162
172
|
try {
|
|
163
|
-
this._cursorStore.close()
|
|
164
|
-
console.error("[ACPGroupClient] cursor store close error:", e);
|
|
165
|
-
});
|
|
173
|
+
this._cursorStore.close();
|
|
166
174
|
}
|
|
167
175
|
catch (e) {
|
|
168
|
-
|
|
176
|
+
utils_1.logger.error("[ACPGroupClient] cursor store close error:", e);
|
|
169
177
|
}
|
|
170
178
|
}
|
|
171
179
|
}
|
|
@@ -10,8 +10,8 @@ export interface CursorStore {
|
|
|
10
10
|
saveEventCursor(groupId: string, eventCursor: number): void;
|
|
11
11
|
loadCursor(groupId: string): [number, number];
|
|
12
12
|
removeCursor(groupId: string): void;
|
|
13
|
-
flush():
|
|
14
|
-
close():
|
|
13
|
+
flush(): void;
|
|
14
|
+
close(): void;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* In-memory + JSON file cursor store.
|
|
@@ -24,18 +24,13 @@ export declare class LocalCursorStore implements CursorStore {
|
|
|
24
24
|
private _cursors;
|
|
25
25
|
private _filePath;
|
|
26
26
|
private _dirty;
|
|
27
|
-
private _flushTimer;
|
|
28
|
-
private _flushPromise;
|
|
29
|
-
private _loaded;
|
|
30
27
|
constructor(filePath?: string);
|
|
31
|
-
init(): Promise<void>;
|
|
32
28
|
saveMsgCursor(groupId: string, msgCursor: number): void;
|
|
33
29
|
saveEventCursor(groupId: string, eventCursor: number): void;
|
|
34
30
|
loadCursor(groupId: string): [number, number];
|
|
35
31
|
removeCursor(groupId: string): void;
|
|
36
|
-
flush():
|
|
37
|
-
close():
|
|
38
|
-
private _flushDebounced;
|
|
32
|
+
flush(): void;
|
|
33
|
+
close(): void;
|
|
39
34
|
private _write;
|
|
40
35
|
private _load;
|
|
41
36
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.LocalCursorStore = void 0;
|
|
8
8
|
const websocket_1 = require("../websocket");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
9
10
|
/**
|
|
10
11
|
* In-memory + JSON file cursor store.
|
|
11
12
|
*
|
|
@@ -17,15 +18,9 @@ class LocalCursorStore {
|
|
|
17
18
|
constructor(filePath = "") {
|
|
18
19
|
this._cursors = {};
|
|
19
20
|
this._dirty = false;
|
|
20
|
-
this._flushTimer = null;
|
|
21
|
-
this._flushPromise = null;
|
|
22
|
-
this._loaded = false;
|
|
23
21
|
this._filePath = filePath;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (this._filePath && websocket_1.isNodeEnvironment && !this._loaded) {
|
|
27
|
-
await this._load();
|
|
28
|
-
this._loaded = true;
|
|
22
|
+
if (filePath && websocket_1.isNodeEnvironment) {
|
|
23
|
+
this._load();
|
|
29
24
|
}
|
|
30
25
|
}
|
|
31
26
|
saveMsgCursor(groupId, msgCursor) {
|
|
@@ -35,7 +30,6 @@ class LocalCursorStore {
|
|
|
35
30
|
if (msgCursor > this._cursors[groupId].msg_cursor) {
|
|
36
31
|
this._cursors[groupId].msg_cursor = msgCursor;
|
|
37
32
|
this._dirty = true;
|
|
38
|
-
this._flushDebounced();
|
|
39
33
|
}
|
|
40
34
|
}
|
|
41
35
|
saveEventCursor(groupId, eventCursor) {
|
|
@@ -45,7 +39,6 @@ class LocalCursorStore {
|
|
|
45
39
|
if (eventCursor > this._cursors[groupId].event_cursor) {
|
|
46
40
|
this._cursors[groupId].event_cursor = eventCursor;
|
|
47
41
|
this._dirty = true;
|
|
48
|
-
this._flushDebounced();
|
|
49
42
|
}
|
|
50
43
|
}
|
|
51
44
|
loadCursor(groupId) {
|
|
@@ -59,58 +52,37 @@ class LocalCursorStore {
|
|
|
59
52
|
if (groupId in this._cursors) {
|
|
60
53
|
delete this._cursors[groupId];
|
|
61
54
|
this._dirty = true;
|
|
62
|
-
this._flushDebounced();
|
|
63
55
|
}
|
|
64
56
|
}
|
|
65
|
-
|
|
57
|
+
flush() {
|
|
66
58
|
if (!this._filePath || !websocket_1.isNodeEnvironment) {
|
|
67
59
|
return;
|
|
68
60
|
}
|
|
69
61
|
if (!this._dirty) {
|
|
70
62
|
return;
|
|
71
63
|
}
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
async close() {
|
|
75
|
-
if (this._flushTimer) {
|
|
76
|
-
clearTimeout(this._flushTimer);
|
|
77
|
-
this._flushTimer = null;
|
|
78
|
-
}
|
|
79
|
-
await this.flush();
|
|
64
|
+
this._write();
|
|
80
65
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return;
|
|
84
|
-
this._flushTimer = setTimeout(async () => {
|
|
85
|
-
this._flushTimer = null;
|
|
86
|
-
try {
|
|
87
|
-
await this.flush();
|
|
88
|
-
}
|
|
89
|
-
catch (e) {
|
|
90
|
-
console.error('[CursorStore] debounced flush failed:', e);
|
|
91
|
-
}
|
|
92
|
-
}, 500);
|
|
66
|
+
close() {
|
|
67
|
+
this.flush();
|
|
93
68
|
}
|
|
94
|
-
|
|
69
|
+
_write() {
|
|
95
70
|
try {
|
|
96
71
|
const fs = require('fs');
|
|
97
|
-
|
|
98
|
-
const tmpPath = this._filePath + '.tmp';
|
|
99
|
-
await fs.promises.writeFile(tmpPath, content, 'utf-8');
|
|
100
|
-
await fs.promises.rename(tmpPath, this._filePath);
|
|
72
|
+
fs.writeFileSync(this._filePath, JSON.stringify(this._cursors, null, 2), 'utf-8');
|
|
101
73
|
this._dirty = false;
|
|
102
74
|
}
|
|
103
75
|
catch (e) {
|
|
104
|
-
|
|
76
|
+
utils_1.logger.error(`[CursorStore] write to ${this._filePath} failed:`, e);
|
|
105
77
|
}
|
|
106
78
|
}
|
|
107
|
-
|
|
79
|
+
_load() {
|
|
108
80
|
try {
|
|
109
81
|
const fs = require('fs');
|
|
110
82
|
if (!fs.existsSync(this._filePath)) {
|
|
111
83
|
return;
|
|
112
84
|
}
|
|
113
|
-
const content =
|
|
85
|
+
const content = fs.readFileSync(this._filePath, 'utf-8');
|
|
114
86
|
if (content) {
|
|
115
87
|
this._cursors = JSON.parse(content);
|
|
116
88
|
}
|
package/dist/group/events.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Group event handler interfaces and dispatch logic.
|
|
3
3
|
* Mirrors Python SDK: agentcp/group/events.py
|
|
4
4
|
*/
|
|
5
|
-
import { GroupNotify, GroupEvent, GroupMessageBatch
|
|
5
|
+
import { GroupNotify, GroupMessage, GroupEvent, GroupMessageBatch } from './types';
|
|
6
6
|
/**
|
|
7
7
|
* Abstract handler for ACP group notifications.
|
|
8
8
|
*/
|
|
@@ -13,9 +13,9 @@ export interface ACPGroupEventHandler {
|
|
|
13
13
|
onJoinApproved(groupId: string, groupAddress: string): void;
|
|
14
14
|
onJoinRejected(groupId: string, reason: string): void;
|
|
15
15
|
onJoinRequestReceived(groupId: string, agentId: string, message: string): void;
|
|
16
|
+
onGroupMessage?(groupId: string, msg: GroupMessage): void;
|
|
16
17
|
onGroupMessageBatch(groupId: string, batch: GroupMessageBatch): void;
|
|
17
18
|
onGroupEvent(groupId: string, evt: GroupEvent): void;
|
|
18
|
-
onDutyDispatch(groupId: string, context: DutyContext): void;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Abstract handler for structured group events (from MSG/Session).
|
package/dist/group/events.js
CHANGED
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.dispatchAcpNotify = dispatchAcpNotify;
|
|
8
8
|
exports.dispatchEvent = dispatchEvent;
|
|
9
|
+
const utils_1 = require("../utils");
|
|
9
10
|
const types_1 = require("./types");
|
|
10
11
|
/**
|
|
11
12
|
* Dispatch an ACP group notification to the handler.
|
|
12
13
|
* Returns true if dispatched, false if unrecognized or handler/notify is null.
|
|
13
14
|
*/
|
|
14
15
|
function dispatchAcpNotify(handler, notify) {
|
|
15
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o
|
|
16
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
16
17
|
if (handler == null || notify == null) {
|
|
17
18
|
return false;
|
|
18
19
|
}
|
|
@@ -38,40 +39,19 @@ function dispatchAcpNotify(handler, notify) {
|
|
|
38
39
|
else if (event === types_1.NOTIFY_JOIN_REQUEST_RECEIVED) {
|
|
39
40
|
handler.onJoinRequestReceived(gid, (_l = data.agent_id) !== null && _l !== void 0 ? _l : "", (_m = data.message) !== null && _m !== void 0 ? _m : "");
|
|
40
41
|
}
|
|
42
|
+
else if (event === types_1.NOTIFY_GROUP_MESSAGE) {
|
|
43
|
+
(_o = handler.onGroupMessage) === null || _o === void 0 ? void 0 : _o.call(handler, gid, data);
|
|
44
|
+
}
|
|
41
45
|
else if (event === types_1.NOTIFY_GROUP_EVENT) {
|
|
42
46
|
handler.onGroupEvent(gid, data);
|
|
43
47
|
}
|
|
44
|
-
else if (event === types_1.NOTIFY_DUTY_DISPATCH) {
|
|
45
|
-
const context = {
|
|
46
|
-
needs_dispatch: (_o = data.needs_dispatch) !== null && _o !== void 0 ? _o : false,
|
|
47
|
-
original_msg_id: (_p = data.original_msg_id) !== null && _p !== void 0 ? _p : 0,
|
|
48
|
-
sender_id: (_q = data.sender_id) !== null && _q !== void 0 ? _q : "",
|
|
49
|
-
sender_type: (_r = data.sender_type) !== null && _r !== void 0 ? _r : "",
|
|
50
|
-
group_member_count: (_s = data.group_member_count) !== null && _s !== void 0 ? _s : 0,
|
|
51
|
-
online_ai_members: ((_t = data.online_ai_members) !== null && _t !== void 0 ? _t : []).map((m) => {
|
|
52
|
-
var _a, _b;
|
|
53
|
-
return ({
|
|
54
|
-
agent_id: (_a = m.agent_id) !== null && _a !== void 0 ? _a : "",
|
|
55
|
-
agent_type: (_b = m.agent_type) !== null && _b !== void 0 ? _b : "",
|
|
56
|
-
});
|
|
57
|
-
}),
|
|
58
|
-
human_members: ((_u = data.human_members) !== null && _u !== void 0 ? _u : []).map((m) => {
|
|
59
|
-
var _a, _b;
|
|
60
|
-
return ({
|
|
61
|
-
agent_id: (_a = m.agent_id) !== null && _a !== void 0 ? _a : "",
|
|
62
|
-
agent_type: (_b = m.agent_type) !== null && _b !== void 0 ? _b : "",
|
|
63
|
-
});
|
|
64
|
-
}),
|
|
65
|
-
};
|
|
66
|
-
handler.onDutyDispatch(gid, context);
|
|
67
|
-
}
|
|
68
48
|
else {
|
|
69
49
|
return false;
|
|
70
50
|
}
|
|
71
51
|
return true;
|
|
72
52
|
}
|
|
73
53
|
catch (e) {
|
|
74
|
-
|
|
54
|
+
utils_1.logger.error(`[GroupEvents] dispatch error for event=${event}:`, e);
|
|
75
55
|
return false;
|
|
76
56
|
}
|
|
77
57
|
}
|
|
@@ -145,7 +125,7 @@ function dispatchEvent(processor, msgType, payload) {
|
|
|
145
125
|
return true;
|
|
146
126
|
}
|
|
147
127
|
catch (e) {
|
|
148
|
-
|
|
128
|
+
utils_1.logger.error(`[GroupEvents] dispatch_event error for ${event}:`, e);
|
|
149
129
|
return false;
|
|
150
130
|
}
|
|
151
131
|
}
|
package/dist/group/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* ACP Group Operations package.
|
|
3
3
|
* Mirrors Python SDK: agentcp/group/__init__.py
|
|
4
4
|
*/
|
|
5
|
-
export { GroupErrorCode, GroupError, GroupRequest, GroupResponse, GroupNotify, buildGroupRequest, groupRequestToJson, parseGroupResponse, parseGroupNotify, GroupMessage, GroupEvent, MsgCursor, EventCursor, CursorState, createMsgCursor, createEventCursor, CreateGroupResp, SendMessageResp, PullMessagesResp, PullEventsResp, GroupInfoResp, BanlistResp, BatchReviewResp, PendingRequestsResp, RequestJoinResp, MembersResp, AdminsResp, RulesResp, AnnouncementResp, JoinRequirementsResp, MasterResp, InviteCodeResp, InviteCodeListResp, BroadcastLockResp, BroadcastPermissionResp, SyncStatusResp, SyncLogResp, ChecksumResp, PublicGroupInfoResp, SearchGroupsResp, DigestResp, MembershipInfo, ListMyGroupsResp, GetFileResp, GetSummaryResp, GetMetricsResp, NOTIFY_NEW_MESSAGE, NOTIFY_NEW_EVENT, NOTIFY_GROUP_INVITE, NOTIFY_JOIN_APPROVED, NOTIFY_JOIN_REJECTED, NOTIFY_JOIN_REQUEST_RECEIVED,
|
|
5
|
+
export { GroupErrorCode, GroupError, GroupRequest, GroupResponse, GroupNotify, buildGroupRequest, groupRequestToJson, parseGroupResponse, parseGroupNotify, GroupMessage, GroupEvent, MsgCursor, EventCursor, CursorState, createMsgCursor, createEventCursor, CreateGroupResp, SendMessageResp, PullMessagesResp, PullEventsResp, GroupInfoResp, BanlistResp, BatchReviewResp, PendingRequestsResp, RequestJoinResp, MembersResp, AdminsResp, RulesResp, AnnouncementResp, JoinRequirementsResp, MasterResp, InviteCodeResp, InviteCodeListResp, BroadcastLockResp, BroadcastPermissionResp, SyncStatusResp, SyncLogResp, ChecksumResp, PublicGroupInfoResp, SearchGroupsResp, DigestResp, MembershipInfo, ListMyGroupsResp, GetFileResp, GetSummaryResp, GetMetricsResp, NOTIFY_NEW_MESSAGE, NOTIFY_NEW_EVENT, NOTIFY_GROUP_INVITE, NOTIFY_JOIN_APPROVED, NOTIFY_JOIN_REJECTED, NOTIFY_JOIN_REQUEST_RECEIVED, NOTIFY_GROUP_MESSAGE, NOTIFY_GROUP_EVENT, EVENT_MEMBER_JOINED, EVENT_MEMBER_REMOVED, EVENT_MEMBER_LEFT, EVENT_MEMBER_BANNED, EVENT_META_UPDATED, EVENT_RULES_UPDATED, EVENT_ANNOUNCEMENT_UPDATED, EVENT_GROUP_DISSOLVED, EVENT_MASTER_TRANSFERRED, EVENT_GROUP_SUSPENDED, EVENT_GROUP_RESUMED, EVENT_MEMBER_UNBANNED, EVENT_JOIN_REQUIREMENTS_UPDATED, EVENT_INVITE_CODE_CREATED, EVENT_INVITE_CODE_REVOKED, ACTION_MESSAGE_BATCH_PUSH, GroupMessageBatch, DutyConfig, DutyState, DutyStatusResp, } from './types';
|
|
6
6
|
export { ACPGroupClient, SendFunc } from './client';
|
|
7
7
|
export { GroupOperations, SyncHandler } from './operations';
|
|
8
8
|
export { ACPGroupEventHandler, EventProcessor, dispatchAcpNotify, dispatchEvent, } from './events';
|
package/dist/group/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Mirrors Python SDK: agentcp/group/__init__.py
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.GroupMessageStore = exports.LocalCursorStore = exports.dispatchAcpNotify = exports.GroupOperations = exports.ACPGroupClient = exports.ACTION_MESSAGE_BATCH_PUSH = exports.EVENT_INVITE_CODE_REVOKED = exports.EVENT_INVITE_CODE_CREATED = exports.EVENT_JOIN_REQUIREMENTS_UPDATED = exports.EVENT_MEMBER_UNBANNED = exports.EVENT_GROUP_RESUMED = exports.EVENT_GROUP_SUSPENDED = exports.EVENT_MASTER_TRANSFERRED = exports.EVENT_GROUP_DISSOLVED = exports.EVENT_ANNOUNCEMENT_UPDATED = exports.EVENT_RULES_UPDATED = exports.EVENT_META_UPDATED = exports.EVENT_MEMBER_BANNED = exports.EVENT_MEMBER_LEFT = exports.EVENT_MEMBER_REMOVED = exports.EVENT_MEMBER_JOINED = exports.
|
|
7
|
+
exports.GroupMessageStore = exports.LocalCursorStore = exports.dispatchAcpNotify = exports.GroupOperations = exports.ACPGroupClient = exports.ACTION_MESSAGE_BATCH_PUSH = exports.EVENT_INVITE_CODE_REVOKED = exports.EVENT_INVITE_CODE_CREATED = exports.EVENT_JOIN_REQUIREMENTS_UPDATED = exports.EVENT_MEMBER_UNBANNED = exports.EVENT_GROUP_RESUMED = exports.EVENT_GROUP_SUSPENDED = exports.EVENT_MASTER_TRANSFERRED = exports.EVENT_GROUP_DISSOLVED = exports.EVENT_ANNOUNCEMENT_UPDATED = exports.EVENT_RULES_UPDATED = exports.EVENT_META_UPDATED = exports.EVENT_MEMBER_BANNED = exports.EVENT_MEMBER_LEFT = exports.EVENT_MEMBER_REMOVED = exports.EVENT_MEMBER_JOINED = exports.NOTIFY_GROUP_EVENT = exports.NOTIFY_GROUP_MESSAGE = exports.NOTIFY_JOIN_REQUEST_RECEIVED = exports.NOTIFY_JOIN_REJECTED = exports.NOTIFY_JOIN_APPROVED = exports.NOTIFY_GROUP_INVITE = exports.NOTIFY_NEW_EVENT = exports.NOTIFY_NEW_MESSAGE = exports.createEventCursor = exports.createMsgCursor = exports.parseGroupNotify = exports.parseGroupResponse = exports.groupRequestToJson = exports.buildGroupRequest = exports.GroupError = exports.GroupErrorCode = void 0;
|
|
8
8
|
// Types
|
|
9
9
|
var types_1 = require("./types");
|
|
10
10
|
Object.defineProperty(exports, "GroupErrorCode", { enumerable: true, get: function () { return types_1.GroupErrorCode; } });
|
|
@@ -22,8 +22,8 @@ Object.defineProperty(exports, "NOTIFY_GROUP_INVITE", { enumerable: true, get: f
|
|
|
22
22
|
Object.defineProperty(exports, "NOTIFY_JOIN_APPROVED", { enumerable: true, get: function () { return types_1.NOTIFY_JOIN_APPROVED; } });
|
|
23
23
|
Object.defineProperty(exports, "NOTIFY_JOIN_REJECTED", { enumerable: true, get: function () { return types_1.NOTIFY_JOIN_REJECTED; } });
|
|
24
24
|
Object.defineProperty(exports, "NOTIFY_JOIN_REQUEST_RECEIVED", { enumerable: true, get: function () { return types_1.NOTIFY_JOIN_REQUEST_RECEIVED; } });
|
|
25
|
+
Object.defineProperty(exports, "NOTIFY_GROUP_MESSAGE", { enumerable: true, get: function () { return types_1.NOTIFY_GROUP_MESSAGE; } });
|
|
25
26
|
Object.defineProperty(exports, "NOTIFY_GROUP_EVENT", { enumerable: true, get: function () { return types_1.NOTIFY_GROUP_EVENT; } });
|
|
26
|
-
Object.defineProperty(exports, "NOTIFY_DUTY_DISPATCH", { enumerable: true, get: function () { return types_1.NOTIFY_DUTY_DISPATCH; } });
|
|
27
27
|
// Group event type constants
|
|
28
28
|
Object.defineProperty(exports, "EVENT_MEMBER_JOINED", { enumerable: true, get: function () { return types_1.EVENT_MEMBER_JOINED; } });
|
|
29
29
|
Object.defineProperty(exports, "EVENT_MEMBER_REMOVED", { enumerable: true, get: function () { return types_1.EVENT_MEMBER_REMOVED; } });
|