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
|
@@ -27,7 +27,6 @@ export declare class GroupMessageStore {
|
|
|
27
27
|
private maxEventsPerGroup;
|
|
28
28
|
private groups;
|
|
29
29
|
private _indexDirty;
|
|
30
|
-
private _flushIndexPromise;
|
|
31
30
|
constructor(options: {
|
|
32
31
|
persistMessages: boolean;
|
|
33
32
|
basePath: string;
|
|
@@ -46,16 +45,16 @@ export declare class GroupMessageStore {
|
|
|
46
45
|
getGroupList(): GroupRecord[];
|
|
47
46
|
getGroup(groupId: string): GroupRecord | null;
|
|
48
47
|
deleteGroup(groupId: string): Promise<boolean>;
|
|
49
|
-
addMessage(groupId: string, msg: GroupMessage):
|
|
50
|
-
addMessages(groupId: string, msgs: GroupMessage[]):
|
|
48
|
+
addMessage(groupId: string, msg: GroupMessage): void;
|
|
49
|
+
addMessages(groupId: string, msgs: GroupMessage[]): void;
|
|
51
50
|
getMessages(groupId: string, options?: {
|
|
52
51
|
afterMsgId?: number;
|
|
53
52
|
beforeMsgId?: number;
|
|
54
53
|
limit?: number;
|
|
55
54
|
}): GroupMessage[];
|
|
56
55
|
getLatestMessages(groupId: string, limit?: number): GroupMessage[];
|
|
57
|
-
addEvent(groupId: string, evt: GroupEvent):
|
|
58
|
-
addEvents(groupId: string, evts: GroupEvent[]):
|
|
56
|
+
addEvent(groupId: string, evt: GroupEvent): void;
|
|
57
|
+
addEvents(groupId: string, evts: GroupEvent[]): void;
|
|
59
58
|
getEvents(groupId: string, options?: {
|
|
60
59
|
afterEventId?: number;
|
|
61
60
|
limit?: number;
|
|
@@ -64,7 +63,7 @@ export declare class GroupMessageStore {
|
|
|
64
63
|
private writeJsonl;
|
|
65
64
|
private flushMessages;
|
|
66
65
|
private flushEvents;
|
|
67
|
-
private
|
|
66
|
+
private flushIndexAsync;
|
|
68
67
|
flushIndex(): Promise<void>;
|
|
69
68
|
flush(ownerAid: string): Promise<void>;
|
|
70
69
|
flushAll(): Promise<void>;
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.GroupMessageStore = void 0;
|
|
13
13
|
const websocket_1 = require("../websocket");
|
|
14
|
+
const utils_1 = require("../utils");
|
|
14
15
|
class GroupMessageStore {
|
|
15
16
|
constructor(options) {
|
|
16
17
|
var _a, _b;
|
|
17
18
|
this.ownerAid = '';
|
|
18
19
|
this.groups = new Map();
|
|
19
20
|
this._indexDirty = false;
|
|
20
|
-
this._flushIndexPromise = null;
|
|
21
21
|
this.persistMessages = options.persistMessages;
|
|
22
22
|
this.basePath = options.basePath;
|
|
23
23
|
this.maxMessagesPerGroup = (_a = options.maxMessagesPerGroup) !== null && _a !== void 0 ? _a : 5000;
|
|
@@ -44,12 +44,12 @@ class GroupMessageStore {
|
|
|
44
44
|
const path = require('path');
|
|
45
45
|
return path.join(this.getGroupDir(aid, groupId), 'events.jsonl');
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
ensureDir(dir) {
|
|
48
48
|
if (!websocket_1.isNodeEnvironment)
|
|
49
49
|
return;
|
|
50
50
|
const fs = require('fs');
|
|
51
51
|
if (!fs.existsSync(dir)) {
|
|
52
|
-
|
|
52
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
// ---- load ----
|
|
@@ -64,45 +64,41 @@ class GroupMessageStore {
|
|
|
64
64
|
if (!fs.existsSync(indexPath))
|
|
65
65
|
return;
|
|
66
66
|
try {
|
|
67
|
-
const raw =
|
|
67
|
+
const raw = fs.readFileSync(indexPath, 'utf-8');
|
|
68
68
|
const records = JSON.parse(raw);
|
|
69
69
|
if (!Array.isArray(records))
|
|
70
70
|
return;
|
|
71
71
|
for (const r of records) {
|
|
72
|
-
const messages =
|
|
73
|
-
const events =
|
|
72
|
+
const messages = this.readJsonl(this.getMessagesPath(ownerAid, r.groupId));
|
|
73
|
+
const events = this.readJsonl(this.getEventsPath(ownerAid, r.groupId));
|
|
74
74
|
this.groups.set(r.groupId, { record: r, messages, events });
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
catch (e) {
|
|
78
|
-
|
|
78
|
+
utils_1.logger.error('[GroupMessageStore] 加载索引失败:', e);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
readJsonl(filePath) {
|
|
82
82
|
if (!websocket_1.isNodeEnvironment)
|
|
83
83
|
return [];
|
|
84
84
|
const fs = require('fs');
|
|
85
85
|
if (!fs.existsSync(filePath))
|
|
86
86
|
return [];
|
|
87
87
|
try {
|
|
88
|
-
const raw =
|
|
88
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
89
89
|
const items = [];
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
const l = lines[i].trim();
|
|
90
|
+
for (const line of raw.split('\n')) {
|
|
91
|
+
const l = line.trim();
|
|
93
92
|
if (!l)
|
|
94
93
|
continue;
|
|
95
94
|
try {
|
|
96
95
|
items.push(JSON.parse(l));
|
|
97
96
|
}
|
|
98
|
-
catch (
|
|
99
|
-
console.warn(`[GroupMessageStore] JSONL 解析失败 (${filePath} 行${i + 1}): ${l.substring(0, 80)}`, lineErr);
|
|
100
|
-
}
|
|
97
|
+
catch (_a) { }
|
|
101
98
|
}
|
|
102
99
|
return items;
|
|
103
100
|
}
|
|
104
|
-
catch (
|
|
105
|
-
console.warn(`[GroupMessageStore] 读取 JSONL 文件失败 (${filePath}):`, e);
|
|
101
|
+
catch (_b) {
|
|
106
102
|
return [];
|
|
107
103
|
}
|
|
108
104
|
}
|
|
@@ -119,7 +115,7 @@ class GroupMessageStore {
|
|
|
119
115
|
data = { record, messages: [], events: [] };
|
|
120
116
|
this.groups.set(groupId, data);
|
|
121
117
|
this._indexDirty = true;
|
|
122
|
-
this.
|
|
118
|
+
this.flushIndexAsync();
|
|
123
119
|
}
|
|
124
120
|
return data.record;
|
|
125
121
|
}
|
|
@@ -147,17 +143,18 @@ class GroupMessageStore {
|
|
|
147
143
|
}
|
|
148
144
|
}
|
|
149
145
|
catch (e) {
|
|
150
|
-
|
|
146
|
+
utils_1.logger.error(`[GroupMessageStore] 删除群目录失败 (${groupId}):`, e);
|
|
151
147
|
}
|
|
152
148
|
await this.flushIndex();
|
|
153
149
|
}
|
|
154
150
|
return true;
|
|
155
151
|
}
|
|
156
152
|
// ---- message storage ----
|
|
157
|
-
|
|
153
|
+
addMessage(groupId, msg) {
|
|
158
154
|
const data = this.groups.get(groupId);
|
|
159
155
|
if (!data)
|
|
160
156
|
return;
|
|
157
|
+
// dedup: skip if msg_id already seen
|
|
161
158
|
if (msg.msg_id <= data.record.lastMsgId)
|
|
162
159
|
return;
|
|
163
160
|
data.messages.push(msg);
|
|
@@ -165,35 +162,39 @@ class GroupMessageStore {
|
|
|
165
162
|
data.record.messageCount = data.messages.length;
|
|
166
163
|
data.record.lastMessageAt = msg.timestamp || Date.now();
|
|
167
164
|
this._indexDirty = true;
|
|
165
|
+
// truncate if over limit
|
|
168
166
|
if (data.messages.length > this.maxMessagesPerGroup) {
|
|
169
167
|
const excess = data.messages.length - this.maxMessagesPerGroup;
|
|
170
168
|
data.messages.splice(0, excess);
|
|
171
169
|
data.record.messageCount = data.messages.length;
|
|
172
|
-
|
|
170
|
+
this.flushMessages(groupId);
|
|
173
171
|
}
|
|
174
172
|
else {
|
|
175
|
-
|
|
173
|
+
this.appendJsonl(this.getMessagesPath(this.ownerAid, groupId), msg);
|
|
176
174
|
}
|
|
177
|
-
this.
|
|
175
|
+
this.flushIndexAsync();
|
|
178
176
|
}
|
|
179
|
-
|
|
177
|
+
addMessages(groupId, msgs) {
|
|
180
178
|
const data = this.groups.get(groupId);
|
|
181
|
-
if (!data)
|
|
179
|
+
if (!data) {
|
|
180
|
+
utils_1.logger.warn(`[GroupMessageStore] addMessages: group=${groupId} NOT FOUND in store! Available groups: [${Array.from(this.groups.keys()).join(', ')}]`);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (!msgs || msgs.length === 0)
|
|
182
184
|
return;
|
|
183
|
-
|
|
184
|
-
const existingIds = new Set(data.messages.map(m => m.msg_id));
|
|
185
|
+
utils_1.logger.log(`[GroupMessageStore] addMessages: group=${groupId} incoming=${msgs.length} currentLastMsgId=${data.record.lastMsgId} incomingMsgIds=[${msgs.map(m => m.msg_id).join(',')}]`);
|
|
185
186
|
let added = 0;
|
|
186
|
-
for (const msg of
|
|
187
|
-
if (
|
|
187
|
+
for (const msg of msgs) {
|
|
188
|
+
if (msg.msg_id <= data.record.lastMsgId) {
|
|
189
|
+
utils_1.logger.log(`[GroupMessageStore] addMessages: SKIP duplicate msg_id=${msg.msg_id} <= lastMsgId=${data.record.lastMsgId}`);
|
|
188
190
|
continue;
|
|
189
|
-
data.messages.push(msg);
|
|
190
|
-
existingIds.add(msg.msg_id);
|
|
191
|
-
if (msg.msg_id > data.record.lastMsgId) {
|
|
192
|
-
data.record.lastMsgId = msg.msg_id;
|
|
193
191
|
}
|
|
192
|
+
data.messages.push(msg);
|
|
193
|
+
data.record.lastMsgId = msg.msg_id;
|
|
194
194
|
data.record.lastMessageAt = msg.timestamp || Date.now();
|
|
195
195
|
added++;
|
|
196
196
|
}
|
|
197
|
+
utils_1.logger.log(`[GroupMessageStore] addMessages result: group=${groupId} added=${added}/${msgs.length} newLastMsgId=${data.record.lastMsgId} totalMessages=${data.messages.length}`);
|
|
197
198
|
if (added === 0)
|
|
198
199
|
return;
|
|
199
200
|
data.record.messageCount = data.messages.length;
|
|
@@ -202,9 +203,12 @@ class GroupMessageStore {
|
|
|
202
203
|
const excess = data.messages.length - this.maxMessagesPerGroup;
|
|
203
204
|
data.messages.splice(0, excess);
|
|
204
205
|
data.record.messageCount = data.messages.length;
|
|
206
|
+
this.flushMessages(groupId);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
this.flushMessages(groupId);
|
|
205
210
|
}
|
|
206
|
-
|
|
207
|
-
this.flushIndexQueued();
|
|
211
|
+
this.flushIndexAsync();
|
|
208
212
|
}
|
|
209
213
|
getMessages(groupId, options) {
|
|
210
214
|
const data = this.groups.get(groupId);
|
|
@@ -229,7 +233,7 @@ class GroupMessageStore {
|
|
|
229
233
|
return data.messages.slice(-limit);
|
|
230
234
|
}
|
|
231
235
|
// ---- event storage ----
|
|
232
|
-
|
|
236
|
+
addEvent(groupId, evt) {
|
|
233
237
|
const data = this.groups.get(groupId);
|
|
234
238
|
if (!data)
|
|
235
239
|
return;
|
|
@@ -243,14 +247,14 @@ class GroupMessageStore {
|
|
|
243
247
|
const excess = data.events.length - this.maxEventsPerGroup;
|
|
244
248
|
data.events.splice(0, excess);
|
|
245
249
|
data.record.eventCount = data.events.length;
|
|
246
|
-
|
|
250
|
+
this.flushEvents(groupId);
|
|
247
251
|
}
|
|
248
252
|
else {
|
|
249
|
-
|
|
253
|
+
this.appendJsonl(this.getEventsPath(this.ownerAid, groupId), evt);
|
|
250
254
|
}
|
|
251
|
-
this.
|
|
255
|
+
this.flushIndexAsync();
|
|
252
256
|
}
|
|
253
|
-
|
|
257
|
+
addEvents(groupId, evts) {
|
|
254
258
|
const data = this.groups.get(groupId);
|
|
255
259
|
if (!data)
|
|
256
260
|
return;
|
|
@@ -271,8 +275,8 @@ class GroupMessageStore {
|
|
|
271
275
|
data.events.splice(0, excess);
|
|
272
276
|
data.record.eventCount = data.events.length;
|
|
273
277
|
}
|
|
274
|
-
|
|
275
|
-
this.
|
|
278
|
+
this.flushEvents(groupId);
|
|
279
|
+
this.flushIndexAsync();
|
|
276
280
|
}
|
|
277
281
|
getEvents(groupId, options) {
|
|
278
282
|
const data = this.groups.get(groupId);
|
|
@@ -288,54 +292,47 @@ class GroupMessageStore {
|
|
|
288
292
|
return result;
|
|
289
293
|
}
|
|
290
294
|
// ---- persistence ----
|
|
291
|
-
|
|
295
|
+
appendJsonl(filePath, item) {
|
|
292
296
|
if (!this.persistMessages || !websocket_1.isNodeEnvironment || !this.ownerAid)
|
|
293
297
|
return;
|
|
294
298
|
const fs = require('fs');
|
|
295
299
|
const path = require('path');
|
|
296
|
-
|
|
300
|
+
this.ensureDir(path.dirname(filePath));
|
|
297
301
|
try {
|
|
298
|
-
|
|
302
|
+
fs.appendFileSync(filePath, JSON.stringify(item) + '\n');
|
|
299
303
|
}
|
|
300
304
|
catch (e) {
|
|
301
|
-
|
|
305
|
+
utils_1.logger.error(`[GroupMessageStore] 追加写入失败 (${filePath}):`, e);
|
|
302
306
|
}
|
|
303
307
|
}
|
|
304
|
-
|
|
308
|
+
writeJsonl(filePath, items) {
|
|
305
309
|
if (!this.persistMessages || !websocket_1.isNodeEnvironment || !this.ownerAid)
|
|
306
310
|
return;
|
|
307
311
|
const fs = require('fs');
|
|
308
312
|
const path = require('path');
|
|
309
|
-
|
|
313
|
+
this.ensureDir(path.dirname(filePath));
|
|
310
314
|
try {
|
|
311
315
|
const lines = items.map(i => JSON.stringify(i)).join('\n');
|
|
312
|
-
|
|
313
|
-
const tmpPath = filePath + '.tmp';
|
|
314
|
-
await fs.promises.writeFile(tmpPath, content);
|
|
315
|
-
await fs.promises.rename(tmpPath, filePath);
|
|
316
|
+
fs.writeFileSync(filePath, lines ? lines + '\n' : '');
|
|
316
317
|
}
|
|
317
318
|
catch (e) {
|
|
318
|
-
|
|
319
|
+
utils_1.logger.error(`[GroupMessageStore] 全量写入失败 (${filePath}):`, e);
|
|
319
320
|
}
|
|
320
321
|
}
|
|
321
|
-
|
|
322
|
+
flushMessages(groupId) {
|
|
322
323
|
const data = this.groups.get(groupId);
|
|
323
324
|
if (!data || !this.ownerAid)
|
|
324
325
|
return;
|
|
325
|
-
|
|
326
|
+
this.writeJsonl(this.getMessagesPath(this.ownerAid, groupId), data.messages);
|
|
326
327
|
}
|
|
327
|
-
|
|
328
|
+
flushEvents(groupId) {
|
|
328
329
|
const data = this.groups.get(groupId);
|
|
329
330
|
if (!data || !this.ownerAid)
|
|
330
331
|
return;
|
|
331
|
-
|
|
332
|
+
this.writeJsonl(this.getEventsPath(this.ownerAid, groupId), data.events);
|
|
332
333
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
const prev = (_a = this._flushIndexPromise) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
336
|
-
this._flushIndexPromise = prev.then(() => this.flushIndex()).catch(e => {
|
|
337
|
-
console.error('[GroupMessageStore] 索引刷盘失败:', e);
|
|
338
|
-
});
|
|
334
|
+
flushIndexAsync() {
|
|
335
|
+
this.flushIndex().catch(() => { });
|
|
339
336
|
}
|
|
340
337
|
async flushIndex() {
|
|
341
338
|
if (!this.persistMessages || !websocket_1.isNodeEnvironment || !this.ownerAid)
|
|
@@ -344,18 +341,15 @@ class GroupMessageStore {
|
|
|
344
341
|
return;
|
|
345
342
|
const fs = require('fs');
|
|
346
343
|
const dir = this.getGroupsDir(this.ownerAid);
|
|
347
|
-
|
|
344
|
+
this.ensureDir(dir);
|
|
348
345
|
const records = Array.from(this.groups.values())
|
|
349
346
|
.map(d => d.record);
|
|
350
347
|
try {
|
|
351
|
-
|
|
352
|
-
const tmpPath = indexPath + '.tmp';
|
|
353
|
-
await fs.promises.writeFile(tmpPath, JSON.stringify(records, null, 2));
|
|
354
|
-
await fs.promises.rename(tmpPath, indexPath);
|
|
348
|
+
fs.writeFileSync(this.getIndexPath(this.ownerAid), JSON.stringify(records, null, 2));
|
|
355
349
|
this._indexDirty = false;
|
|
356
350
|
}
|
|
357
351
|
catch (e) {
|
|
358
|
-
|
|
352
|
+
utils_1.logger.error('[GroupMessageStore] 写入索引失败:', e);
|
|
359
353
|
}
|
|
360
354
|
}
|
|
361
355
|
async flush(ownerAid) {
|
|
@@ -363,9 +357,9 @@ class GroupMessageStore {
|
|
|
363
357
|
return;
|
|
364
358
|
this.ownerAid = ownerAid;
|
|
365
359
|
await this.flushIndex();
|
|
366
|
-
for (const [groupId] of this.groups) {
|
|
367
|
-
|
|
368
|
-
|
|
360
|
+
for (const [groupId, data] of this.groups) {
|
|
361
|
+
this.flushMessages(groupId);
|
|
362
|
+
this.flushEvents(groupId);
|
|
369
363
|
}
|
|
370
364
|
}
|
|
371
365
|
async flushAll() {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Mirrors Python SDK: agentcp/group/operations.py
|
|
4
4
|
*/
|
|
5
5
|
import { ACPGroupClient } from './client';
|
|
6
|
-
import { CreateGroupResp, SendMessageResp, PullMessagesResp, PullEventsResp, CursorState, GroupInfoResp, BanlistResp, BatchReviewResp, PendingRequestsResp, RequestJoinResp, MembersResp, AdminsResp, RulesResp, AnnouncementResp, JoinRequirementsResp, MasterResp, InviteCodeResp, InviteCodeListResp, BroadcastLockResp, BroadcastPermissionResp, SyncStatusResp, SyncLogResp, ChecksumResp, PublicGroupInfoResp, SearchGroupsResp, DigestResp, ListMyGroupsResp, GetFileResp, GetSummaryResp, GetMetricsResp, DutyConfig, DutyStatusResp
|
|
6
|
+
import { CreateGroupResp, SendMessageResp, PullMessagesResp, PullEventsResp, CursorState, GroupInfoResp, BanlistResp, BatchReviewResp, PendingRequestsResp, RequestJoinResp, MembersResp, AdminsResp, RulesResp, AnnouncementResp, JoinRequirementsResp, MasterResp, InviteCodeResp, InviteCodeListResp, BroadcastLockResp, BroadcastPermissionResp, SyncStatusResp, SyncLogResp, ChecksumResp, PublicGroupInfoResp, SearchGroupsResp, DigestResp, ListMyGroupsResp, GetFileResp, GetSummaryResp, GetMetricsResp, DutyConfig, DutyStatusResp } from './types';
|
|
7
7
|
/**
|
|
8
8
|
* Callback interface for syncGroup.
|
|
9
9
|
*/
|
|
@@ -146,10 +146,6 @@ export declare class GroupOperations {
|
|
|
146
146
|
* 获取值班状态,包含 config 和 state。
|
|
147
147
|
*/
|
|
148
148
|
getDutyStatus(targetAid: string, groupId: string): Promise<DutyStatusResp>;
|
|
149
|
-
/**
|
|
150
|
-
* 值班 Agent 提交仲裁决策。
|
|
151
|
-
*/
|
|
152
|
-
dispatchDecision(targetAid: string, groupId: string, params: DispatchDecisionParams): Promise<void>;
|
|
153
149
|
/**
|
|
154
150
|
* 重新获取所有成员的 agent.md 并更新 AgentType。
|
|
155
151
|
*/
|
package/dist/group/operations.js
CHANGED
|
@@ -207,9 +207,10 @@ class GroupOperations {
|
|
|
207
207
|
let after = cursor.msg_cursor.current_msg_id;
|
|
208
208
|
while (true) {
|
|
209
209
|
const result = await this.pullMessages(targetAid, groupId, after, 50);
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
const messages = result.messages || [];
|
|
211
|
+
if (messages.length > 0) {
|
|
212
|
+
handler.onMessages(groupId, messages);
|
|
213
|
+
const lastId = (_a = messages[messages.length - 1].msg_id) !== null && _a !== void 0 ? _a : after;
|
|
213
214
|
await this.ackMessages(targetAid, groupId, lastId);
|
|
214
215
|
after = lastId;
|
|
215
216
|
}
|
|
@@ -223,9 +224,10 @@ class GroupOperations {
|
|
|
223
224
|
let after = cursor.event_cursor.current_event_id;
|
|
224
225
|
while (true) {
|
|
225
226
|
const result = await this.pullEvents(targetAid, groupId, after, 50);
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
const events = result.events || [];
|
|
228
|
+
if (events.length > 0) {
|
|
229
|
+
handler.onEvents(groupId, events);
|
|
230
|
+
const lastId = (_a = events[events.length - 1].event_id) !== null && _a !== void 0 ? _a : after;
|
|
229
231
|
await this.ackEvents(targetAid, groupId, lastId);
|
|
230
232
|
after = lastId;
|
|
231
233
|
}
|
|
@@ -634,11 +636,11 @@ class GroupOperations {
|
|
|
634
636
|
params.shift_duration_ms = config.shift_duration_ms;
|
|
635
637
|
if (config.max_messages_per_shift != null)
|
|
636
638
|
params.max_messages_per_shift = config.max_messages_per_shift;
|
|
637
|
-
if (config.
|
|
638
|
-
params.
|
|
639
|
-
if (config.
|
|
640
|
-
params.
|
|
641
|
-
const resp = await this._client.sendRequest(targetAid, groupId, "update_duty_config", params);
|
|
639
|
+
if (config.duty_priority_window_ms != null)
|
|
640
|
+
params.duty_priority_window_ms = config.duty_priority_window_ms;
|
|
641
|
+
if (config.enable_rule_prelude != null)
|
|
642
|
+
params.enable_rule_prelude = config.enable_rule_prelude;
|
|
643
|
+
const resp = await this._client.sendRequest(targetAid, groupId, "update_duty_config", { duty_config: params });
|
|
642
644
|
this._check(resp, "update_duty_config");
|
|
643
645
|
}
|
|
644
646
|
/**
|
|
@@ -658,13 +660,6 @@ class GroupOperations {
|
|
|
658
660
|
const d = resp.data || {};
|
|
659
661
|
return { config: (_a = d.config) !== null && _a !== void 0 ? _a : {}, state: (_b = d.state) !== null && _b !== void 0 ? _b : {} };
|
|
660
662
|
}
|
|
661
|
-
/**
|
|
662
|
-
* 值班 Agent 提交仲裁决策。
|
|
663
|
-
*/
|
|
664
|
-
async dispatchDecision(targetAid, groupId, params) {
|
|
665
|
-
const resp = await this._client.sendRequest(targetAid, groupId, "dispatch_decision", params);
|
|
666
|
-
this._check(resp, "dispatch_decision");
|
|
667
|
-
}
|
|
668
663
|
/**
|
|
669
664
|
* 重新获取所有成员的 agent.md 并更新 AgentType。
|
|
670
665
|
*/
|
package/dist/group/types.d.ts
CHANGED
|
@@ -20,8 +20,6 @@ export declare enum GroupErrorCode {
|
|
|
20
20
|
ACTION_NOT_IMPL = 1099,
|
|
21
21
|
DUTY_NOT_ENABLED = 1020,
|
|
22
22
|
NOT_DUTY_AGENT = 1021,
|
|
23
|
-
DISPATCH_NOT_FOUND = 1022,
|
|
24
|
-
INVALID_DECISION = 1023,
|
|
25
23
|
AGENT_MD_NOT_FOUND = 1024,
|
|
26
24
|
AGENT_MD_INVALID = 1025
|
|
27
25
|
}
|
|
@@ -258,8 +256,8 @@ export declare const NOTIFY_GROUP_INVITE = "group_invite";
|
|
|
258
256
|
export declare const NOTIFY_JOIN_APPROVED = "join_approved";
|
|
259
257
|
export declare const NOTIFY_JOIN_REJECTED = "join_rejected";
|
|
260
258
|
export declare const NOTIFY_JOIN_REQUEST_RECEIVED = "join_request_received";
|
|
259
|
+
export declare const NOTIFY_GROUP_MESSAGE = "group_message";
|
|
261
260
|
export declare const NOTIFY_GROUP_EVENT = "group_event";
|
|
262
|
-
export declare const NOTIFY_DUTY_DISPATCH = "duty_dispatch";
|
|
263
261
|
export declare const EVENT_MEMBER_JOINED = "member_joined";
|
|
264
262
|
export declare const EVENT_MEMBER_REMOVED = "member_removed";
|
|
265
263
|
export declare const EVENT_MEMBER_LEFT = "member_left";
|
|
@@ -275,37 +273,13 @@ export declare const EVENT_MEMBER_UNBANNED = "member_unbanned";
|
|
|
275
273
|
export declare const EVENT_JOIN_REQUIREMENTS_UPDATED = "join_requirements_updated";
|
|
276
274
|
export declare const EVENT_INVITE_CODE_CREATED = "invite_code_created";
|
|
277
275
|
export declare const EVENT_INVITE_CODE_REVOKED = "invite_code_revoked";
|
|
278
|
-
export interface DutyMemberInfo {
|
|
279
|
-
agent_id: string;
|
|
280
|
-
agent_type: string;
|
|
281
|
-
}
|
|
282
|
-
export interface DutyContext {
|
|
283
|
-
needs_dispatch: boolean;
|
|
284
|
-
original_msg_id: number;
|
|
285
|
-
sender_id: string;
|
|
286
|
-
sender_type: string;
|
|
287
|
-
group_member_count: number;
|
|
288
|
-
online_ai_members: DutyMemberInfo[];
|
|
289
|
-
human_members: DutyMemberInfo[];
|
|
290
|
-
}
|
|
291
|
-
export interface DispatchDecisionParams {
|
|
292
|
-
original_msg_id: number;
|
|
293
|
-
type: "broadcast" | "selective" | "suppress";
|
|
294
|
-
hint?: string;
|
|
295
|
-
reply_mode?: string;
|
|
296
|
-
}
|
|
297
|
-
export interface DispatchMetadata {
|
|
298
|
-
type: string;
|
|
299
|
-
hint: string;
|
|
300
|
-
reply_mode: string;
|
|
301
|
-
}
|
|
302
276
|
export interface DutyConfig {
|
|
303
277
|
mode: "none" | "fixed" | "rotation";
|
|
304
278
|
rotation_strategy?: "round_robin" | "random";
|
|
305
279
|
shift_duration_ms?: number;
|
|
306
280
|
max_messages_per_shift?: number;
|
|
307
|
-
|
|
308
|
-
|
|
281
|
+
duty_priority_window_ms?: number;
|
|
282
|
+
enable_rule_prelude?: boolean;
|
|
309
283
|
agents?: string[];
|
|
310
284
|
}
|
|
311
285
|
export interface DutyState {
|
package/dist/group/types.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Mirrors Python SDK: agentcp/group/types.py
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
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.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.GroupError = exports.GroupErrorCode = void 0;
|
|
8
8
|
exports.buildGroupRequest = buildGroupRequest;
|
|
9
9
|
exports.groupRequestToJson = groupRequestToJson;
|
|
10
10
|
exports.parseGroupResponse = parseGroupResponse;
|
|
@@ -34,8 +34,6 @@ var GroupErrorCode;
|
|
|
34
34
|
// Duty error codes
|
|
35
35
|
GroupErrorCode[GroupErrorCode["DUTY_NOT_ENABLED"] = 1020] = "DUTY_NOT_ENABLED";
|
|
36
36
|
GroupErrorCode[GroupErrorCode["NOT_DUTY_AGENT"] = 1021] = "NOT_DUTY_AGENT";
|
|
37
|
-
GroupErrorCode[GroupErrorCode["DISPATCH_NOT_FOUND"] = 1022] = "DISPATCH_NOT_FOUND";
|
|
38
|
-
GroupErrorCode[GroupErrorCode["INVALID_DECISION"] = 1023] = "INVALID_DECISION";
|
|
39
37
|
GroupErrorCode[GroupErrorCode["AGENT_MD_NOT_FOUND"] = 1024] = "AGENT_MD_NOT_FOUND";
|
|
40
38
|
GroupErrorCode[GroupErrorCode["AGENT_MD_INVALID"] = 1025] = "AGENT_MD_INVALID";
|
|
41
39
|
})(GroupErrorCode || (exports.GroupErrorCode = GroupErrorCode = {}));
|
|
@@ -56,8 +54,6 @@ const CODE_MESSAGES = {
|
|
|
56
54
|
1013: "broadcast conflict",
|
|
57
55
|
1020: "duty not enabled",
|
|
58
56
|
1021: "not duty agent",
|
|
59
|
-
1022: "dispatch not found",
|
|
60
|
-
1023: "invalid decision",
|
|
61
57
|
1024: "agent.md not found",
|
|
62
58
|
1025: "agent.md invalid",
|
|
63
59
|
1099: "action not implemented",
|
|
@@ -133,8 +129,8 @@ exports.NOTIFY_GROUP_INVITE = "group_invite";
|
|
|
133
129
|
exports.NOTIFY_JOIN_APPROVED = "join_approved";
|
|
134
130
|
exports.NOTIFY_JOIN_REJECTED = "join_rejected";
|
|
135
131
|
exports.NOTIFY_JOIN_REQUEST_RECEIVED = "join_request_received";
|
|
132
|
+
exports.NOTIFY_GROUP_MESSAGE = "group_message";
|
|
136
133
|
exports.NOTIFY_GROUP_EVENT = "group_event";
|
|
137
|
-
exports.NOTIFY_DUTY_DISPATCH = "duty_dispatch";
|
|
138
134
|
// Group Event Type Constants
|
|
139
135
|
exports.EVENT_MEMBER_JOINED = "member_joined";
|
|
140
136
|
exports.EVENT_MEMBER_REMOVED = "member_removed";
|