@ai-setting/roy-agent-core 1.6.20 → 1.6.21

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/env/index.js CHANGED
@@ -21,7 +21,7 @@ import"../shared/@ai-setting/roy-agent-core-grajzyhd.js";
21
21
  import"../shared/@ai-setting/roy-agent-core-az13yzmc.js";
22
22
  import {
23
23
  WorkflowComponent
24
- } from "../shared/@ai-setting/roy-agent-core-mekk4as5.js";
24
+ } from "../shared/@ai-setting/roy-agent-core-q06h6qf8.js";
25
25
  import"../shared/@ai-setting/roy-agent-core-77wfej1h.js";
26
26
  import"../shared/@ai-setting/roy-agent-core-f1cjs6c4.js";
27
27
  import"../shared/@ai-setting/roy-agent-core-6atd905e.js";
@@ -30,7 +30,7 @@ import"../shared/@ai-setting/roy-agent-core-ez91vxas.js";
30
30
  import"../shared/@ai-setting/roy-agent-core-ddwa0n6h.js";
31
31
  import"../shared/@ai-setting/roy-agent-core-hhrg314p.js";
32
32
  import"../shared/@ai-setting/roy-agent-core-7kw06e4b.js";
33
- import"../shared/@ai-setting/roy-agent-core-kkt2ndpf.js";
33
+ import"../shared/@ai-setting/roy-agent-core-j8t1tyhr.js";
34
34
  import"../shared/@ai-setting/roy-agent-core-1db4vpc6.js";
35
35
  import"../shared/@ai-setting/roy-agent-core-r15sn7ve.js";
36
36
  import"../shared/@ai-setting/roy-agent-core-1mrc9a1r.js";
@@ -48,10 +48,10 @@ import"../shared/@ai-setting/roy-agent-core-ataagh3a.js";
48
48
  import"../shared/@ai-setting/roy-agent-core-e25xkv53.js";
49
49
  import {
50
50
  TaskComponent
51
- } from "../shared/@ai-setting/roy-agent-core-rdf8tqj7.js";
51
+ } from "../shared/@ai-setting/roy-agent-core-bb20se79.js";
52
52
  import"../shared/@ai-setting/roy-agent-core-amkqnyzy.js";
53
53
  import"../shared/@ai-setting/roy-agent-core-8gxth0eh.js";
54
- import"../shared/@ai-setting/roy-agent-core-8n3je2r0.js";
54
+ import"../shared/@ai-setting/roy-agent-core-zvwdfm79.js";
55
55
  import"../shared/@ai-setting/roy-agent-core-44g3synv.js";
56
56
  import"../shared/@ai-setting/roy-agent-core-zdzkzx5g.js";
57
57
  import"../shared/@ai-setting/roy-agent-core-skqt40yy.js";
@@ -71,9 +71,9 @@ import {
71
71
  import"../shared/@ai-setting/roy-agent-core-ctdhjv68.js";
72
72
  import"../shared/@ai-setting/roy-agent-core-fnv3ev18.js";
73
73
  import"../shared/@ai-setting/roy-agent-core-mdp8y7ky.js";
74
- import"../shared/@ai-setting/roy-agent-core-bqe4c9f2.js";
74
+ import"../shared/@ai-setting/roy-agent-core-kr58bgz0.js";
75
75
  import"../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
76
- import"../shared/@ai-setting/roy-agent-core-zs4f0tcy.js";
76
+ import"../shared/@ai-setting/roy-agent-core-xjj88tpn.js";
77
77
  import"../shared/@ai-setting/roy-agent-core-7r72622v.js";
78
78
  import"../shared/@ai-setting/roy-agent-core-e0kaxcy1.js";
79
79
  import"../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
@@ -3,11 +3,11 @@ import {
3
3
  MIN_SESSION_ID_LENGTH,
4
4
  SessionComponent,
5
5
  isValidSessionId
6
- } from "../../shared/@ai-setting/roy-agent-core-bqe4c9f2.js";
6
+ } from "../../shared/@ai-setting/roy-agent-core-kr58bgz0.js";
7
7
  import"../../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
8
8
  import {
9
9
  MemorySessionStore
10
- } from "../../shared/@ai-setting/roy-agent-core-zs4f0tcy.js";
10
+ } from "../../shared/@ai-setting/roy-agent-core-xjj88tpn.js";
11
11
  import {
12
12
  SessionMessageConverter
13
13
  } from "../../shared/@ai-setting/roy-agent-core-7r72622v.js";
@@ -3,7 +3,7 @@ import {
3
3
  SQLiteSessionStore,
4
4
  getDefaultDataDir,
5
5
  getDefaultSessionDbPath
6
- } from "../../../shared/@ai-setting/roy-agent-core-zs4f0tcy.js";
6
+ } from "../../../shared/@ai-setting/roy-agent-core-xjj88tpn.js";
7
7
  import"../../../shared/@ai-setting/roy-agent-core-7r72622v.js";
8
8
  import"../../../shared/@ai-setting/roy-agent-core-e0kaxcy1.js";
9
9
  import"../../../shared/@ai-setting/roy-agent-core-nna4s0qs.js";
@@ -3,7 +3,7 @@ import {
3
3
  BackgroundTaskManager,
4
4
  createDelegateTool,
5
5
  createStopTool
6
- } from "../../../shared/@ai-setting/roy-agent-core-8n3je2r0.js";
6
+ } from "../../../shared/@ai-setting/roy-agent-core-zvwdfm79.js";
7
7
  import"../../../shared/@ai-setting/roy-agent-core-44g3synv.js";
8
8
  import"../../../shared/@ai-setting/roy-agent-core-skqt40yy.js";
9
9
  import"../../../shared/@ai-setting/roy-agent-core-c1v263jn.js";
@@ -5,12 +5,12 @@ import {
5
5
  TaskPriorityEnum,
6
6
  TaskStatusEnum,
7
7
  TaskTypeEnum
8
- } from "../../shared/@ai-setting/roy-agent-core-rdf8tqj7.js";
8
+ } from "../../shared/@ai-setting/roy-agent-core-bb20se79.js";
9
9
  import"../../shared/@ai-setting/roy-agent-core-amkqnyzy.js";
10
10
  import {
11
11
  TaskEntityEventTypes
12
12
  } from "../../shared/@ai-setting/roy-agent-core-8gxth0eh.js";
13
- import"../../shared/@ai-setting/roy-agent-core-8n3je2r0.js";
13
+ import"../../shared/@ai-setting/roy-agent-core-zvwdfm79.js";
14
14
  import"../../shared/@ai-setting/roy-agent-core-44g3synv.js";
15
15
  import {
16
16
  SQLiteTaskStore,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  WorkflowComponent
3
- } from "../../shared/@ai-setting/roy-agent-core-mekk4as5.js";
3
+ } from "../../shared/@ai-setting/roy-agent-core-q06h6qf8.js";
4
4
  import"../../shared/@ai-setting/roy-agent-core-77wfej1h.js";
5
5
  import"../../shared/@ai-setting/roy-agent-core-f1cjs6c4.js";
6
6
  import"../../shared/@ai-setting/roy-agent-core-6atd905e.js";
@@ -9,7 +9,7 @@ import"../../shared/@ai-setting/roy-agent-core-ez91vxas.js";
9
9
  import"../../shared/@ai-setting/roy-agent-core-ddwa0n6h.js";
10
10
  import"../../shared/@ai-setting/roy-agent-core-hhrg314p.js";
11
11
  import"../../shared/@ai-setting/roy-agent-core-7kw06e4b.js";
12
- import"../../shared/@ai-setting/roy-agent-core-kkt2ndpf.js";
12
+ import"../../shared/@ai-setting/roy-agent-core-j8t1tyhr.js";
13
13
  import"../../shared/@ai-setting/roy-agent-core-1db4vpc6.js";
14
14
  import"../../shared/@ai-setting/roy-agent-core-r15sn7ve.js";
15
15
  import"../../shared/@ai-setting/roy-agent-core-1mrc9a1r.js";
@@ -84,9 +84,9 @@ import {
84
84
  createWorkflowAskUserEvent
85
85
  } from "../../shared/@ai-setting/roy-agent-core-e25xkv53.js";
86
86
  import"../../shared/@ai-setting/roy-agent-core-c1v263jn.js";
87
- import"../../shared/@ai-setting/roy-agent-core-bqe4c9f2.js";
87
+ import"../../shared/@ai-setting/roy-agent-core-kr58bgz0.js";
88
88
  import"../../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
89
- import"../../shared/@ai-setting/roy-agent-core-zs4f0tcy.js";
89
+ import"../../shared/@ai-setting/roy-agent-core-xjj88tpn.js";
90
90
  import"../../shared/@ai-setting/roy-agent-core-7r72622v.js";
91
91
  import"../../shared/@ai-setting/roy-agent-core-e0kaxcy1.js";
92
92
  import"../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
@@ -24,7 +24,7 @@ import {
24
24
  getRunWorkflowTool,
25
25
  initRunWorkflowTool,
26
26
  resetRunWorkflowTool
27
- } from "../../../shared/@ai-setting/roy-agent-core-kkt2ndpf.js";
27
+ } from "../../../shared/@ai-setting/roy-agent-core-j8t1tyhr.js";
28
28
  import {
29
29
  WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME,
30
30
  WorkflowJsonOutputMarker,
@@ -38,9 +38,9 @@ import"../../../shared/@ai-setting/roy-agent-core-bq1gskrf.js";
38
38
  import"../../../shared/@ai-setting/roy-agent-core-jrj30vq3.js";
39
39
  import"../../../shared/@ai-setting/roy-agent-core-e25xkv53.js";
40
40
  import"../../../shared/@ai-setting/roy-agent-core-c1v263jn.js";
41
- import"../../../shared/@ai-setting/roy-agent-core-bqe4c9f2.js";
41
+ import"../../../shared/@ai-setting/roy-agent-core-kr58bgz0.js";
42
42
  import"../../../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
43
- import"../../../shared/@ai-setting/roy-agent-core-zs4f0tcy.js";
43
+ import"../../../shared/@ai-setting/roy-agent-core-xjj88tpn.js";
44
44
  import"../../../shared/@ai-setting/roy-agent-core-7r72622v.js";
45
45
  import"../../../shared/@ai-setting/roy-agent-core-e0kaxcy1.js";
46
46
  import"../../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ import {
102
102
  } from "./shared/@ai-setting/roy-agent-core-az13yzmc.js";
103
103
  import {
104
104
  WorkflowComponent
105
- } from "./shared/@ai-setting/roy-agent-core-mekk4as5.js";
105
+ } from "./shared/@ai-setting/roy-agent-core-q06h6qf8.js";
106
106
  import {
107
107
  init_node_registry_helper,
108
108
  registerDecoratorNodeType
@@ -114,7 +114,7 @@ import"./shared/@ai-setting/roy-agent-core-ez91vxas.js";
114
114
  import"./shared/@ai-setting/roy-agent-core-ddwa0n6h.js";
115
115
  import"./shared/@ai-setting/roy-agent-core-hhrg314p.js";
116
116
  import"./shared/@ai-setting/roy-agent-core-7kw06e4b.js";
117
- import"./shared/@ai-setting/roy-agent-core-kkt2ndpf.js";
117
+ import"./shared/@ai-setting/roy-agent-core-j8t1tyhr.js";
118
118
  import"./shared/@ai-setting/roy-agent-core-1db4vpc6.js";
119
119
  import"./shared/@ai-setting/roy-agent-core-r15sn7ve.js";
120
120
  import"./shared/@ai-setting/roy-agent-core-1mrc9a1r.js";
@@ -150,10 +150,10 @@ import {
150
150
  } from "./shared/@ai-setting/roy-agent-core-e25xkv53.js";
151
151
  import {
152
152
  TaskComponent
153
- } from "./shared/@ai-setting/roy-agent-core-rdf8tqj7.js";
153
+ } from "./shared/@ai-setting/roy-agent-core-bb20se79.js";
154
154
  import"./shared/@ai-setting/roy-agent-core-amkqnyzy.js";
155
155
  import"./shared/@ai-setting/roy-agent-core-8gxth0eh.js";
156
- import"./shared/@ai-setting/roy-agent-core-8n3je2r0.js";
156
+ import"./shared/@ai-setting/roy-agent-core-zvwdfm79.js";
157
157
  import"./shared/@ai-setting/roy-agent-core-44g3synv.js";
158
158
  import {
159
159
  SQLiteTaskStore,
@@ -199,11 +199,11 @@ import"./shared/@ai-setting/roy-agent-core-fnv3ev18.js";
199
199
  import"./shared/@ai-setting/roy-agent-core-mdp8y7ky.js";
200
200
  import {
201
201
  SessionComponent
202
- } from "./shared/@ai-setting/roy-agent-core-bqe4c9f2.js";
202
+ } from "./shared/@ai-setting/roy-agent-core-kr58bgz0.js";
203
203
  import"./shared/@ai-setting/roy-agent-core-rvxg1wps.js";
204
204
  import {
205
205
  MemorySessionStore
206
- } from "./shared/@ai-setting/roy-agent-core-zs4f0tcy.js";
206
+ } from "./shared/@ai-setting/roy-agent-core-xjj88tpn.js";
207
207
  import"./shared/@ai-setting/roy-agent-core-7r72622v.js";
208
208
  import"./shared/@ai-setting/roy-agent-core-e0kaxcy1.js";
209
209
  import"./shared/@ai-setting/roy-agent-core-7hh0brvs.js";
@@ -8,7 +8,7 @@ import {
8
8
  BackgroundTaskManager,
9
9
  createDelegateTool,
10
10
  createStopTool
11
- } from "./roy-agent-core-8n3je2r0.js";
11
+ } from "./roy-agent-core-zvwdfm79.js";
12
12
  import {
13
13
  SQLiteTaskStore,
14
14
  getDefaultTaskDbPath
@@ -14,7 +14,7 @@ import {
14
14
  } from "./roy-agent-core-c1v263jn.js";
15
15
  import {
16
16
  isValidSessionId
17
- } from "./roy-agent-core-bqe4c9f2.js";
17
+ } from "./roy-agent-core-kr58bgz0.js";
18
18
  import {
19
19
  TracedAs,
20
20
  init_decorator
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  MemorySessionStore,
8
8
  SQLiteSessionStore
9
- } from "./roy-agent-core-zs4f0tcy.js";
9
+ } from "./roy-agent-core-xjj88tpn.js";
10
10
  import {
11
11
  envKeyToConfigKey
12
12
  } from "./roy-agent-core-7hh0brvs.js";
@@ -664,6 +664,14 @@ class SessionComponent extends BaseComponent {
664
664
  }
665
665
  return success;
666
666
  }
667
+ async endSessionCleanup(sessionId, opts) {
668
+ const store = this.store;
669
+ if (typeof store?.endSessionCleanup === "function") {
670
+ await store.endSessionCleanup(sessionId, opts);
671
+ } else {
672
+ logger.debug(`[SessionComponent] endSessionCleanup skipped: store type ${this.config?.storage?.type ?? "unknown"} 不实现该方法`);
673
+ }
674
+ }
667
675
  async getContext(sessionId, options) {
668
676
  const session = await this.get(sessionId);
669
677
  if (!session) {
@@ -18,7 +18,7 @@ import {
18
18
  createWorkflowSearchTool,
19
19
  createWorkflowTagListTool,
20
20
  createWorkflowValidateTool
21
- } from "./roy-agent-core-kkt2ndpf.js";
21
+ } from "./roy-agent-core-j8t1tyhr.js";
22
22
  import {
23
23
  WorkflowService
24
24
  } from "./roy-agent-core-r15sn7ve.js";
@@ -32,10 +32,24 @@ function generateMessageId() {
32
32
  }
33
33
 
34
34
  class MemorySessionStore extends BaseSessionStore {
35
+ maxMessagesPerSession;
36
+ maxCheckpointsPerSession;
37
+ defaultKeepAllMessagesUntilCompaction;
35
38
  sessions = new Map;
36
39
  messages = new Map;
37
40
  checkpoints = new Map;
38
41
  messageConverter = new SessionMessageConverter;
42
+ constructor(options = {}) {
43
+ super();
44
+ this.maxMessagesPerSession = options.maxMessagesPerSession ?? 1e4;
45
+ this.maxCheckpointsPerSession = options.maxCheckpointsPerSession ?? 1000;
46
+ this.defaultKeepAllMessagesUntilCompaction = options.keepAllMessagesUntilCompaction ?? true;
47
+ }
48
+ trimMessages(messages) {
49
+ if (messages.length > this.maxMessagesPerSession) {
50
+ messages.splice(0, messages.length - this.maxMessagesPerSession);
51
+ }
52
+ }
39
53
  async create(options) {
40
54
  const now = Date.now();
41
55
  const rawParent = options.parentSessionId !== undefined ? options.parentSessionId : options.parentID ?? null;
@@ -126,6 +140,7 @@ class MemorySessionStore extends BaseSessionStore {
126
140
  if (deleted) {
127
141
  this.messages.delete(id);
128
142
  this.checkpoints.delete(id);
143
+ this.messageTruncOffsets.delete(id);
129
144
  }
130
145
  return deleted;
131
146
  }
@@ -149,6 +164,7 @@ class MemorySessionStore extends BaseSessionStore {
149
164
  msg.timestamp = Date.now();
150
165
  const sessionMessages = this.messages.get(sessionId) ?? [];
151
166
  sessionMessages.push(msg);
167
+ this.trimMessages(sessionMessages);
152
168
  this.messages.set(sessionId, sessionMessages);
153
169
  session.messageCount = sessionMessages.filter((m) => !m.isArchived).length;
154
170
  session.metadata = {
@@ -183,6 +199,7 @@ class MemorySessionStore extends BaseSessionStore {
183
199
  sessionMessages.push(msg);
184
200
  ids.push(msg.id);
185
201
  }
202
+ this.trimMessages(sessionMessages);
186
203
  this.messages.set(sessionId, sessionMessages);
187
204
  session.messageCount = sessionMessages.filter((m) => !m.isArchived).length;
188
205
  session.metadata = {
@@ -262,6 +279,13 @@ class MemorySessionStore extends BaseSessionStore {
262
279
  }
263
280
  const cps = this.checkpoints.get(sessionId) ?? [];
264
281
  cps.push(checkpoint);
282
+ let droppedCheckpoints = [];
283
+ if (cps.length > this.maxCheckpointsPerSession) {
284
+ droppedCheckpoints = cps.splice(0, cps.length - this.maxCheckpointsPerSession);
285
+ }
286
+ if (!this.defaultKeepAllMessagesUntilCompaction && cps.length > 1) {
287
+ droppedCheckpoints = droppedCheckpoints.concat(cps.splice(0, cps.length - 1));
288
+ }
265
289
  this.checkpoints.set(sessionId, cps);
266
290
  const meta = session.metadata || {};
267
291
  const checkpointsMeta = meta.checkpoints || { checkpoints: [] };
@@ -272,13 +296,115 @@ class MemorySessionStore extends BaseSessionStore {
272
296
  createdAt: checkpoint.createdAt,
273
297
  type: checkpoint.type
274
298
  });
275
- checkpointsMeta.latestCheckpointId = checkpoint.id;
299
+ if (droppedCheckpoints.length > 0) {
300
+ const droppedIds = new Set(droppedCheckpoints.map((c) => c.id));
301
+ checkpointsMeta.checkpoints = checkpointsMeta.checkpoints.filter((c) => !droppedIds.has(c.id));
302
+ if (meta.checkpointDetails) {
303
+ for (const id of droppedIds) {
304
+ delete meta.checkpointDetails[id];
305
+ }
306
+ }
307
+ }
308
+ checkpointsMeta.latestCheckpointId = cps[cps.length - 1]?.id ?? checkpoint.id;
276
309
  meta.checkpoints = checkpointsMeta;
277
310
  if (!meta.checkpointDetails) {
278
311
  meta.checkpointDetails = {};
279
312
  }
280
313
  meta.checkpointDetails[checkpoint.id] = checkpoint;
281
314
  session.metadata = meta;
315
+ if (!this.defaultKeepAllMessagesUntilCompaction && cps.length > 0) {
316
+ const latest = cps[cps.length - 1];
317
+ this.truncateMessagesBeforeIndex(sessionId, latest.messageIndex);
318
+ const sessionMessages = this.messages.get(sessionId) ?? [];
319
+ session.messageCount = sessionMessages.filter((m) => !m.isArchived).length;
320
+ session.metadata = {
321
+ ...session.metadata,
322
+ messageCount: session.messageCount
323
+ };
324
+ }
325
+ session.updatedAt = Date.now();
326
+ }
327
+ messageTruncOffsets = new Map;
328
+ truncateMessagesBeforeIndex(sessionId, originalBeforeIndex) {
329
+ const sessionMessages = this.messages.get(sessionId);
330
+ if (!sessionMessages || sessionMessages.length === 0)
331
+ return;
332
+ const offset = this.messageTruncOffsets.get(sessionId) ?? 0;
333
+ const adjustedIndex = originalBeforeIndex - offset;
334
+ if (adjustedIndex <= 0) {
335
+ return;
336
+ }
337
+ if (adjustedIndex >= sessionMessages.length) {
338
+ return;
339
+ }
340
+ sessionMessages.splice(0, adjustedIndex);
341
+ this.messageTruncOffsets.set(sessionId, offset + adjustedIndex);
342
+ this.messages.set(sessionId, sessionMessages);
343
+ const cps = this.checkpoints.get(sessionId);
344
+ if (cps) {
345
+ for (const cp of cps) {
346
+ cp.messageIndex = Math.max(0, cp.messageIndex - adjustedIndex);
347
+ }
348
+ }
349
+ const session = this.sessions.get(sessionId);
350
+ if (session) {
351
+ const meta = session.metadata;
352
+ if (meta) {
353
+ const checkpointsMeta = meta.checkpoints;
354
+ if (checkpointsMeta?.checkpoints) {
355
+ for (const cm of checkpointsMeta.checkpoints) {
356
+ cm.messageIndex = Math.max(0, cm.messageIndex - adjustedIndex);
357
+ }
358
+ }
359
+ if (meta.checkpointDetails) {
360
+ const details = meta.checkpointDetails;
361
+ for (const id in details) {
362
+ details[id].messageIndex = Math.max(0, details[id].messageIndex - adjustedIndex);
363
+ }
364
+ }
365
+ }
366
+ }
367
+ }
368
+ async endSessionCleanup(sessionId, opts = {}) {
369
+ const session = this.sessions.get(sessionId);
370
+ if (!session) {
371
+ return;
372
+ }
373
+ const keepAllMessages = opts.keepAllMessagesUntilCompaction ?? this.defaultKeepAllMessagesUntilCompaction;
374
+ const keepLatest = Math.max(0, opts.keepLatestCheckpoints ?? 1);
375
+ const cps = this.checkpoints.get(sessionId) ?? [];
376
+ let droppedCheckpoints = [];
377
+ const targetCheckpointCap = keepAllMessages ? this.maxCheckpointsPerSession : keepLatest;
378
+ if (cps.length > targetCheckpointCap) {
379
+ droppedCheckpoints = cps.splice(0, cps.length - targetCheckpointCap);
380
+ }
381
+ this.checkpoints.set(sessionId, cps);
382
+ if (droppedCheckpoints.length > 0) {
383
+ const meta = session.metadata;
384
+ const droppedIds = new Set(droppedCheckpoints.map((c) => c.id));
385
+ const checkpointsMeta = meta.checkpoints ?? {
386
+ checkpoints: []
387
+ };
388
+ checkpointsMeta.checkpoints = checkpointsMeta.checkpoints.filter((c) => !droppedIds.has(c.id));
389
+ checkpointsMeta.latestCheckpointId = cps[cps.length - 1]?.id;
390
+ meta.checkpoints = checkpointsMeta;
391
+ if (meta.checkpointDetails) {
392
+ for (const id of droppedIds) {
393
+ delete meta.checkpointDetails[id];
394
+ }
395
+ }
396
+ session.metadata = meta;
397
+ }
398
+ if (!keepAllMessages && cps.length > 0) {
399
+ const latest = cps[cps.length - 1];
400
+ this.truncateMessagesBeforeIndex(sessionId, latest.messageIndex);
401
+ const sessionMessages = this.messages.get(sessionId) ?? [];
402
+ session.messageCount = sessionMessages.filter((m) => !m.isArchived).length;
403
+ session.metadata = {
404
+ ...session.metadata,
405
+ messageCount: session.messageCount
406
+ };
407
+ }
282
408
  session.updatedAt = Date.now();
283
409
  }
284
410
  async getCheckpoints(sessionId) {
@@ -420,6 +546,7 @@ class MemorySessionStore extends BaseSessionStore {
420
546
  this.sessions.clear();
421
547
  this.messages.clear();
422
548
  this.checkpoints.clear();
549
+ this.messageTruncOffsets.clear();
423
550
  }
424
551
  }
425
552
  // src/env/session/storage/sqlite.ts
@@ -896,7 +896,10 @@ var PROGRESS_INTERVAL = 1200000;
896
896
 
897
897
  class BackgroundTaskManager {
898
898
  env;
899
+ maxProcessRegistries = 1000;
900
+ maxTerminalTasks = 1000;
899
901
  tasks = new Map;
902
+ terminalTasks = new Map;
900
903
  abortControllers = new Map;
901
904
  progressTimers = new Map;
902
905
  processRegistries = new Map;
@@ -964,6 +967,52 @@ class BackgroundTaskManager {
964
967
  set.clear();
965
968
  return { runIds, stopResults };
966
969
  }
970
+ finalizeTask(taskId, reason) {
971
+ if (!taskId)
972
+ return;
973
+ this.stopProgressReporter(taskId);
974
+ this.progressTimers.delete(taskId);
975
+ const task = this.tasks.get(taskId);
976
+ if (task) {
977
+ this.tasks.delete(taskId);
978
+ if (this.terminalTasks.size >= this.maxTerminalTasks) {
979
+ const oldestKey = this.terminalTasks.keys().next().value;
980
+ if (oldestKey !== undefined) {
981
+ this.terminalTasks.delete(oldestKey);
982
+ }
983
+ }
984
+ this.terminalTasks.set(taskId, task);
985
+ }
986
+ const abortCtl = this.abortControllers.get(taskId);
987
+ if (abortCtl) {
988
+ try {
989
+ abortCtl.abort();
990
+ } catch {}
991
+ }
992
+ this.abortControllers.delete(taskId);
993
+ this.workflowRunRegistries.delete(taskId);
994
+ const registry = this.processRegistries.get(taskId);
995
+ if (registry && registry.size() > 0) {
996
+ logger3.debug(`[BackgroundTaskManager] finalizeTask保留 processRegistry ${taskId} (residualPIDs=${registry.size()}, reason=${reason})`);
997
+ }
998
+ logger3.debug(`[BackgroundTaskManager] finalizeTask taskId=${taskId} reason=${reason}`);
999
+ }
1000
+ getProcessRegistrySize() {
1001
+ return this.processRegistries.size;
1002
+ }
1003
+ getMaxProcessRegistries() {
1004
+ return this.maxProcessRegistries;
1005
+ }
1006
+ cleanupEmptyProcessRegistries() {
1007
+ let cleaned = 0;
1008
+ for (const [taskId, registry] of this.processRegistries) {
1009
+ if (registry.size() === 0) {
1010
+ this.processRegistries.delete(taskId);
1011
+ cleaned++;
1012
+ }
1013
+ }
1014
+ return cleaned;
1015
+ }
967
1016
  static DEFAULT_WORKFLOW_ENTRY_AGENT = "workflow-runner";
968
1017
  resolveEntryAgent(subagentType) {
969
1018
  try {
@@ -1074,6 +1123,12 @@ class BackgroundTaskManager {
1074
1123
  }
1075
1124
  }
1076
1125
  const abortController = new AbortController;
1126
+ if (this.processRegistries.size >= this.maxProcessRegistries) {
1127
+ this.cleanupEmptyProcessRegistries();
1128
+ if (this.processRegistries.size >= this.maxProcessRegistries) {
1129
+ throw new Error(`BackgroundTaskManager.processRegistries 达到上限 ${this.maxProcessRegistries}(含残留 PID),拒绝创建新 task(taskId=${taskIdGen})。请清理 / 重启 / 调高 maxProcessRegistries。`);
1130
+ }
1131
+ }
1077
1132
  const processRegistry = new ProcessRegistry;
1078
1133
  this.processRegistries.set(taskIdGen, processRegistry);
1079
1134
  const createdAt = Date.now();
@@ -1214,7 +1269,15 @@ class BackgroundTaskManager {
1214
1269
  error: errorMessage
1215
1270
  });
1216
1271
  } finally {
1217
- this.stopProgressReporter(taskId);
1272
+ this.finalizeTask(taskId, task.status);
1273
+ const sessionComp = this.getSessionComponent();
1274
+ if (sessionComp?.endSessionCleanup && task?.subSessionId) {
1275
+ try {
1276
+ await sessionComp.endSessionCleanup(task.subSessionId);
1277
+ } catch (err) {
1278
+ logger3.warn(`[BackgroundTaskManager] endSessionCleanup failed for ${task.subSessionId}`, { error: err instanceof Error ? err.message : String(err) });
1279
+ }
1280
+ }
1218
1281
  }
1219
1282
  }
1220
1283
  startProgressReporter(taskId, parentSessionId) {
@@ -1426,10 +1489,17 @@ ${reuseSection.markdown}`;
1426
1489
  });
1427
1490
  }
1428
1491
  async stopTask(taskId) {
1429
- const task = this.tasks.get(taskId);
1492
+ const task = this.tasks.get(taskId) ?? this.terminalTasks.get(taskId);
1430
1493
  if (!task) {
1431
1494
  return { success: false, message: "Task not found" };
1432
1495
  }
1496
+ if (this.terminalTasks.has(taskId)) {
1497
+ return {
1498
+ success: false,
1499
+ task,
1500
+ message: `Cannot stop task with status: ${task.status}`
1501
+ };
1502
+ }
1433
1503
  if (task.status === "completed" || task.status === "failed" || task.status === "stopped" || task.status === "timeout") {
1434
1504
  return {
1435
1505
  success: false,
@@ -1462,6 +1532,7 @@ ${reuseSection.markdown}`;
1462
1532
  associatedTaskId: task.associatedTaskId
1463
1533
  };
1464
1534
  this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, task.parentSessionId);
1535
+ this.finalizeTask(taskId, "stopped");
1465
1536
  return {
1466
1537
  success: true,
1467
1538
  task,
@@ -1471,10 +1542,10 @@ ${reuseSection.markdown}`;
1471
1542
  };
1472
1543
  }
1473
1544
  getTask(taskId) {
1474
- return this.tasks.get(taskId);
1545
+ return this.tasks.get(taskId) ?? this.terminalTasks.get(taskId);
1475
1546
  }
1476
1547
  listTasks() {
1477
- return Array.from(this.tasks.values());
1548
+ return Array.from(this.tasks.values()).concat(Array.from(this.terminalTasks.values()));
1478
1549
  }
1479
1550
  hasActiveTaskForParent(parentSessionId) {
1480
1551
  if (!parentSessionId)
@@ -1506,7 +1577,18 @@ ${reuseSection.markdown}`;
1506
1577
  return { stoppedTaskIds };
1507
1578
  }
1508
1579
  async forceStopAllAcrossParents() {
1509
- for (const [taskId, task] of this.tasks) {
1580
+ const seen = new Set;
1581
+ const allTaskIds = new Set([
1582
+ ...this.tasks.keys(),
1583
+ ...this.terminalTasks.keys(),
1584
+ ...this.processRegistries.keys()
1585
+ ]);
1586
+ for (const taskId of allTaskIds) {
1587
+ if (seen.has(taskId))
1588
+ continue;
1589
+ seen.add(taskId);
1590
+ const task = this.tasks.get(taskId) ?? this.terminalTasks.get(taskId);
1591
+ const taskSafe = task;
1510
1592
  try {
1511
1593
  await this.processRegistries.get(taskId)?.killAll();
1512
1594
  } catch (err) {
@@ -1518,29 +1600,29 @@ ${reuseSection.markdown}`;
1518
1600
  logger3.warn(`[BackgroundTaskManager] forceStopAllAcrossParents propagateStopToWorkflowRuns failed for ${taskId}: ${err instanceof Error ? err.message : String(err)}`);
1519
1601
  }
1520
1602
  let justMarkedStopped = false;
1521
- if (task.status === "running" || task.status === "pending") {
1603
+ if (taskSafe && (taskSafe.status === "running" || taskSafe.status === "pending")) {
1522
1604
  try {
1523
- task.status = "stopped";
1524
- task.completedAt = Date.now();
1525
- task.lastUpdatedAt = task.completedAt;
1526
- task.abortController?.abort();
1605
+ taskSafe.status = "stopped";
1606
+ taskSafe.completedAt = Date.now();
1607
+ taskSafe.lastUpdatedAt = taskSafe.completedAt;
1608
+ taskSafe.abortController?.abort();
1527
1609
  justMarkedStopped = true;
1528
1610
  } catch (err) {
1529
1611
  logger3.warn(`[BackgroundTaskManager] forceStopAllAcrossParents mark stopped failed for ${taskId}: ${err instanceof Error ? err.message : String(err)}`);
1530
1612
  }
1531
1613
  }
1532
- if (justMarkedStopped) {
1614
+ if (justMarkedStopped && taskSafe) {
1533
1615
  const stoppedPayload = {
1534
- backgroundTaskId: task.id,
1535
- subSessionId: task.subSessionId,
1536
- parentSessionId: task.parentSessionId,
1616
+ backgroundTaskId: taskSafe.id,
1617
+ subSessionId: taskSafe.subSessionId,
1618
+ parentSessionId: taskSafe.parentSessionId,
1537
1619
  status: "stopped",
1538
- description: task.description,
1620
+ description: taskSafe.description,
1539
1621
  error: "force stop all",
1540
- executionTimeMs: task.startedAt && task.completedAt ? task.completedAt - task.startedAt : 0,
1541
- associatedTaskId: task.associatedTaskId
1622
+ executionTimeMs: taskSafe.startedAt && taskSafe.completedAt ? taskSafe.completedAt - taskSafe.startedAt : 0,
1623
+ associatedTaskId: taskSafe.associatedTaskId
1542
1624
  };
1543
- this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, task.parentSessionId);
1625
+ this.publishBackgroundEvent(BackgroundTaskEventTypes.STOPPED, stoppedPayload, taskSafe.parentSessionId);
1544
1626
  }
1545
1627
  }
1546
1628
  }
@@ -1548,9 +1630,16 @@ ${reuseSection.markdown}`;
1548
1630
  return this.forceStopAllAcrossParents();
1549
1631
  }
1550
1632
  async dispose() {
1551
- for (const [taskId, controller] of this.abortControllers) {
1552
- controller.abort();
1553
- logger3.debug(`[BackgroundTaskManager] Aborted task: ${taskId}`);
1633
+ for (const [, timer] of this.progressTimers) {
1634
+ try {
1635
+ clearInterval(timer);
1636
+ } catch {}
1637
+ }
1638
+ this.progressTimers.clear();
1639
+ for (const [, controller] of this.abortControllers) {
1640
+ try {
1641
+ controller.abort();
1642
+ } catch {}
1554
1643
  }
1555
1644
  this.abortControllers.clear();
1556
1645
  for (const [, registry] of this.processRegistries) {
@@ -1599,6 +1688,9 @@ __legacyDecorateClassTS([
1599
1688
  log: true
1600
1689
  })
1601
1690
  ], BackgroundTaskManager.prototype, "propagateStopToWorkflowRuns", null);
1691
+ __legacyDecorateClassTS([
1692
+ TracedAs("task.background.finalizeTask", { recordParams: true, recordResult: false, log: true })
1693
+ ], BackgroundTaskManager.prototype, "finalizeTask", null);
1602
1694
  __legacyDecorateClassTS([
1603
1695
  TracedAs("task.background.resolveEntryAgent", { recordParams: true, recordResult: true })
1604
1696
  ], BackgroundTaskManager.prototype, "resolveEntryAgent", null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-agent-core",
3
- "version": "1.6.20",
3
+ "version": "1.6.21",
4
4
  "type": "module",
5
5
  "description": "Core SDK for roy-agent - Environment, Components, Tools, Sessions, Tasks",
6
6
  "main": "./dist/index.js",