@ainetwork/adk-provider-memory-mongodb 0.4.0 → 0.5.0

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.
Files changed (54) hide show
  1. package/dist/{chunk-GPOFS7ZT.js → chunk-2XJ6S2W5.js} +12 -7
  2. package/dist/chunk-2XJ6S2W5.js.map +1 -0
  3. package/dist/{chunk-5CCEN7NK.js → chunk-QULDFKGZ.js} +5 -1
  4. package/dist/chunk-QULDFKGZ.js.map +1 -0
  5. package/dist/chunk-RC275GLE.js +70 -0
  6. package/dist/chunk-RC275GLE.js.map +1 -0
  7. package/dist/{chunk-NGLXQZLX.js → chunk-SJ2FHHN6.js} +13 -10
  8. package/dist/chunk-SJ2FHHN6.js.map +1 -0
  9. package/dist/index.cjs +322 -75
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +11 -3
  12. package/dist/index.d.ts +11 -3
  13. package/dist/index.js +232 -59
  14. package/dist/index.js.map +1 -1
  15. package/dist/models/messages.model.cjs +4 -0
  16. package/dist/models/messages.model.cjs.map +1 -1
  17. package/dist/models/messages.model.d.cts +14 -1
  18. package/dist/models/messages.model.d.ts +14 -1
  19. package/dist/models/messages.model.js +1 -1
  20. package/dist/models/threads.model.cjs +11 -6
  21. package/dist/models/threads.model.cjs.map +1 -1
  22. package/dist/models/threads.model.d.cts +22 -9
  23. package/dist/models/threads.model.d.ts +22 -9
  24. package/dist/models/threads.model.js +1 -1
  25. package/dist/models/user-workflow.model.cjs +105 -0
  26. package/dist/models/user-workflow.model.cjs.map +1 -0
  27. package/dist/models/user-workflow.model.d.cts +92 -0
  28. package/dist/models/user-workflow.model.d.ts +92 -0
  29. package/dist/models/user-workflow.model.js +9 -0
  30. package/dist/models/{workflow.model.cjs → workflow-template.model.cjs} +18 -15
  31. package/dist/models/workflow-template.model.cjs.map +1 -0
  32. package/dist/models/workflow-template.model.d.cts +60 -0
  33. package/dist/models/workflow-template.model.d.ts +60 -0
  34. package/dist/models/workflow-template.model.js +9 -0
  35. package/dist/models/workflow-template.model.js.map +1 -0
  36. package/implements/base.memory.ts +130 -12
  37. package/implements/thread.memory.ts +48 -22
  38. package/implements/user-workflow.memory.ts +87 -0
  39. package/implements/workflow-template.memory.ts +69 -0
  40. package/models/messages.model.ts +7 -0
  41. package/models/threads.model.ts +16 -9
  42. package/models/user-workflow.model.ts +91 -0
  43. package/models/workflow-template.model.ts +58 -0
  44. package/package.json +3 -3
  45. package/dist/chunk-5CCEN7NK.js.map +0 -1
  46. package/dist/chunk-GPOFS7ZT.js.map +0 -1
  47. package/dist/chunk-NGLXQZLX.js.map +0 -1
  48. package/dist/models/workflow.model.cjs.map +0 -1
  49. package/dist/models/workflow.model.d.cts +0 -54
  50. package/dist/models/workflow.model.d.ts +0 -54
  51. package/dist/models/workflow.model.js +0 -9
  52. package/implements/workflow.memory.ts +0 -78
  53. package/models/workflow.model.ts +0 -46
  54. /package/dist/models/{workflow.model.js.map → user-workflow.model.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -35,7 +35,7 @@ __export(index_exports, {
35
35
  module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // implements/base.memory.ts
38
- var import_mongoose10 = __toESM(require("mongoose"), 1);
38
+ var import_mongoose12 = __toESM(require("mongoose"), 1);
39
39
  var import_logger2 = require("@ainetwork/adk/utils/logger");
40
40
 
41
41
  // models/agent.model.ts
@@ -259,14 +259,19 @@ var ThreadObjectSchema = new import_mongoose4.Schema(
259
259
  type: String,
260
260
  required: false
261
261
  },
262
- created_at: {
263
- type: Number,
264
- required: true
262
+ isPinned: {
263
+ type: Boolean,
264
+ required: false,
265
+ default: false
265
266
  },
266
- updated_at: {
267
- type: Number,
268
- required: true
267
+ workflowId: {
268
+ type: String,
269
+ required: false,
270
+ index: true
269
271
  }
272
+ },
273
+ {
274
+ timestamps: true
270
275
  }
271
276
  );
272
277
  var ThreadModel = import_mongoose5.default.model("Thread", ThreadObjectSchema);
@@ -316,8 +321,12 @@ var MessageObjectSchema = new import_mongoose6.Schema(
316
321
  type: import_mongoose6.Schema.Types.Mixed,
317
322
  default: {}
318
323
  }
324
+ },
325
+ {
326
+ timestamps: true
319
327
  }
320
328
  );
329
+ MessageObjectSchema.index({ threadId: 1, messageId: 1 }, { unique: true });
321
330
  var MessageModel = import_mongoose7.default.model("Message", MessageObjectSchema);
322
331
 
323
332
  // implements/thread.memory.ts
@@ -341,6 +350,8 @@ var MongoDBThread = class {
341
350
  userId: thread.userId,
342
351
  type: thread.type,
343
352
  title: thread.title || "New thread",
353
+ isPinned: thread.isPinned ?? false,
354
+ workflowId: thread.workflowId,
344
355
  messages: []
345
356
  };
346
357
  messages.forEach((message) => {
@@ -355,36 +366,39 @@ var MongoDBThread = class {
355
366
  return threadObject;
356
367
  }, `getThread(${userId}, ${threadId})`);
357
368
  }
358
- async createThread(type, userId, threadId, title) {
369
+ async createThread(type, userId, threadId, title, workflowId) {
359
370
  return this.executeWithRetry(async () => {
360
- const now = Date.now();
361
371
  await ThreadModel.create({
362
372
  type,
363
373
  userId,
364
374
  threadId,
365
375
  title,
366
- updated_at: now,
367
- created_at: now
376
+ workflowId
368
377
  });
369
- return { type, userId, threadId, title, messages: [] };
378
+ return { type, userId, threadId, title, workflowId, messages: [] };
370
379
  }, `createThread(${userId}, ${threadId})`);
371
380
  }
372
381
  async addMessagesToThread(userId, threadId, messages) {
373
382
  return this.executeWithRetry(async () => {
374
- await ThreadModel.updateOne({ threadId, userId }, {
375
- updated_at: Date.now()
376
- });
377
- for (const message of messages) {
378
- await MessageModel.create({
379
- threadId,
380
- messageId: message.messageId,
381
- userId,
382
- role: message.role,
383
- content: message.content,
384
- timestamp: message.timestamp,
385
- metadata: message.metadata
386
- });
383
+ if (messages.length > 0) {
384
+ const messageIds = messages.map((m) => m.messageId);
385
+ await MessageModel.deleteMany({ threadId, userId, messageId: { $in: messageIds } });
386
+ await MessageModel.insertMany(
387
+ messages.map((message) => ({
388
+ threadId,
389
+ messageId: message.messageId,
390
+ userId,
391
+ role: message.role,
392
+ content: message.content,
393
+ timestamp: message.timestamp,
394
+ metadata: message.metadata
395
+ }))
396
+ );
387
397
  }
398
+ await ThreadModel.updateOne(
399
+ { threadId, userId },
400
+ { $set: { updatedAt: /* @__PURE__ */ new Date() } }
401
+ );
388
402
  }, `addMessagesToThread(${userId}, ${threadId})`);
389
403
  }
390
404
  async deleteThread(userId, threadId) {
@@ -394,28 +408,43 @@ var MongoDBThread = class {
394
408
  await ThreadModel.deleteOne({ userId, threadId }).maxTimeMS(timeout);
395
409
  }, `deleteThread(${userId}, ${threadId})`);
396
410
  }
397
- async listThreads(userId) {
411
+ async listThreads(userId, filter) {
398
412
  return this.executeWithRetry(async () => {
399
413
  const timeout = this.getOperationTimeout();
400
- const threads = await ThreadModel.find({ userId }).sort({ updated_at: -1 }).maxTimeMS(timeout);
414
+ const query = { userId };
415
+ if (filter?.workflowId) query.workflowId = filter.workflowId;
416
+ if (filter?.type) query.type = filter.type;
417
+ const threads = await ThreadModel.find(query).sort({ updatedAt: -1 }).maxTimeMS(timeout);
401
418
  const data = threads.map((thread) => {
402
419
  return {
403
420
  type: thread.type,
404
421
  userId,
405
422
  threadId: thread.threadId,
406
423
  title: thread.title,
407
- updatedAt: thread.updated_at
424
+ isPinned: thread.isPinned ?? false,
425
+ workflowId: thread.workflowId,
426
+ createdAt: thread.createdAt?.toISOString(),
427
+ updatedAt: thread.updatedAt?.toISOString()
408
428
  };
409
429
  });
410
430
  return data;
411
431
  }, `listThreads(${userId})`);
412
432
  }
433
+ async updateThreadPin(userId, threadId, isPinned) {
434
+ return this.executeWithRetry(async () => {
435
+ const timeout = this.getOperationTimeout();
436
+ await ThreadModel.updateOne(
437
+ { threadId, userId },
438
+ { $set: { isPinned } }
439
+ ).maxTimeMS(timeout);
440
+ }, `updateThreadPin(${userId}, ${threadId})`);
441
+ }
413
442
  };
414
443
 
415
- // models/workflow.model.ts
444
+ // models/user-workflow.model.ts
416
445
  var import_mongoose8 = require("mongoose");
417
446
  var import_mongoose9 = __toESM(require("mongoose"), 1);
418
- var WorkflowObjectSchema = new import_mongoose8.Schema(
447
+ var UserWorkflowObjectSchema = new import_mongoose8.Schema(
419
448
  {
420
449
  workflowId: {
421
450
  type: String,
@@ -423,81 +452,203 @@ var WorkflowObjectSchema = new import_mongoose8.Schema(
423
452
  unique: true
424
453
  },
425
454
  userId: {
426
- type: String
455
+ type: String,
456
+ required: true,
457
+ index: true
427
458
  },
428
459
  title: {
429
460
  type: String,
430
461
  required: true
431
462
  },
432
463
  description: {
433
- type: String,
434
- required: true
464
+ type: String
435
465
  },
436
466
  active: {
437
467
  type: Boolean,
438
468
  required: true,
439
469
  default: false
440
470
  },
471
+ templateId: {
472
+ type: String
473
+ },
441
474
  content: {
442
475
  type: String,
443
476
  required: true
477
+ },
478
+ variables: {
479
+ type: import_mongoose8.Schema.Types.Mixed
480
+ },
481
+ variableValues: {
482
+ type: import_mongoose8.Schema.Types.Mixed
483
+ },
484
+ schedule: {
485
+ type: String
486
+ },
487
+ timezone: {
488
+ type: String
489
+ },
490
+ lastRunAt: {
491
+ type: Number
492
+ },
493
+ nextRunAt: {
494
+ type: Number
495
+ },
496
+ lastThreadId: {
497
+ type: String
444
498
  }
445
499
  },
446
500
  {
447
501
  timestamps: true
448
502
  }
449
503
  );
450
- var WorkflowModel = import_mongoose9.default.model("Workflow", WorkflowObjectSchema);
504
+ var UserWorkflowModel = import_mongoose9.default.model(
505
+ "UserWorkflow",
506
+ UserWorkflowObjectSchema
507
+ );
451
508
 
452
- // implements/workflow.memory.ts
453
- var MongoDBWorkflow = class {
509
+ // implements/user-workflow.memory.ts
510
+ var MongoDBUserWorkflow = class {
454
511
  executeWithRetry;
455
512
  getOperationTimeout;
456
513
  constructor(executeWithRetry, getOperationTimeout) {
457
514
  this.executeWithRetry = executeWithRetry;
458
515
  this.getOperationTimeout = getOperationTimeout;
459
516
  }
460
- async createWorkflow(workflow) {
517
+ async createUserWorkflow(workflow) {
461
518
  return this.executeWithRetry(async () => {
462
- const timeout = this.getOperationTimeout();
463
- const created = await WorkflowModel.create(workflow);
519
+ const created = await UserWorkflowModel.create(workflow);
464
520
  return created.toObject();
465
- }, "createWorkflow()");
521
+ }, "createUserWorkflow()");
466
522
  }
467
- async getWorkflow(workflowId) {
523
+ async getUserWorkflow(workflowId) {
468
524
  return this.executeWithRetry(async () => {
469
525
  const timeout = this.getOperationTimeout();
470
- const workflow = await WorkflowModel.findOne({
471
- workflowId
472
- }).maxTimeMS(timeout).lean();
526
+ const workflow = await UserWorkflowModel.findOne({ workflowId }).maxTimeMS(timeout).lean();
473
527
  return workflow || void 0;
474
- }, "getWorkflow()");
528
+ }, "getUserWorkflow()");
475
529
  }
476
- async updateWorkflow(workflowId, updates) {
530
+ async updateUserWorkflow(workflowId, updates) {
477
531
  if (!updates.userId) {
478
- throw new Error("userId is required for updateWorkflow");
532
+ throw new Error("userId is required for updateUserWorkflow");
479
533
  }
534
+ const { userId, workflowId: _workflowId, ...mutableUpdates } = updates;
480
535
  return this.executeWithRetry(async () => {
481
536
  const timeout = this.getOperationTimeout();
482
- await WorkflowModel.updateOne(
483
- { workflowId, userId: updates.userId },
484
- { $set: updates }
537
+ await UserWorkflowModel.updateOne(
538
+ { workflowId, userId },
539
+ { $set: mutableUpdates }
485
540
  ).maxTimeMS(timeout);
486
- }, "updateWorkflow()");
541
+ }, "updateUserWorkflow()");
542
+ }
543
+ async deleteUserWorkflow(workflowId, userId) {
544
+ return this.executeWithRetry(async () => {
545
+ const timeout = this.getOperationTimeout();
546
+ await UserWorkflowModel.deleteOne({ workflowId, userId }).maxTimeMS(timeout);
547
+ }, "deleteUserWorkflow()");
487
548
  }
488
- async deleteWorkflow(workflowId, userId) {
549
+ async listUserWorkflows(userId) {
489
550
  return this.executeWithRetry(async () => {
490
551
  const timeout = this.getOperationTimeout();
491
- await WorkflowModel.deleteOne({ workflowId, userId }).maxTimeMS(timeout);
492
- }, "deleteWorkflow()");
552
+ const query = userId ? { userId } : {};
553
+ const workflows = await UserWorkflowModel.find(query).maxTimeMS(timeout).lean();
554
+ return workflows;
555
+ }, "listUserWorkflows()");
493
556
  }
494
- async listWorkflows(userId) {
557
+ async listActiveScheduledWorkflows() {
495
558
  return this.executeWithRetry(async () => {
496
559
  const timeout = this.getOperationTimeout();
497
- const query = userId ? { $or: [{ userId }, { userId: { $exists: false } }, { userId: null }] } : { $or: [{ userId: { $exists: false } }, { userId: null }] };
498
- const workflows = await WorkflowModel.find(query).maxTimeMS(timeout).lean();
560
+ const workflows = await UserWorkflowModel.find({
561
+ active: true,
562
+ schedule: { $exists: true, $ne: null }
563
+ }).maxTimeMS(timeout).lean();
499
564
  return workflows;
500
- }, "listWorkflows()");
565
+ }, "listActiveScheduledWorkflows()");
566
+ }
567
+ };
568
+
569
+ // models/workflow-template.model.ts
570
+ var import_mongoose10 = require("mongoose");
571
+ var import_mongoose11 = __toESM(require("mongoose"), 1);
572
+ var WorkflowTemplateObjectSchema = new import_mongoose10.Schema(
573
+ {
574
+ templateId: {
575
+ type: String,
576
+ required: true,
577
+ unique: true
578
+ },
579
+ title: {
580
+ type: String,
581
+ required: true
582
+ },
583
+ description: {
584
+ type: String,
585
+ required: true
586
+ },
587
+ active: {
588
+ type: Boolean,
589
+ required: true,
590
+ default: false
591
+ },
592
+ content: {
593
+ type: String,
594
+ required: true
595
+ },
596
+ variables: {
597
+ type: import_mongoose10.Schema.Types.Mixed
598
+ }
599
+ },
600
+ {
601
+ timestamps: true
602
+ }
603
+ );
604
+ var WorkflowTemplateModel = import_mongoose11.default.model(
605
+ "WorkflowTemplate",
606
+ WorkflowTemplateObjectSchema
607
+ );
608
+
609
+ // implements/workflow-template.memory.ts
610
+ var MongoDBWorkflowTemplate = class {
611
+ executeWithRetry;
612
+ getOperationTimeout;
613
+ constructor(executeWithRetry, getOperationTimeout) {
614
+ this.executeWithRetry = executeWithRetry;
615
+ this.getOperationTimeout = getOperationTimeout;
616
+ }
617
+ async createTemplate(template) {
618
+ return this.executeWithRetry(async () => {
619
+ const created = await WorkflowTemplateModel.create(template);
620
+ return created.toObject();
621
+ }, "createTemplate()");
622
+ }
623
+ async getTemplate(templateId) {
624
+ return this.executeWithRetry(async () => {
625
+ const timeout = this.getOperationTimeout();
626
+ const template = await WorkflowTemplateModel.findOne({ templateId }).maxTimeMS(timeout).lean();
627
+ return template || void 0;
628
+ }, "getTemplate()");
629
+ }
630
+ async updateTemplate(templateId, updates) {
631
+ const { templateId: _templateId, ...mutableUpdates } = updates;
632
+ return this.executeWithRetry(async () => {
633
+ const timeout = this.getOperationTimeout();
634
+ await WorkflowTemplateModel.updateOne(
635
+ { templateId },
636
+ { $set: mutableUpdates }
637
+ ).maxTimeMS(timeout);
638
+ }, "updateTemplate()");
639
+ }
640
+ async deleteTemplate(templateId) {
641
+ return this.executeWithRetry(async () => {
642
+ const timeout = this.getOperationTimeout();
643
+ await WorkflowTemplateModel.deleteOne({ templateId }).maxTimeMS(timeout);
644
+ }, "deleteTemplate()");
645
+ }
646
+ async listTemplates() {
647
+ return this.executeWithRetry(async () => {
648
+ const timeout = this.getOperationTimeout();
649
+ const templates = await WorkflowTemplateModel.find().maxTimeMS(timeout).lean();
650
+ return templates;
651
+ }, "listTemplates()");
501
652
  }
502
653
  };
503
654
 
@@ -513,18 +664,26 @@ var MongoDBMemory = class _MongoDBMemory {
513
664
  connectionConfig;
514
665
  eventListenersSetup = false;
515
666
  operationTimeoutMS;
667
+ threadTTLSeconds;
668
+ orphanCleanupTimer;
516
669
  agentMemory;
517
670
  intentMemory;
518
671
  threadMemory;
519
- workflowMemory;
672
+ workflowTemplateMemory;
673
+ userWorkflowMemory;
520
674
  constructor(config) {
521
675
  const cfg = typeof config === "string" ? { uri: config } : config;
522
676
  this.uri = cfg.uri;
523
677
  this.maxReconnectAttempts = cfg.maxReconnectAttempts ?? 5;
524
678
  this.reconnectInterval = cfg.reconnectInterval ?? 5e3;
525
679
  this.operationTimeoutMS = cfg.operationTimeoutMS ?? 1e4;
680
+ if (cfg.threadTTLSeconds !== void 0 && cfg.threadTTLSeconds > 0) {
681
+ this.threadTTLSeconds = cfg.threadTTLSeconds;
682
+ }
526
683
  this.connectionConfig = {
527
- maxPoolSize: cfg.maxPoolSize ?? 1,
684
+ maxPoolSize: cfg.maxPoolSize ?? 10,
685
+ minPoolSize: 0,
686
+ maxIdleTimeMS: 3e4,
528
687
  serverSelectionTimeoutMS: cfg.serverSelectionTimeoutMS ?? 3e4,
529
688
  socketTimeoutMS: cfg.socketTimeoutMS ?? 45e3,
530
689
  connectTimeoutMS: cfg.connectTimeoutMS ?? 3e4,
@@ -549,7 +708,11 @@ var MongoDBMemory = class _MongoDBMemory {
549
708
  this.executeWithRetry.bind(this),
550
709
  this.getOperationTimeout.bind(this)
551
710
  );
552
- this.workflowMemory = new MongoDBWorkflow(
711
+ this.workflowTemplateMemory = new MongoDBWorkflowTemplate(
712
+ this.executeWithRetry.bind(this),
713
+ this.getOperationTimeout.bind(this)
714
+ );
715
+ this.userWorkflowMemory = new MongoDBUserWorkflow(
553
716
  this.executeWithRetry.bind(this),
554
717
  this.getOperationTimeout.bind(this)
555
718
  );
@@ -563,29 +726,32 @@ var MongoDBMemory = class _MongoDBMemory {
563
726
  getIntentMemory() {
564
727
  return this.intentMemory;
565
728
  }
566
- getWorkflowMemory() {
567
- return this.workflowMemory;
729
+ getWorkflowTemplateMemory() {
730
+ return this.workflowTemplateMemory;
731
+ }
732
+ getUserWorkflowMemory() {
733
+ return this.userWorkflowMemory;
568
734
  }
569
735
  setupMongooseEventListeners() {
570
736
  if (this.eventListenersSetup) return;
571
737
  this.eventListenersSetup = true;
572
- import_mongoose10.default.connection.on("connected", () => {
738
+ import_mongoose12.default.connection.on("connected", () => {
573
739
  this.connected = true;
574
740
  this.reconnectAttempts = 0;
575
741
  this.reconnecting = false;
576
742
  import_logger2.loggers.agent.info("MongoDB connected successfully");
577
743
  });
578
- import_mongoose10.default.connection.on("disconnected", () => {
744
+ import_mongoose12.default.connection.on("disconnected", () => {
579
745
  this.connected = false;
580
746
  import_logger2.loggers.agent.warn("MongoDB disconnected");
581
747
  this.handleDisconnection();
582
748
  });
583
- import_mongoose10.default.connection.on("error", (error) => {
749
+ import_mongoose12.default.connection.on("error", (error) => {
584
750
  this.connected = false;
585
751
  import_logger2.loggers.agent.error("MongoDB connection error:", error);
586
752
  this.handleDisconnection();
587
753
  });
588
- import_mongoose10.default.connection.on("reconnected", () => {
754
+ import_mongoose12.default.connection.on("reconnected", () => {
589
755
  this.connected = true;
590
756
  this.reconnectAttempts = 0;
591
757
  this.reconnecting = false;
@@ -597,13 +763,13 @@ var MongoDBMemory = class _MongoDBMemory {
597
763
  return;
598
764
  }
599
765
  this.reconnecting = true;
600
- while (this.reconnectAttempts < this.maxReconnectAttempts && !this.isConnected) {
766
+ while (this.reconnectAttempts < this.maxReconnectAttempts && !this.connected) {
601
767
  this.reconnectAttempts++;
602
768
  import_logger2.loggers.agent.info(
603
769
  `Attempting to reconnect to MongoDB (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`
604
770
  );
605
771
  try {
606
- await import_mongoose10.default.connect(this.uri, this.connectionConfig);
772
+ await import_mongoose12.default.connect(this.uri, this.connectionConfig);
607
773
  this.connected = true;
608
774
  this.reconnectAttempts = 0;
609
775
  this.reconnecting = false;
@@ -622,7 +788,7 @@ var MongoDBMemory = class _MongoDBMemory {
622
788
  }
623
789
  }
624
790
  this.reconnecting = false;
625
- if (!this.isConnected) {
791
+ if (!this.connected) {
626
792
  import_logger2.loggers.agent.error(
627
793
  `Failed to reconnect to MongoDB after ${this.maxReconnectAttempts} attempts`
628
794
  );
@@ -633,20 +799,26 @@ var MongoDBMemory = class _MongoDBMemory {
633
799
  return;
634
800
  }
635
801
  try {
636
- await import_mongoose10.default.connect(this.uri, this.connectionConfig);
802
+ await import_mongoose12.default.connect(this.uri, this.connectionConfig);
637
803
  this.connected = true;
638
804
  this.reconnectAttempts = 0;
805
+ await this.setupTTLIndex();
806
+ this.startOrphanCleanup();
639
807
  } catch (error) {
640
808
  import_logger2.loggers.agent.error("Failed to connect to MongoDB:", error);
641
809
  throw error;
642
810
  }
643
811
  }
644
812
  async disconnect() {
645
- if (!this.isConnected) {
813
+ if (!this.connected) {
646
814
  return;
647
815
  }
648
816
  try {
649
- await import_mongoose10.default.disconnect();
817
+ if (this.orphanCleanupTimer) {
818
+ clearInterval(this.orphanCleanupTimer);
819
+ this.orphanCleanupTimer = void 0;
820
+ }
821
+ await import_mongoose12.default.disconnect();
650
822
  this.connected = false;
651
823
  } catch (error) {
652
824
  import_logger2.loggers.agent.error("Failed to disconnect from MongoDB:", error);
@@ -657,7 +829,7 @@ var MongoDBMemory = class _MongoDBMemory {
657
829
  return this.connected;
658
830
  }
659
831
  async ensureConnection() {
660
- if (!this.isConnected && !this.reconnecting) {
832
+ if (!this.connected && !this.reconnecting) {
661
833
  await this.connect();
662
834
  }
663
835
  const maxWaitTime = 3e4;
@@ -665,10 +837,66 @@ var MongoDBMemory = class _MongoDBMemory {
665
837
  while (this.reconnecting && Date.now() - startTime < maxWaitTime) {
666
838
  await new Promise((resolve) => setTimeout(resolve, 100));
667
839
  }
668
- if (!this.isConnected) {
840
+ if (!this.connected) {
669
841
  throw new Error("MongoDB is not connected and reconnection failed");
670
842
  }
671
843
  }
844
+ async setupTTLIndex() {
845
+ if (this.threadTTLSeconds === void 0) return;
846
+ try {
847
+ const db = import_mongoose12.default.connection.db;
848
+ if (!db) return;
849
+ const collection = db.collection("threads");
850
+ const indexes = await collection.indexes();
851
+ const existingTTL = indexes.find(
852
+ (idx) => idx.key?.updatedAt !== void 0 && idx.expireAfterSeconds !== void 0
853
+ );
854
+ if (existingTTL) {
855
+ if (existingTTL.expireAfterSeconds !== this.threadTTLSeconds) {
856
+ await db.command({
857
+ collMod: "threads",
858
+ index: { keyPattern: { updatedAt: 1 }, expireAfterSeconds: this.threadTTLSeconds }
859
+ });
860
+ import_logger2.loggers.agent.info(`Thread TTL index updated to ${this.threadTTLSeconds} seconds`);
861
+ }
862
+ } else {
863
+ await collection.createIndex(
864
+ { updatedAt: 1 },
865
+ { expireAfterSeconds: this.threadTTLSeconds }
866
+ );
867
+ import_logger2.loggers.agent.info(`Thread TTL index created with ${this.threadTTLSeconds} seconds`);
868
+ }
869
+ } catch (error) {
870
+ import_logger2.loggers.agent.error("Failed to setup TTL index:", error);
871
+ }
872
+ }
873
+ startOrphanCleanup() {
874
+ if (this.threadTTLSeconds === void 0) return;
875
+ if (this.orphanCleanupTimer) return;
876
+ const intervalMs = Math.max(6e4, Math.min(this.threadTTLSeconds * 500, 36e5));
877
+ this.orphanCleanupTimer = setInterval(() => {
878
+ this.cleanupOrphanedMessages().catch((error) => {
879
+ import_logger2.loggers.agent.error("Orphaned message cleanup failed:", error);
880
+ });
881
+ }, intervalMs);
882
+ import_logger2.loggers.agent.info(`Orphaned message cleanup scheduled every ${Math.round(intervalMs / 1e3)}s`);
883
+ }
884
+ async cleanupOrphanedMessages() {
885
+ if (!this.connected) return;
886
+ try {
887
+ const db = import_mongoose12.default.connection.db;
888
+ if (!db) return;
889
+ const existingThreadIds = await db.collection("threads").distinct("threadId");
890
+ const result = await MessageModel.deleteMany({
891
+ threadId: { $nin: existingThreadIds }
892
+ });
893
+ if (result.deletedCount > 0) {
894
+ import_logger2.loggers.agent.info(`Cleaned up ${result.deletedCount} orphaned messages`);
895
+ }
896
+ } catch (error) {
897
+ import_logger2.loggers.agent.error("Failed to cleanup orphaned messages:", error);
898
+ }
899
+ }
672
900
  /**
673
901
  * Get the operation timeout in milliseconds
674
902
  */
@@ -688,6 +916,25 @@ var MongoDBMemory = class _MongoDBMemory {
688
916
  import_logger2.loggers.agent.error(`${operationName} exceeded time limit`);
689
917
  throw error;
690
918
  }
919
+ if (error.code === 261 || error.codeName === "TooManyLogicalSessions") {
920
+ import_logger2.loggers.agent.warn(
921
+ `${operationName} failed due to too many sessions, disconnecting to release sessions...`
922
+ );
923
+ try {
924
+ await import_mongoose12.default.disconnect();
925
+ this.connected = false;
926
+ } catch (disconnectError) {
927
+ import_logger2.loggers.agent.error("Failed to disconnect during session cleanup:", disconnectError);
928
+ }
929
+ await new Promise((resolve) => setTimeout(resolve, 5e3));
930
+ await this.ensureConnection();
931
+ try {
932
+ return await operation();
933
+ } catch (retryError) {
934
+ import_logger2.loggers.agent.error(`${operationName} failed after session cleanup retry:`, retryError);
935
+ throw retryError;
936
+ }
937
+ }
691
938
  if (error.name === "MongoNetworkError" || error.name === "MongoServerError" || error.message?.includes("connection") || error.message?.includes("disconnect")) {
692
939
  import_logger2.loggers.agent.warn(
693
940
  `${operationName} failed due to connection issue, attempting reconnection...`