@librechat/data-schemas 0.0.10 → 0.0.11

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