@librechat/data-schemas 0.0.10 → 0.0.12

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/index.cjs CHANGED
@@ -427,10 +427,23 @@ const conversationPreset = {
427
427
  max_tokens: {
428
428
  type: Number,
429
429
  },
430
- /** omni models only */
430
+ useResponsesApi: {
431
+ type: Boolean,
432
+ },
433
+ /** OpenAI Responses API / Anthropic API / Google API */
434
+ web_search: {
435
+ type: Boolean,
436
+ },
437
+ disableStreaming: {
438
+ type: Boolean,
439
+ },
440
+ /** Reasoning models only */
431
441
  reasoning_effort: {
432
442
  type: String,
433
443
  },
444
+ reasoning_summary: {
445
+ type: String,
446
+ },
434
447
  };
435
448
 
436
449
  const convoSchema = new mongoose.Schema({
@@ -883,7 +896,9 @@ const promptGroupSchema = new mongoose.Schema({
883
896
  });
884
897
  promptGroupSchema.index({ createdAt: 1, updatedAt: 1 });
885
898
 
886
- // Create a sub-schema for permissions. Notice we disable _id for this subdocument.
899
+ /**
900
+ * Uses a sub-schema for permissions. Notice we disable `_id` for this subdocument.
901
+ */
887
902
  const rolePermissionsSchema = new mongoose.Schema({
888
903
  [librechatDataProvider.PermissionTypes.BOOKMARKS]: {
889
904
  [librechatDataProvider.Permissions.USE]: { type: Boolean, default: true },
@@ -917,6 +932,9 @@ const rolePermissionsSchema = new mongoose.Schema({
917
932
  [librechatDataProvider.PermissionTypes.WEB_SEARCH]: {
918
933
  [librechatDataProvider.Permissions.USE]: { type: Boolean, default: true },
919
934
  },
935
+ [librechatDataProvider.PermissionTypes.FILE_SEARCH]: {
936
+ [librechatDataProvider.Permissions.USE]: { type: Boolean, default: true },
937
+ },
920
938
  }, { _id: false });
921
939
  const roleSchema = new mongoose.Schema({
922
940
  name: { type: String, required: true, unique: true, index: true },
@@ -944,6 +962,7 @@ const roleSchema = new mongoose.Schema({
944
962
  [librechatDataProvider.PermissionTypes.TEMPORARY_CHAT]: { [librechatDataProvider.Permissions.USE]: true },
945
963
  [librechatDataProvider.PermissionTypes.RUN_CODE]: { [librechatDataProvider.Permissions.USE]: true },
946
964
  [librechatDataProvider.PermissionTypes.WEB_SEARCH]: { [librechatDataProvider.Permissions.USE]: true },
965
+ [librechatDataProvider.PermissionTypes.FILE_SEARCH]: { [librechatDataProvider.Permissions.USE]: true },
947
966
  }),
948
967
  },
949
968
  });
@@ -1338,6 +1357,13 @@ const searchEnabled = process.env.SEARCH != null && process.env.SEARCH.toLowerCa
1338
1357
  * Flag to indicate if MeiliSearch is enabled based on required environment variables.
1339
1358
  */
1340
1359
  const meiliEnabled = process.env.MEILI_HOST != null && process.env.MEILI_MASTER_KEY != null && searchEnabled;
1360
+ /**
1361
+ * Get sync configuration from environment variables
1362
+ */
1363
+ const getSyncConfig = () => ({
1364
+ batchSize: parseInt(process.env.MEILI_SYNC_BATCH_SIZE || '100', 10),
1365
+ delayMs: parseInt(process.env.MEILI_SYNC_DELAY_MS || '100', 10),
1366
+ });
1341
1367
  /**
1342
1368
  * Local implementation of parseTextParts to avoid dependency on librechat-data-provider
1343
1369
  * Extracts text content from an array of content items
@@ -1369,6 +1395,19 @@ const validateOptions = (options) => {
1369
1395
  }
1370
1396
  });
1371
1397
  };
1398
+ /**
1399
+ * Helper function to process documents in batches with rate limiting
1400
+ */
1401
+ const processBatch = async (items, batchSize, delayMs, processor) => {
1402
+ for (let i = 0; i < items.length; i += batchSize) {
1403
+ const batch = items.slice(i, i + batchSize);
1404
+ await processor(batch);
1405
+ // Add delay between batches to prevent overwhelming resources
1406
+ if (i + batchSize < items.length && delayMs > 0) {
1407
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
1408
+ }
1409
+ }
1410
+ };
1372
1411
  /**
1373
1412
  * Factory function to create a MeiliMongooseModel class which extends a Mongoose model.
1374
1413
  * This class contains static and instance methods to synchronize and manage the MeiliSearch index
@@ -1377,97 +1416,148 @@ const validateOptions = (options) => {
1377
1416
  * @param config - Configuration object.
1378
1417
  * @param config.index - The MeiliSearch index object.
1379
1418
  * @param config.attributesToIndex - List of attributes to index.
1419
+ * @param config.syncOptions - Sync configuration options.
1380
1420
  * @returns A class definition that will be loaded into the Mongoose schema.
1381
1421
  */
1382
- const createMeiliMongooseModel = ({ index, attributesToIndex, }) => {
1422
+ const createMeiliMongooseModel = ({ index, attributesToIndex, syncOptions, }) => {
1383
1423
  const primaryKey = attributesToIndex[0];
1424
+ const syncConfig = { ...getSyncConfig(), ...syncOptions };
1384
1425
  class MeiliMongooseModel {
1426
+ /**
1427
+ * Get the current sync progress
1428
+ */
1429
+ static async getSyncProgress() {
1430
+ const totalDocuments = await this.countDocuments();
1431
+ const indexedDocuments = await this.countDocuments({ _meiliIndex: true });
1432
+ return {
1433
+ totalProcessed: indexedDocuments,
1434
+ totalDocuments,
1435
+ isComplete: indexedDocuments === totalDocuments,
1436
+ };
1437
+ }
1385
1438
  /**
1386
1439
  * Synchronizes the data between the MongoDB collection and the MeiliSearch index.
1387
- *
1388
- * The synchronization process involves:
1389
- * 1. Fetching all documents from the MongoDB collection and MeiliSearch index.
1390
- * 2. Comparing documents from both sources.
1391
- * 3. Deleting documents from MeiliSearch that no longer exist in MongoDB.
1392
- * 4. Adding documents to MeiliSearch that exist in MongoDB but not in the index.
1393
- * 5. Updating documents in MeiliSearch if key fields (such as `text` or `title`) differ.
1394
- * 6. Updating the `_meiliIndex` field in MongoDB to indicate the indexing status.
1395
- *
1396
- * Note: The function processes documents in batches because MeiliSearch's
1397
- * `index.getDocuments` requires an exact limit and `index.addDocuments` does not handle
1398
- * partial failures in a batch.
1399
- *
1400
- * @returns {Promise<void>} Resolves when the synchronization is complete.
1440
+ * Now uses streaming and batching to reduce memory usage.
1401
1441
  */
1402
- static async syncWithMeili() {
1442
+ static async syncWithMeili(options) {
1403
1443
  try {
1404
- let moreDocuments = true;
1405
- const mongoDocuments = await this.find().lean();
1444
+ const startTime = Date.now();
1445
+ const { batchSize, delayMs } = syncConfig;
1446
+ logger$1.info(`[syncWithMeili] Starting sync for ${primaryKey === 'messageId' ? 'messages' : 'conversations'} with batch size ${batchSize}`);
1447
+ // Build query with resume capability
1448
+ const query = {};
1449
+ if (options === null || options === void 0 ? void 0 : options.resumeFromId) {
1450
+ query._id = { $gt: options.resumeFromId };
1451
+ }
1452
+ // Get total count for progress tracking
1453
+ const totalCount = await this.countDocuments(query);
1454
+ let processedCount = 0;
1455
+ // First, handle documents that need to be removed from Meili
1456
+ await this.cleanupMeiliIndex(index, primaryKey, batchSize, delayMs);
1457
+ // Process MongoDB documents in batches using cursor
1458
+ const cursor = this.find(query)
1459
+ .select(attributesToIndex.join(' ') + ' _meiliIndex')
1460
+ .sort({ _id: 1 })
1461
+ .batchSize(batchSize)
1462
+ .cursor();
1406
1463
  const format = (doc) => _.omitBy(_.pick(doc, attributesToIndex), (v, k) => k.startsWith('$'));
1407
- const mongoMap = new Map(mongoDocuments.map((doc) => {
1408
- const typedDoc = doc;
1409
- return [typedDoc[primaryKey], format(typedDoc)];
1410
- }));
1411
- const indexMap = new Map();
1464
+ let documentBatch = [];
1465
+ let updateOps = [];
1466
+ // Process documents in streaming fashion
1467
+ for await (const doc of cursor) {
1468
+ const typedDoc = doc.toObject();
1469
+ const formatted = format(typedDoc);
1470
+ // Check if document needs indexing
1471
+ if (!typedDoc._meiliIndex) {
1472
+ documentBatch.push(formatted);
1473
+ updateOps.push({
1474
+ updateOne: {
1475
+ filter: { _id: typedDoc._id },
1476
+ update: { $set: { _meiliIndex: true } },
1477
+ },
1478
+ });
1479
+ }
1480
+ processedCount++;
1481
+ // Process batch when it reaches the configured size
1482
+ if (documentBatch.length >= batchSize) {
1483
+ await this.processSyncBatch(index, documentBatch, updateOps);
1484
+ documentBatch = [];
1485
+ updateOps = [];
1486
+ // Log progress
1487
+ const progress = Math.round((processedCount / totalCount) * 100);
1488
+ logger$1.info(`[syncWithMeili] Progress: ${progress}% (${processedCount}/${totalCount})`);
1489
+ // Add delay to prevent overwhelming resources
1490
+ if (delayMs > 0) {
1491
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
1492
+ }
1493
+ }
1494
+ }
1495
+ // Process remaining documents
1496
+ if (documentBatch.length > 0) {
1497
+ await this.processSyncBatch(index, documentBatch, updateOps);
1498
+ }
1499
+ const duration = Date.now() - startTime;
1500
+ logger$1.info(`[syncWithMeili] Completed sync for ${primaryKey === 'messageId' ? 'messages' : 'conversations'} in ${duration}ms`);
1501
+ }
1502
+ catch (error) {
1503
+ logger$1.error('[syncWithMeili] Error during sync:', error);
1504
+ throw error;
1505
+ }
1506
+ }
1507
+ /**
1508
+ * Process a batch of documents for syncing
1509
+ */
1510
+ static async processSyncBatch(index, documents, updateOps) {
1511
+ if (documents.length === 0) {
1512
+ return;
1513
+ }
1514
+ try {
1515
+ // Add documents to MeiliSearch
1516
+ await index.addDocuments(documents);
1517
+ // Update MongoDB to mark documents as indexed
1518
+ if (updateOps.length > 0) {
1519
+ await this.collection.bulkWrite(updateOps);
1520
+ }
1521
+ }
1522
+ catch (error) {
1523
+ logger$1.error('[processSyncBatch] Error processing batch:', error);
1524
+ // Don't throw - allow sync to continue with other documents
1525
+ }
1526
+ }
1527
+ /**
1528
+ * Clean up documents in MeiliSearch that no longer exist in MongoDB
1529
+ */
1530
+ static async cleanupMeiliIndex(index, primaryKey, batchSize, delayMs) {
1531
+ try {
1412
1532
  let offset = 0;
1413
- const batchSize = 1000;
1533
+ let moreDocuments = true;
1414
1534
  while (moreDocuments) {
1415
1535
  const batch = await index.getDocuments({ limit: batchSize, offset });
1416
1536
  if (batch.results.length === 0) {
1417
1537
  moreDocuments = false;
1538
+ break;
1418
1539
  }
1419
- for (const doc of batch.results) {
1420
- indexMap.set(doc[primaryKey], format(doc));
1540
+ const meiliIds = batch.results.map((doc) => doc[primaryKey]);
1541
+ const query = {};
1542
+ query[primaryKey] = { $in: meiliIds };
1543
+ // Find which documents exist in MongoDB
1544
+ const existingDocs = await this.find(query).select(primaryKey).lean();
1545
+ const existingIds = new Set(existingDocs.map((doc) => doc[primaryKey]));
1546
+ // Delete documents that don't exist in MongoDB
1547
+ const toDelete = meiliIds.filter((id) => !existingIds.has(id));
1548
+ if (toDelete.length > 0) {
1549
+ await Promise.all(toDelete.map((id) => index.deleteDocument(id)));
1550
+ logger$1.debug(`[cleanupMeiliIndex] Deleted ${toDelete.length} orphaned documents`);
1421
1551
  }
1422
1552
  offset += batchSize;
1423
- }
1424
- logger$1.debug('[syncWithMeili]', { indexMap: indexMap.size, mongoMap: mongoMap.size });
1425
- const updateOps = [];
1426
- // Process documents present in the MeiliSearch index
1427
- for (const [id, doc] of indexMap) {
1428
- const update = {};
1429
- update[primaryKey] = id;
1430
- if (mongoMap.has(id)) {
1431
- const mongoDoc = mongoMap.get(id);
1432
- if ((doc.text && doc.text !== (mongoDoc === null || mongoDoc === void 0 ? void 0 : mongoDoc.text)) ||
1433
- (doc.title && doc.title !== (mongoDoc === null || mongoDoc === void 0 ? void 0 : mongoDoc.title))) {
1434
- logger$1.debug(`[syncWithMeili] ${id} had document discrepancy in ${doc.text ? 'text' : 'title'} field`);
1435
- updateOps.push({
1436
- updateOne: { filter: update, update: { $set: { _meiliIndex: true } } },
1437
- });
1438
- await index.addDocuments([doc]);
1439
- }
1440
- }
1441
- else {
1442
- await index.deleteDocument(id);
1443
- updateOps.push({
1444
- updateOne: { filter: update, update: { $set: { _meiliIndex: false } } },
1445
- });
1446
- }
1447
- }
1448
- // Process documents present in MongoDB
1449
- for (const [id, doc] of mongoMap) {
1450
- const update = {};
1451
- update[primaryKey] = id;
1452
- if (!indexMap.has(id)) {
1453
- await index.addDocuments([doc]);
1454
- updateOps.push({
1455
- updateOne: { filter: update, update: { $set: { _meiliIndex: true } } },
1456
- });
1457
- }
1458
- else if (doc._meiliIndex === false) {
1459
- updateOps.push({
1460
- updateOne: { filter: update, update: { $set: { _meiliIndex: true } } },
1461
- });
1553
+ // Add delay between batches
1554
+ if (delayMs > 0) {
1555
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
1462
1556
  }
1463
1557
  }
1464
- if (updateOps.length > 0) {
1465
- await this.collection.bulkWrite(updateOps);
1466
- logger$1.debug(`[syncWithMeili] Finished indexing ${primaryKey === 'messageId' ? 'messages' : 'conversations'}`);
1467
- }
1468
1558
  }
1469
1559
  catch (error) {
1470
- logger$1.error('[syncWithMeili] Error adding document to Meili:', error);
1560
+ logger$1.error('[cleanupMeiliIndex] Error during cleanup:', error);
1471
1561
  }
1472
1562
  }
1473
1563
  /**
@@ -1523,16 +1613,26 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, }) => {
1523
1613
  return object;
1524
1614
  }
1525
1615
  /**
1526
- * Adds the current document to the MeiliSearch index
1616
+ * Adds the current document to the MeiliSearch index with retry logic
1527
1617
  */
1528
1618
  async addObjectToMeili(next) {
1529
1619
  const object = this.preprocessObjectForIndex();
1530
- try {
1531
- await index.addDocuments([object]);
1532
- }
1533
- catch (error) {
1534
- logger$1.error('[addObjectToMeili] Error adding document to Meili:', error);
1535
- return next();
1620
+ const maxRetries = 3;
1621
+ let retryCount = 0;
1622
+ while (retryCount < maxRetries) {
1623
+ try {
1624
+ await index.addDocuments([object]);
1625
+ break;
1626
+ }
1627
+ catch (error) {
1628
+ retryCount++;
1629
+ if (retryCount >= maxRetries) {
1630
+ logger$1.error('[addObjectToMeili] Error adding document to Meili after retries:', error);
1631
+ return next();
1632
+ }
1633
+ // Exponential backoff
1634
+ await new Promise((resolve) => setTimeout(resolve, Math.pow(2, retryCount) * 1000));
1635
+ }
1536
1636
  }
1537
1637
  try {
1538
1638
  await this.collection.updateMany({ _id: this._id }, { $set: { _meiliIndex: true } });
@@ -1633,6 +1733,8 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, }) => {
1633
1733
  * @param options.apiKey - The MeiliSearch API key.
1634
1734
  * @param options.indexName - The name of the MeiliSearch index.
1635
1735
  * @param options.primaryKey - The primary key field for indexing.
1736
+ * @param options.syncBatchSize - Batch size for sync operations.
1737
+ * @param options.syncDelayMs - Delay between batches in milliseconds.
1636
1738
  */
1637
1739
  function mongoMeili(schema, options) {
1638
1740
  const mongoose = options.mongoose;
@@ -1647,9 +1749,37 @@ function mongoMeili(schema, options) {
1647
1749
  },
1648
1750
  });
1649
1751
  const { host, apiKey, indexName, primaryKey } = options;
1752
+ const syncOptions = {
1753
+ batchSize: options.syncBatchSize || getSyncConfig().batchSize,
1754
+ delayMs: options.syncDelayMs || getSyncConfig().delayMs,
1755
+ };
1650
1756
  const client = new meilisearch.MeiliSearch({ host, apiKey });
1651
- client.createIndex(indexName, { primaryKey });
1757
+ /** Create index only if it doesn't exist */
1652
1758
  const index = client.index(indexName);
1759
+ // Check if index exists and create if needed
1760
+ (async () => {
1761
+ try {
1762
+ await index.getRawInfo();
1763
+ logger$1.debug(`[mongoMeili] Index ${indexName} already exists`);
1764
+ }
1765
+ catch (error) {
1766
+ const errorCode = error === null || error === void 0 ? void 0 : error.code;
1767
+ if (errorCode === 'index_not_found') {
1768
+ try {
1769
+ logger$1.info(`[mongoMeili] Creating new index: ${indexName}`);
1770
+ await client.createIndex(indexName, { primaryKey });
1771
+ logger$1.info(`[mongoMeili] Successfully created index: ${indexName}`);
1772
+ }
1773
+ catch (createError) {
1774
+ // Index might have been created by another instance
1775
+ logger$1.debug(`[mongoMeili] Index ${indexName} may already exist:`, createError);
1776
+ }
1777
+ }
1778
+ else {
1779
+ logger$1.error(`[mongoMeili] Error checking index ${indexName}:`, error);
1780
+ }
1781
+ }
1782
+ })();
1653
1783
  // Collect attributes from the schema that should be indexed
1654
1784
  const attributesToIndex = [
1655
1785
  ...Object.entries(schema.obj).reduce((results, [key, value]) => {
@@ -1657,7 +1787,7 @@ function mongoMeili(schema, options) {
1657
1787
  return schemaValue.meiliIndex ? [...results, key] : results;
1658
1788
  }, []),
1659
1789
  ];
1660
- schema.loadClass(createMeiliMongooseModel({ index, attributesToIndex }));
1790
+ schema.loadClass(createMeiliMongooseModel({ index, attributesToIndex, syncOptions }));
1661
1791
  // Register Mongoose hooks
1662
1792
  schema.post('save', function (doc, next) {
1663
1793
  var _a;
@@ -1678,29 +1808,38 @@ function mongoMeili(schema, options) {
1678
1808
  }
1679
1809
  try {
1680
1810
  const conditions = this.getQuery();
1811
+ const { batchSize, delayMs } = syncOptions;
1681
1812
  if (Object.prototype.hasOwnProperty.call(schema.obj, 'messages')) {
1682
1813
  const convoIndex = client.index('convos');
1683
1814
  const deletedConvos = await mongoose
1684
1815
  .model('Conversation')
1685
1816
  .find(conditions)
1817
+ .select('conversationId')
1686
1818
  .lean();
1687
- const promises = deletedConvos.map((convo) => convoIndex.deleteDocument(convo.conversationId));
1688
- await Promise.all(promises);
1819
+ // Process deletions in batches
1820
+ await processBatch(deletedConvos, batchSize, delayMs, async (batch) => {
1821
+ const promises = batch.map((convo) => convoIndex.deleteDocument(convo.conversationId));
1822
+ await Promise.all(promises);
1823
+ });
1689
1824
  }
1690
1825
  if (Object.prototype.hasOwnProperty.call(schema.obj, 'messageId')) {
1691
1826
  const messageIndex = client.index('messages');
1692
1827
  const deletedMessages = await mongoose
1693
1828
  .model('Message')
1694
1829
  .find(conditions)
1830
+ .select('messageId')
1695
1831
  .lean();
1696
- const promises = deletedMessages.map((message) => messageIndex.deleteDocument(message.messageId));
1697
- await Promise.all(promises);
1832
+ // Process deletions in batches
1833
+ await processBatch(deletedMessages, batchSize, delayMs, async (batch) => {
1834
+ const promises = batch.map((message) => messageIndex.deleteDocument(message.messageId));
1835
+ await Promise.all(promises);
1836
+ });
1698
1837
  }
1699
1838
  return next();
1700
1839
  }
1701
1840
  catch (error) {
1702
1841
  if (meiliEnabled) {
1703
- logger$1.error('[MeiliMongooseModel.deleteMany] There was an issue deleting conversation indexes upon deletion. Next startup may be slow due to syncing.', error);
1842
+ logger$1.error('[MeiliMongooseModel.deleteMany] There was an issue deleting conversation indexes upon deletion. Next startup may trigger syncing.', error);
1704
1843
  }
1705
1844
  return next();
1706
1845
  }
@@ -2374,12 +2513,9 @@ class SessionError extends Error {
2374
2513
  }
2375
2514
  }
2376
2515
  const { REFRESH_TOKEN_EXPIRY } = (_a = process.env) !== null && _a !== void 0 ? _a : {};
2377
- const expires = REFRESH_TOKEN_EXPIRY
2378
- ? eval(REFRESH_TOKEN_EXPIRY)
2379
- : 1000 * 60 * 60 * 24 * 7; // 7 days default
2516
+ const expires = REFRESH_TOKEN_EXPIRY ? eval(REFRESH_TOKEN_EXPIRY) : 1000 * 60 * 60 * 24 * 7; // 7 days default
2380
2517
  // Factory function that takes mongoose instance and returns the methods
2381
2518
  function createSessionMethods(mongoose) {
2382
- const Session = mongoose.models.Session;
2383
2519
  /**
2384
2520
  * Creates a new session for a user
2385
2521
  */
@@ -2388,12 +2524,13 @@ function createSessionMethods(mongoose) {
2388
2524
  throw new SessionError('User ID is required', 'INVALID_USER_ID');
2389
2525
  }
2390
2526
  try {
2391
- const session = new Session({
2527
+ const Session = mongoose.models.Session;
2528
+ const currentSession = new Session({
2392
2529
  user: userId,
2393
2530
  expiration: options.expiration || new Date(Date.now() + expires),
2394
2531
  });
2395
- const refreshToken = await generateRefreshToken(session);
2396
- return { session, refreshToken };
2532
+ const refreshToken = await generateRefreshToken(currentSession);
2533
+ return { session: currentSession, refreshToken };
2397
2534
  }
2398
2535
  catch (error) {
2399
2536
  logger.error('[createSession] Error creating session:', error);
@@ -2405,6 +2542,7 @@ function createSessionMethods(mongoose) {
2405
2542
  */
2406
2543
  async function findSession(params, options = { lean: true }) {
2407
2544
  try {
2545
+ const Session = mongoose.models.Session;
2408
2546
  const query = {};
2409
2547
  if (!params.refreshToken && !params.userId && !params.sessionId) {
2410
2548
  throw new SessionError('At least one search parameter is required', 'INVALID_SEARCH_PARAMS');
@@ -2445,6 +2583,7 @@ function createSessionMethods(mongoose) {
2445
2583
  */
2446
2584
  async function updateExpiration(session, newExpiration) {
2447
2585
  try {
2586
+ const Session = mongoose.models.Session;
2448
2587
  const sessionDoc = typeof session === 'string' ? await Session.findById(session) : session;
2449
2588
  if (!sessionDoc) {
2450
2589
  throw new SessionError('Session not found', 'SESSION_NOT_FOUND');
@@ -2462,6 +2601,7 @@ function createSessionMethods(mongoose) {
2462
2601
  */
2463
2602
  async function deleteSession(params) {
2464
2603
  try {
2604
+ const Session = mongoose.models.Session;
2465
2605
  if (!params.refreshToken && !params.sessionId) {
2466
2606
  throw new SessionError('Either refreshToken or sessionId is required', 'INVALID_DELETE_PARAMS');
2467
2607
  }
@@ -2488,6 +2628,7 @@ function createSessionMethods(mongoose) {
2488
2628
  */
2489
2629
  async function deleteAllUserSessions(userId, options = {}) {
2490
2630
  try {
2631
+ const Session = mongoose.models.Session;
2491
2632
  if (!userId) {
2492
2633
  throw new SessionError('User ID is required', 'INVALID_USER_ID');
2493
2634
  }
@@ -2544,6 +2685,7 @@ function createSessionMethods(mongoose) {
2544
2685
  */
2545
2686
  async function countActiveSessions(userId) {
2546
2687
  try {
2688
+ const Session = mongoose.models.Session;
2547
2689
  if (!userId) {
2548
2690
  throw new SessionError('User ID is required', 'INVALID_USER_ID');
2549
2691
  }
@@ -2714,7 +2856,6 @@ const formatDate = (date) => {
2714
2856
  };
2715
2857
  // Factory function that takes mongoose instance and returns the methods
2716
2858
  function createMemoryMethods(mongoose) {
2717
- const MemoryEntry = mongoose.models.MemoryEntry;
2718
2859
  /**
2719
2860
  * Creates a new memory entry for a user
2720
2861
  * Throws an error if a memory with the same key already exists
@@ -2724,6 +2865,7 @@ function createMemoryMethods(mongoose) {
2724
2865
  if ((key === null || key === void 0 ? void 0 : key.toLowerCase()) === 'nothing') {
2725
2866
  return { ok: false };
2726
2867
  }
2868
+ const MemoryEntry = mongoose.models.MemoryEntry;
2727
2869
  const existingMemory = await MemoryEntry.findOne({ userId, key });
2728
2870
  if (existingMemory) {
2729
2871
  throw new Error('Memory with this key already exists');
@@ -2749,6 +2891,7 @@ function createMemoryMethods(mongoose) {
2749
2891
  if ((key === null || key === void 0 ? void 0 : key.toLowerCase()) === 'nothing') {
2750
2892
  return { ok: false };
2751
2893
  }
2894
+ const MemoryEntry = mongoose.models.MemoryEntry;
2752
2895
  await MemoryEntry.findOneAndUpdate({ userId, key }, {
2753
2896
  value,
2754
2897
  tokenCount,
@@ -2768,6 +2911,7 @@ function createMemoryMethods(mongoose) {
2768
2911
  */
2769
2912
  async function deleteMemory({ userId, key }) {
2770
2913
  try {
2914
+ const MemoryEntry = mongoose.models.MemoryEntry;
2771
2915
  const result = await MemoryEntry.findOneAndDelete({ userId, key });
2772
2916
  return { ok: !!result };
2773
2917
  }
@@ -2780,6 +2924,7 @@ function createMemoryMethods(mongoose) {
2780
2924
  */
2781
2925
  async function getAllUserMemories(userId) {
2782
2926
  try {
2927
+ const MemoryEntry = mongoose.models.MemoryEntry;
2783
2928
  return (await MemoryEntry.find({ userId }).lean());
2784
2929
  }
2785
2930
  catch (error) {
@@ -3190,12 +3335,12 @@ function createShareMethods(mongoose) {
3190
3335
 
3191
3336
  // Factory function that takes mongoose instance and returns the methods
3192
3337
  function createPluginAuthMethods(mongoose) {
3193
- const PluginAuth = mongoose.models.PluginAuth;
3194
3338
  /**
3195
3339
  * Finds a single plugin auth entry by userId and authField
3196
3340
  */
3197
3341
  async function findOnePluginAuth({ userId, authField, }) {
3198
3342
  try {
3343
+ const PluginAuth = mongoose.models.PluginAuth;
3199
3344
  return await PluginAuth.findOne({ userId, authField }).lean();
3200
3345
  }
3201
3346
  catch (error) {
@@ -3210,6 +3355,7 @@ function createPluginAuthMethods(mongoose) {
3210
3355
  if (!pluginKeys || pluginKeys.length === 0) {
3211
3356
  return [];
3212
3357
  }
3358
+ const PluginAuth = mongoose.models.PluginAuth;
3213
3359
  return await PluginAuth.find({
3214
3360
  userId,
3215
3361
  pluginKey: { $in: pluginKeys },
@@ -3224,6 +3370,7 @@ function createPluginAuthMethods(mongoose) {
3224
3370
  */
3225
3371
  async function updatePluginAuth({ userId, authField, pluginKey, value, }) {
3226
3372
  try {
3373
+ const PluginAuth = mongoose.models.PluginAuth;
3227
3374
  const existingAuth = await PluginAuth.findOne({ userId, pluginKey, authField }).lean();
3228
3375
  if (existingAuth) {
3229
3376
  return await PluginAuth.findOneAndUpdate({ userId, pluginKey, authField }, { $set: { value } }, { new: true, upsert: true }).lean();
@@ -3248,6 +3395,7 @@ function createPluginAuthMethods(mongoose) {
3248
3395
  */
3249
3396
  async function deletePluginAuth({ userId, authField, pluginKey, all = false, }) {
3250
3397
  try {
3398
+ const PluginAuth = mongoose.models.PluginAuth;
3251
3399
  if (all) {
3252
3400
  const filter = { userId };
3253
3401
  if (pluginKey) {
@@ -3269,6 +3417,7 @@ function createPluginAuthMethods(mongoose) {
3269
3417
  */
3270
3418
  async function deleteAllUserPluginAuths(userId) {
3271
3419
  try {
3420
+ const PluginAuth = mongoose.models.PluginAuth;
3272
3421
  return await PluginAuth.deleteMany({ userId });
3273
3422
  }
3274
3423
  catch (error) {