@librechat/data-schemas 0.0.8 → 0.0.10

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
@@ -9,6 +9,7 @@ import winston from 'winston';
9
9
  import 'winston-daily-rotate-file';
10
10
  import { klona } from 'klona';
11
11
  import traverse from 'traverse';
12
+ import { nanoid } from 'nanoid';
12
13
 
13
14
  async function signPayload({ payload, secret, expirationTime, }) {
14
15
  return jwt.sign(payload, secret, { expiresIn: expirationTime });
@@ -868,7 +869,7 @@ const promptGroupSchema = new Schema({
868
869
  validator: function (v) {
869
870
  return v === undefined || v === null || v === '' || /^[a-z0-9-]+$/.test(v);
870
871
  },
871
- message: (props) => `${props.value} is not a valid command. Only lowercase alphanumeric characters and hyphens are allowed.`,
872
+ message: (props) => { var _a; return `${(_a = props === null || props === void 0 ? void 0 : props.value) !== null && _a !== void 0 ? _a : 'Value'} is not a valid command. Only lowercase alphanumeric characters and hyphens are allowed.`; },
872
873
  },
873
874
  maxlength: [
874
875
  Constants.COMMANDS_MAX_LENGTH,
@@ -890,6 +891,13 @@ const rolePermissionsSchema = new Schema({
890
891
  [Permissions.USE]: { type: Boolean, default: true },
891
892
  [Permissions.CREATE]: { type: Boolean, default: true },
892
893
  },
894
+ [PermissionTypes.MEMORIES]: {
895
+ [Permissions.USE]: { type: Boolean, default: true },
896
+ [Permissions.CREATE]: { type: Boolean, default: true },
897
+ [Permissions.UPDATE]: { type: Boolean, default: true },
898
+ [Permissions.READ]: { type: Boolean, default: true },
899
+ [Permissions.OPT_OUT]: { type: Boolean, default: true },
900
+ },
893
901
  [PermissionTypes.AGENTS]: {
894
902
  [Permissions.SHARED_GLOBAL]: { type: Boolean, default: false },
895
903
  [Permissions.USE]: { type: Boolean, default: true },
@@ -919,6 +927,12 @@ const roleSchema = new Schema({
919
927
  [Permissions.USE]: true,
920
928
  [Permissions.CREATE]: true,
921
929
  },
930
+ [PermissionTypes.MEMORIES]: {
931
+ [Permissions.USE]: true,
932
+ [Permissions.CREATE]: true,
933
+ [Permissions.UPDATE]: true,
934
+ [Permissions.READ]: true,
935
+ },
922
936
  [PermissionTypes.AGENTS]: {
923
937
  [Permissions.SHARED_GLOBAL]: false,
924
938
  [Permissions.USE]: true,
@@ -1196,8 +1210,46 @@ const userSchema = new Schema({
1196
1210
  type: Boolean,
1197
1211
  default: false,
1198
1212
  },
1213
+ personalization: {
1214
+ type: {
1215
+ memories: {
1216
+ type: Boolean,
1217
+ default: true,
1218
+ },
1219
+ },
1220
+ default: {},
1221
+ },
1199
1222
  }, { timestamps: true });
1200
1223
 
1224
+ const MemoryEntrySchema = new Schema({
1225
+ userId: {
1226
+ type: Schema.Types.ObjectId,
1227
+ ref: 'User',
1228
+ index: true,
1229
+ required: true,
1230
+ },
1231
+ key: {
1232
+ type: String,
1233
+ required: true,
1234
+ validate: {
1235
+ validator: (v) => /^[a-z_]+$/.test(v),
1236
+ message: 'Key must only contain lowercase letters and underscores',
1237
+ },
1238
+ },
1239
+ value: {
1240
+ type: String,
1241
+ required: true,
1242
+ },
1243
+ tokenCount: {
1244
+ type: Number,
1245
+ default: 0,
1246
+ },
1247
+ updated_at: {
1248
+ type: Date,
1249
+ default: Date.now,
1250
+ },
1251
+ });
1252
+
1201
1253
  /**
1202
1254
  * Creates or returns the User model using the provided mongoose instance and schema
1203
1255
  */
@@ -1226,7 +1278,7 @@ function createBalanceModel(mongoose) {
1226
1278
  return mongoose.models.Balance || mongoose.model('Balance', balanceSchema);
1227
1279
  }
1228
1280
 
1229
- const logDir$1 = path.join(__dirname, '..', 'logs');
1281
+ const logDir$1 = path.join(__dirname, '..', '..', '..', 'api', 'logs');
1230
1282
  const { NODE_ENV: NODE_ENV$1, DEBUG_LOGGING: DEBUG_LOGGING$1 = 'false' } = process.env;
1231
1283
  const useDebugLogging$1 = (typeof DEBUG_LOGGING$1 === 'string' && DEBUG_LOGGING$1.toLowerCase() === 'true') ||
1232
1284
  DEBUG_LOGGING$1 === 'true';
@@ -1413,7 +1465,7 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, }) => {
1413
1465
  }
1414
1466
  }
1415
1467
  catch (error) {
1416
- logger$1.error('[syncWithMeili] Error adding document to Meili', error);
1468
+ logger$1.error('[syncWithMeili] Error adding document to Meili:', error);
1417
1469
  }
1418
1470
  }
1419
1471
  /**
@@ -1471,30 +1523,52 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, }) => {
1471
1523
  /**
1472
1524
  * Adds the current document to the MeiliSearch index
1473
1525
  */
1474
- async addObjectToMeili() {
1526
+ async addObjectToMeili(next) {
1475
1527
  const object = this.preprocessObjectForIndex();
1476
1528
  try {
1477
1529
  await index.addDocuments([object]);
1478
1530
  }
1479
1531
  catch (error) {
1480
- logger$1.error('[addObjectToMeili] Error adding document to Meili', error);
1532
+ logger$1.error('[addObjectToMeili] Error adding document to Meili:', error);
1533
+ return next();
1481
1534
  }
1482
- await this.collection.updateMany({ _id: this._id }, { $set: { _meiliIndex: true } });
1535
+ try {
1536
+ await this.collection.updateMany({ _id: this._id }, { $set: { _meiliIndex: true } });
1537
+ }
1538
+ catch (error) {
1539
+ logger$1.error('[addObjectToMeili] Error updating _meiliIndex field:', error);
1540
+ return next();
1541
+ }
1542
+ next();
1483
1543
  }
1484
1544
  /**
1485
1545
  * Updates the current document in the MeiliSearch index
1486
1546
  */
1487
- async updateObjectToMeili() {
1488
- const object = _.omitBy(_.pick(this.toJSON(), attributesToIndex), (v, k) => k.startsWith('$'));
1489
- await index.updateDocuments([object]);
1547
+ async updateObjectToMeili(next) {
1548
+ try {
1549
+ const object = _.omitBy(_.pick(this.toJSON(), attributesToIndex), (v, k) => k.startsWith('$'));
1550
+ await index.updateDocuments([object]);
1551
+ next();
1552
+ }
1553
+ catch (error) {
1554
+ logger$1.error('[updateObjectToMeili] Error updating document in Meili:', error);
1555
+ return next();
1556
+ }
1490
1557
  }
1491
1558
  /**
1492
1559
  * Deletes the current document from the MeiliSearch index.
1493
1560
  *
1494
1561
  * @returns {Promise<void>}
1495
1562
  */
1496
- async deleteObjectFromMeili() {
1497
- await index.deleteDocument(this._id);
1563
+ async deleteObjectFromMeili(next) {
1564
+ try {
1565
+ await index.deleteDocument(this._id);
1566
+ next();
1567
+ }
1568
+ catch (error) {
1569
+ logger$1.error('[deleteObjectFromMeili] Error deleting document from Meili:', error);
1570
+ return next();
1571
+ }
1498
1572
  }
1499
1573
  /**
1500
1574
  * Post-save hook to synchronize the document with MeiliSearch.
@@ -1502,12 +1576,12 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, }) => {
1502
1576
  * If the document is already indexed (i.e. `_meiliIndex` is true), it updates it;
1503
1577
  * otherwise, it adds the document to the index.
1504
1578
  */
1505
- postSaveHook() {
1579
+ postSaveHook(next) {
1506
1580
  if (this._meiliIndex) {
1507
- this.updateObjectToMeili();
1581
+ this.updateObjectToMeili(next);
1508
1582
  }
1509
1583
  else {
1510
- this.addObjectToMeili();
1584
+ this.addObjectToMeili(next);
1511
1585
  }
1512
1586
  }
1513
1587
  /**
@@ -1516,9 +1590,12 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, }) => {
1516
1590
  * This hook is triggered after a document update, ensuring that changes are
1517
1591
  * propagated to the MeiliSearch index if the document is indexed.
1518
1592
  */
1519
- postUpdateHook() {
1593
+ postUpdateHook(next) {
1520
1594
  if (this._meiliIndex) {
1521
- this.updateObjectToMeili();
1595
+ this.updateObjectToMeili(next);
1596
+ }
1597
+ else {
1598
+ next();
1522
1599
  }
1523
1600
  }
1524
1601
  /**
@@ -1527,9 +1604,12 @@ const createMeiliMongooseModel = ({ index, attributesToIndex, }) => {
1527
1604
  * This hook is triggered after a document is removed, ensuring that the document
1528
1605
  * is also removed from the MeiliSearch index if it was previously indexed.
1529
1606
  */
1530
- postRemoveHook() {
1607
+ postRemoveHook(next) {
1531
1608
  if (this._meiliIndex) {
1532
- this.deleteObjectFromMeili();
1609
+ this.deleteObjectFromMeili(next);
1610
+ }
1611
+ else {
1612
+ next();
1533
1613
  }
1534
1614
  }
1535
1615
  }
@@ -1577,17 +1657,17 @@ function mongoMeili(schema, options) {
1577
1657
  ];
1578
1658
  schema.loadClass(createMeiliMongooseModel({ index, attributesToIndex }));
1579
1659
  // Register Mongoose hooks
1580
- schema.post('save', function (doc) {
1660
+ schema.post('save', function (doc, next) {
1581
1661
  var _a;
1582
- (_a = doc.postSaveHook) === null || _a === void 0 ? void 0 : _a.call(doc);
1662
+ (_a = doc.postSaveHook) === null || _a === void 0 ? void 0 : _a.call(doc, next);
1583
1663
  });
1584
- schema.post('updateOne', function (doc) {
1664
+ schema.post('updateOne', function (doc, next) {
1585
1665
  var _a;
1586
- (_a = doc.postUpdateHook) === null || _a === void 0 ? void 0 : _a.call(doc);
1666
+ (_a = doc.postUpdateHook) === null || _a === void 0 ? void 0 : _a.call(doc, next);
1587
1667
  });
1588
- schema.post('deleteOne', function (doc) {
1668
+ schema.post('deleteOne', function (doc, next) {
1589
1669
  var _a;
1590
- (_a = doc.postRemoveHook) === null || _a === void 0 ? void 0 : _a.call(doc);
1670
+ (_a = doc.postRemoveHook) === null || _a === void 0 ? void 0 : _a.call(doc, next);
1591
1671
  });
1592
1672
  // Pre-deleteMany hook: remove corresponding documents from MeiliSearch when multiple documents are deleted.
1593
1673
  schema.pre('deleteMany', async function (next) {
@@ -1624,13 +1704,13 @@ function mongoMeili(schema, options) {
1624
1704
  }
1625
1705
  });
1626
1706
  // Post-findOneAndUpdate hook
1627
- schema.post('findOneAndUpdate', async function (doc) {
1707
+ schema.post('findOneAndUpdate', async function (doc, next) {
1628
1708
  var _a;
1629
1709
  if (!meiliEnabled) {
1630
- return;
1710
+ return next();
1631
1711
  }
1632
1712
  if (doc.unfinished) {
1633
- return;
1713
+ return next();
1634
1714
  }
1635
1715
  let meiliDoc;
1636
1716
  if (doc.messages) {
@@ -1643,9 +1723,9 @@ function mongoMeili(schema, options) {
1643
1723
  }
1644
1724
  }
1645
1725
  if (meiliDoc && meiliDoc.title === doc.title) {
1646
- return;
1726
+ return next();
1647
1727
  }
1648
- (_a = doc.postSaveHook) === null || _a === void 0 ? void 0 : _a.call(doc);
1728
+ (_a = doc.postSaveHook) === null || _a === void 0 ? void 0 : _a.call(doc, next);
1649
1729
  });
1650
1730
  }
1651
1731
 
@@ -1796,6 +1876,10 @@ function createToolCallModel(mongoose) {
1796
1876
  return mongoose.models.ToolCall || mongoose.model('ToolCall', toolCallSchema);
1797
1877
  }
1798
1878
 
1879
+ function createMemoryModel(mongoose) {
1880
+ return mongoose.models.MemoryEntry || mongoose.model('MemoryEntry', MemoryEntrySchema);
1881
+ }
1882
+
1799
1883
  /**
1800
1884
  * Creates all database models for all collections
1801
1885
  */
@@ -1823,6 +1907,7 @@ function createModels(mongoose) {
1823
1907
  ConversationTag: createConversationTagModel(mongoose),
1824
1908
  SharedLink: createSharedLinkModel(mongoose),
1825
1909
  ToolCall: createToolCallModel(mongoose),
1910
+ MemoryEntry: createMemoryModel(mongoose),
1826
1911
  };
1827
1912
  }
1828
1913
 
@@ -1958,6 +2043,28 @@ function createUserMethods(mongoose) {
1958
2043
  expirationTime: expires / 1000,
1959
2044
  });
1960
2045
  }
2046
+ /**
2047
+ * Update a user's personalization memories setting.
2048
+ * Handles the edge case where the personalization object doesn't exist.
2049
+ */
2050
+ async function toggleUserMemories(userId, memoriesEnabled) {
2051
+ const User = mongoose.models.User;
2052
+ // First, ensure the personalization object exists
2053
+ const user = await User.findById(userId);
2054
+ if (!user) {
2055
+ return null;
2056
+ }
2057
+ // Use $set to update the nested field, which will create the personalization object if it doesn't exist
2058
+ const updateOperation = {
2059
+ $set: {
2060
+ 'personalization.memories': memoriesEnabled,
2061
+ },
2062
+ };
2063
+ return (await User.findByIdAndUpdate(userId, updateOperation, {
2064
+ new: true,
2065
+ runValidators: true,
2066
+ }).lean());
2067
+ }
1961
2068
  // Return all methods
1962
2069
  return {
1963
2070
  findUser,
@@ -1967,6 +2074,7 @@ function createUserMethods(mongoose) {
1967
2074
  getUserById,
1968
2075
  deleteUserById,
1969
2076
  generateToken,
2077
+ toggleUserMemories,
1970
2078
  };
1971
2079
  }
1972
2080
 
@@ -2171,14 +2279,11 @@ const jsonTruncateFormat = winston.format((info) => {
2171
2279
  return truncateObject(info);
2172
2280
  });
2173
2281
 
2174
- // Define log directory
2175
- const logDir = path.join(__dirname, '..', 'logs');
2176
- // Type-safe environment variables
2282
+ const logDir = path.join(__dirname, '..', '..', '..', 'api', 'logs');
2177
2283
  const { NODE_ENV, DEBUG_LOGGING, CONSOLE_JSON, DEBUG_CONSOLE } = process.env;
2178
2284
  const useConsoleJson = typeof CONSOLE_JSON === 'string' && CONSOLE_JSON.toLowerCase() === 'true';
2179
2285
  const useDebugConsole = typeof DEBUG_CONSOLE === 'string' && DEBUG_CONSOLE.toLowerCase() === 'true';
2180
2286
  const useDebugLogging = typeof DEBUG_LOGGING === 'string' && DEBUG_LOGGING.toLowerCase() === 'true';
2181
- // Define custom log levels
2182
2287
  const levels = {
2183
2288
  error: 0,
2184
2289
  warn: 1,
@@ -2258,7 +2363,7 @@ const logger = winston.createLogger({
2258
2363
  transports,
2259
2364
  });
2260
2365
 
2261
- var _a, _b;
2366
+ var _a;
2262
2367
  class SessionError extends Error {
2263
2368
  constructor(message, code = 'SESSION_ERROR') {
2264
2369
  super(message);
@@ -2267,7 +2372,9 @@ class SessionError extends Error {
2267
2372
  }
2268
2373
  }
2269
2374
  const { REFRESH_TOKEN_EXPIRY } = (_a = process.env) !== null && _a !== void 0 ? _a : {};
2270
- const expires = (_b = eval(REFRESH_TOKEN_EXPIRY !== null && REFRESH_TOKEN_EXPIRY !== void 0 ? REFRESH_TOKEN_EXPIRY : '0')) !== null && _b !== void 0 ? _b : 1000 * 60 * 60 * 24 * 7; // 7 days default
2375
+ const expires = REFRESH_TOKEN_EXPIRY
2376
+ ? eval(REFRESH_TOKEN_EXPIRY)
2377
+ : 1000 * 60 * 60 * 24 * 7; // 7 days default
2271
2378
  // Factory function that takes mongoose instance and returns the methods
2272
2379
  function createSessionMethods(mongoose) {
2273
2380
  const Session = mongoose.models.Session;
@@ -2597,6 +2704,584 @@ function createRoleMethods(mongoose) {
2597
2704
  };
2598
2705
  }
2599
2706
 
2707
+ /**
2708
+ * Formats a date in YYYY-MM-DD format
2709
+ */
2710
+ const formatDate = (date) => {
2711
+ return date.toISOString().split('T')[0];
2712
+ };
2713
+ // Factory function that takes mongoose instance and returns the methods
2714
+ function createMemoryMethods(mongoose) {
2715
+ const MemoryEntry = mongoose.models.MemoryEntry;
2716
+ /**
2717
+ * Creates a new memory entry for a user
2718
+ * Throws an error if a memory with the same key already exists
2719
+ */
2720
+ async function createMemory({ userId, key, value, tokenCount = 0, }) {
2721
+ try {
2722
+ if ((key === null || key === void 0 ? void 0 : key.toLowerCase()) === 'nothing') {
2723
+ return { ok: false };
2724
+ }
2725
+ const existingMemory = await MemoryEntry.findOne({ userId, key });
2726
+ if (existingMemory) {
2727
+ throw new Error('Memory with this key already exists');
2728
+ }
2729
+ await MemoryEntry.create({
2730
+ userId,
2731
+ key,
2732
+ value,
2733
+ tokenCount,
2734
+ updated_at: new Date(),
2735
+ });
2736
+ return { ok: true };
2737
+ }
2738
+ catch (error) {
2739
+ throw new Error(`Failed to create memory: ${error instanceof Error ? error.message : 'Unknown error'}`);
2740
+ }
2741
+ }
2742
+ /**
2743
+ * Sets or updates a memory entry for a user
2744
+ */
2745
+ async function setMemory({ userId, key, value, tokenCount = 0, }) {
2746
+ try {
2747
+ if ((key === null || key === void 0 ? void 0 : key.toLowerCase()) === 'nothing') {
2748
+ return { ok: false };
2749
+ }
2750
+ await MemoryEntry.findOneAndUpdate({ userId, key }, {
2751
+ value,
2752
+ tokenCount,
2753
+ updated_at: new Date(),
2754
+ }, {
2755
+ upsert: true,
2756
+ new: true,
2757
+ });
2758
+ return { ok: true };
2759
+ }
2760
+ catch (error) {
2761
+ throw new Error(`Failed to set memory: ${error instanceof Error ? error.message : 'Unknown error'}`);
2762
+ }
2763
+ }
2764
+ /**
2765
+ * Deletes a specific memory entry for a user
2766
+ */
2767
+ async function deleteMemory({ userId, key }) {
2768
+ try {
2769
+ const result = await MemoryEntry.findOneAndDelete({ userId, key });
2770
+ return { ok: !!result };
2771
+ }
2772
+ catch (error) {
2773
+ throw new Error(`Failed to delete memory: ${error instanceof Error ? error.message : 'Unknown error'}`);
2774
+ }
2775
+ }
2776
+ /**
2777
+ * Gets all memory entries for a user
2778
+ */
2779
+ async function getAllUserMemories(userId) {
2780
+ try {
2781
+ return (await MemoryEntry.find({ userId }).lean());
2782
+ }
2783
+ catch (error) {
2784
+ throw new Error(`Failed to get all memories: ${error instanceof Error ? error.message : 'Unknown error'}`);
2785
+ }
2786
+ }
2787
+ /**
2788
+ * Gets and formats all memories for a user in two different formats
2789
+ */
2790
+ async function getFormattedMemories({ userId, }) {
2791
+ try {
2792
+ const memories = await getAllUserMemories(userId);
2793
+ if (!memories || memories.length === 0) {
2794
+ return { withKeys: '', withoutKeys: '', totalTokens: 0 };
2795
+ }
2796
+ const sortedMemories = memories.sort((a, b) => new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime());
2797
+ const totalTokens = sortedMemories.reduce((sum, memory) => {
2798
+ return sum + (memory.tokenCount || 0);
2799
+ }, 0);
2800
+ const withKeys = sortedMemories
2801
+ .map((memory, index) => {
2802
+ const date = formatDate(new Date(memory.updated_at));
2803
+ const tokenInfo = memory.tokenCount ? ` [${memory.tokenCount} tokens]` : '';
2804
+ return `${index + 1}. [${date}]. ["key": "${memory.key}"]${tokenInfo}. ["value": "${memory.value}"]`;
2805
+ })
2806
+ .join('\n\n');
2807
+ const withoutKeys = sortedMemories
2808
+ .map((memory, index) => {
2809
+ const date = formatDate(new Date(memory.updated_at));
2810
+ return `${index + 1}. [${date}]. ${memory.value}`;
2811
+ })
2812
+ .join('\n\n');
2813
+ return { withKeys, withoutKeys, totalTokens };
2814
+ }
2815
+ catch (error) {
2816
+ logger.error('Failed to get formatted memories:', error);
2817
+ return { withKeys: '', withoutKeys: '', totalTokens: 0 };
2818
+ }
2819
+ }
2820
+ return {
2821
+ setMemory,
2822
+ createMemory,
2823
+ deleteMemory,
2824
+ getAllUserMemories,
2825
+ getFormattedMemories,
2826
+ };
2827
+ }
2828
+
2829
+ class ShareServiceError extends Error {
2830
+ constructor(message, code) {
2831
+ super(message);
2832
+ this.name = 'ShareServiceError';
2833
+ this.code = code;
2834
+ }
2835
+ }
2836
+ function memoizedAnonymizeId(prefix) {
2837
+ const memo = new Map();
2838
+ return (id) => {
2839
+ if (!memo.has(id)) {
2840
+ memo.set(id, `${prefix}_${nanoid()}`);
2841
+ }
2842
+ return memo.get(id);
2843
+ };
2844
+ }
2845
+ const anonymizeConvoId = memoizedAnonymizeId('convo');
2846
+ const anonymizeAssistantId = memoizedAnonymizeId('a');
2847
+ const anonymizeMessageId = (id) => id === Constants.NO_PARENT ? id : memoizedAnonymizeId('msg')(id);
2848
+ function anonymizeConvo(conversation) {
2849
+ if (!conversation) {
2850
+ return null;
2851
+ }
2852
+ const newConvo = { ...conversation };
2853
+ if (newConvo.assistant_id) {
2854
+ newConvo.assistant_id = anonymizeAssistantId(newConvo.assistant_id);
2855
+ }
2856
+ return newConvo;
2857
+ }
2858
+ function anonymizeMessages(messages, newConvoId) {
2859
+ if (!Array.isArray(messages)) {
2860
+ return [];
2861
+ }
2862
+ const idMap = new Map();
2863
+ return messages.map((message) => {
2864
+ var _a, _b;
2865
+ const newMessageId = anonymizeMessageId(message.messageId);
2866
+ idMap.set(message.messageId, newMessageId);
2867
+ const anonymizedAttachments = (_a = message.attachments) === null || _a === void 0 ? void 0 : _a.map((attachment) => {
2868
+ return {
2869
+ ...attachment,
2870
+ messageId: newMessageId,
2871
+ conversationId: newConvoId,
2872
+ };
2873
+ });
2874
+ return {
2875
+ ...message,
2876
+ messageId: newMessageId,
2877
+ parentMessageId: idMap.get(message.parentMessageId || '') ||
2878
+ anonymizeMessageId(message.parentMessageId || ''),
2879
+ conversationId: newConvoId,
2880
+ model: ((_b = message.model) === null || _b === void 0 ? void 0 : _b.startsWith('asst_'))
2881
+ ? anonymizeAssistantId(message.model)
2882
+ : message.model,
2883
+ attachments: anonymizedAttachments,
2884
+ };
2885
+ });
2886
+ }
2887
+ /** Factory function that takes mongoose instance and returns the methods */
2888
+ function createShareMethods(mongoose) {
2889
+ /**
2890
+ * Get shared messages for a public share link
2891
+ */
2892
+ async function getSharedMessages(shareId) {
2893
+ try {
2894
+ const SharedLink = mongoose.models.SharedLink;
2895
+ const share = (await SharedLink.findOne({ shareId, isPublic: true })
2896
+ .populate({
2897
+ path: 'messages',
2898
+ select: '-_id -__v -user',
2899
+ })
2900
+ .select('-_id -__v -user')
2901
+ .lean());
2902
+ if (!(share === null || share === void 0 ? void 0 : share.conversationId) || !share.isPublic) {
2903
+ return null;
2904
+ }
2905
+ const newConvoId = anonymizeConvoId(share.conversationId);
2906
+ const result = {
2907
+ shareId: share.shareId || shareId,
2908
+ title: share.title,
2909
+ isPublic: share.isPublic,
2910
+ createdAt: share.createdAt,
2911
+ updatedAt: share.updatedAt,
2912
+ conversationId: newConvoId,
2913
+ messages: anonymizeMessages(share.messages, newConvoId),
2914
+ };
2915
+ return result;
2916
+ }
2917
+ catch (error) {
2918
+ logger.error('[getSharedMessages] Error getting share link', {
2919
+ error: error instanceof Error ? error.message : 'Unknown error',
2920
+ shareId,
2921
+ });
2922
+ throw new ShareServiceError('Error getting share link', 'SHARE_FETCH_ERROR');
2923
+ }
2924
+ }
2925
+ /**
2926
+ * Get shared links for a specific user with pagination and search
2927
+ */
2928
+ async function getSharedLinks(user, pageParam, pageSize = 10, isPublic = true, sortBy = 'createdAt', sortDirection = 'desc', search) {
2929
+ var _a;
2930
+ try {
2931
+ const SharedLink = mongoose.models.SharedLink;
2932
+ const Conversation = mongoose.models.Conversation;
2933
+ const query = { user, isPublic };
2934
+ if (pageParam) {
2935
+ if (sortDirection === 'desc') {
2936
+ query[sortBy] = { $lt: pageParam };
2937
+ }
2938
+ else {
2939
+ query[sortBy] = { $gt: pageParam };
2940
+ }
2941
+ }
2942
+ if (search && search.trim()) {
2943
+ try {
2944
+ const searchResults = await Conversation.meiliSearch(search);
2945
+ if (!((_a = searchResults === null || searchResults === void 0 ? void 0 : searchResults.hits) === null || _a === void 0 ? void 0 : _a.length)) {
2946
+ return {
2947
+ links: [],
2948
+ nextCursor: undefined,
2949
+ hasNextPage: false,
2950
+ };
2951
+ }
2952
+ const conversationIds = searchResults.hits.map((hit) => hit.conversationId);
2953
+ query['conversationId'] = { $in: conversationIds };
2954
+ }
2955
+ catch (searchError) {
2956
+ logger.error('[getSharedLinks] Meilisearch error', {
2957
+ error: searchError instanceof Error ? searchError.message : 'Unknown error',
2958
+ user,
2959
+ });
2960
+ return {
2961
+ links: [],
2962
+ nextCursor: undefined,
2963
+ hasNextPage: false,
2964
+ };
2965
+ }
2966
+ }
2967
+ const sort = {};
2968
+ sort[sortBy] = sortDirection === 'desc' ? -1 : 1;
2969
+ const sharedLinks = await SharedLink.find(query)
2970
+ .sort(sort)
2971
+ .limit(pageSize + 1)
2972
+ .select('-__v -user')
2973
+ .lean();
2974
+ const hasNextPage = sharedLinks.length > pageSize;
2975
+ const links = sharedLinks.slice(0, pageSize);
2976
+ const nextCursor = hasNextPage
2977
+ ? links[links.length - 1][sortBy]
2978
+ : undefined;
2979
+ return {
2980
+ links: links.map((link) => ({
2981
+ shareId: link.shareId || '',
2982
+ title: (link === null || link === void 0 ? void 0 : link.title) || 'Untitled',
2983
+ isPublic: link.isPublic,
2984
+ createdAt: link.createdAt || new Date(),
2985
+ conversationId: link.conversationId,
2986
+ })),
2987
+ nextCursor,
2988
+ hasNextPage,
2989
+ };
2990
+ }
2991
+ catch (error) {
2992
+ logger.error('[getSharedLinks] Error getting shares', {
2993
+ error: error instanceof Error ? error.message : 'Unknown error',
2994
+ user,
2995
+ });
2996
+ throw new ShareServiceError('Error getting shares', 'SHARES_FETCH_ERROR');
2997
+ }
2998
+ }
2999
+ /**
3000
+ * Delete all shared links for a user
3001
+ */
3002
+ async function deleteAllSharedLinks(user) {
3003
+ try {
3004
+ const SharedLink = mongoose.models.SharedLink;
3005
+ const result = await SharedLink.deleteMany({ user });
3006
+ return {
3007
+ message: 'All shared links deleted successfully',
3008
+ deletedCount: result.deletedCount,
3009
+ };
3010
+ }
3011
+ catch (error) {
3012
+ logger.error('[deleteAllSharedLinks] Error deleting shared links', {
3013
+ error: error instanceof Error ? error.message : 'Unknown error',
3014
+ user,
3015
+ });
3016
+ throw new ShareServiceError('Error deleting shared links', 'BULK_DELETE_ERROR');
3017
+ }
3018
+ }
3019
+ /**
3020
+ * Create a new shared link for a conversation
3021
+ */
3022
+ async function createSharedLink(user, conversationId) {
3023
+ if (!user || !conversationId) {
3024
+ throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
3025
+ }
3026
+ try {
3027
+ const Message = mongoose.models.Message;
3028
+ const SharedLink = mongoose.models.SharedLink;
3029
+ const Conversation = mongoose.models.Conversation;
3030
+ const [existingShare, conversationMessages] = await Promise.all([
3031
+ SharedLink.findOne({ conversationId, user, isPublic: true })
3032
+ .select('-_id -__v -user')
3033
+ .lean(),
3034
+ Message.find({ conversationId, user }).sort({ createdAt: 1 }).lean(),
3035
+ ]);
3036
+ if (existingShare && existingShare.isPublic) {
3037
+ logger.error('[createSharedLink] Share already exists', {
3038
+ user,
3039
+ conversationId,
3040
+ });
3041
+ throw new ShareServiceError('Share already exists', 'SHARE_EXISTS');
3042
+ }
3043
+ else if (existingShare) {
3044
+ await SharedLink.deleteOne({ conversationId, user });
3045
+ }
3046
+ const conversation = (await Conversation.findOne({ conversationId, user }).lean());
3047
+ // Check if user owns the conversation
3048
+ if (!conversation) {
3049
+ throw new ShareServiceError('Conversation not found or access denied', 'CONVERSATION_NOT_FOUND');
3050
+ }
3051
+ // Check if there are any messages to share
3052
+ if (!conversationMessages || conversationMessages.length === 0) {
3053
+ throw new ShareServiceError('No messages to share', 'NO_MESSAGES');
3054
+ }
3055
+ const title = conversation.title || 'Untitled';
3056
+ const shareId = nanoid();
3057
+ await SharedLink.create({
3058
+ shareId,
3059
+ conversationId,
3060
+ messages: conversationMessages,
3061
+ title,
3062
+ user,
3063
+ });
3064
+ return { shareId, conversationId };
3065
+ }
3066
+ catch (error) {
3067
+ if (error instanceof ShareServiceError) {
3068
+ throw error;
3069
+ }
3070
+ logger.error('[createSharedLink] Error creating shared link', {
3071
+ error: error instanceof Error ? error.message : 'Unknown error',
3072
+ user,
3073
+ conversationId,
3074
+ });
3075
+ throw new ShareServiceError('Error creating shared link', 'SHARE_CREATE_ERROR');
3076
+ }
3077
+ }
3078
+ /**
3079
+ * Get a shared link for a conversation
3080
+ */
3081
+ async function getSharedLink(user, conversationId) {
3082
+ if (!user || !conversationId) {
3083
+ throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
3084
+ }
3085
+ try {
3086
+ const SharedLink = mongoose.models.SharedLink;
3087
+ const share = (await SharedLink.findOne({ conversationId, user, isPublic: true })
3088
+ .select('shareId -_id')
3089
+ .lean());
3090
+ if (!share) {
3091
+ return { shareId: null, success: false };
3092
+ }
3093
+ return { shareId: share.shareId || null, success: true };
3094
+ }
3095
+ catch (error) {
3096
+ logger.error('[getSharedLink] Error getting shared link', {
3097
+ error: error instanceof Error ? error.message : 'Unknown error',
3098
+ user,
3099
+ conversationId,
3100
+ });
3101
+ throw new ShareServiceError('Error getting shared link', 'SHARE_FETCH_ERROR');
3102
+ }
3103
+ }
3104
+ /**
3105
+ * Update a shared link with new messages
3106
+ */
3107
+ async function updateSharedLink(user, shareId) {
3108
+ if (!user || !shareId) {
3109
+ throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
3110
+ }
3111
+ try {
3112
+ const SharedLink = mongoose.models.SharedLink;
3113
+ const Message = mongoose.models.Message;
3114
+ const share = (await SharedLink.findOne({ shareId, user })
3115
+ .select('-_id -__v -user')
3116
+ .lean());
3117
+ if (!share) {
3118
+ throw new ShareServiceError('Share not found', 'SHARE_NOT_FOUND');
3119
+ }
3120
+ const updatedMessages = await Message.find({ conversationId: share.conversationId, user })
3121
+ .sort({ createdAt: 1 })
3122
+ .lean();
3123
+ const newShareId = nanoid();
3124
+ const update = {
3125
+ messages: updatedMessages,
3126
+ user,
3127
+ shareId: newShareId,
3128
+ };
3129
+ const updatedShare = (await SharedLink.findOneAndUpdate({ shareId, user }, update, {
3130
+ new: true,
3131
+ upsert: false,
3132
+ runValidators: true,
3133
+ }).lean());
3134
+ if (!updatedShare) {
3135
+ throw new ShareServiceError('Share update failed', 'SHARE_UPDATE_ERROR');
3136
+ }
3137
+ anonymizeConvo(updatedShare);
3138
+ return { shareId: newShareId, conversationId: updatedShare.conversationId };
3139
+ }
3140
+ catch (error) {
3141
+ logger.error('[updateSharedLink] Error updating shared link', {
3142
+ error: error instanceof Error ? error.message : 'Unknown error',
3143
+ user,
3144
+ shareId,
3145
+ });
3146
+ throw new ShareServiceError(error instanceof ShareServiceError ? error.message : 'Error updating shared link', error instanceof ShareServiceError ? error.code : 'SHARE_UPDATE_ERROR');
3147
+ }
3148
+ }
3149
+ /**
3150
+ * Delete a shared link
3151
+ */
3152
+ async function deleteSharedLink(user, shareId) {
3153
+ if (!user || !shareId) {
3154
+ throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
3155
+ }
3156
+ try {
3157
+ const SharedLink = mongoose.models.SharedLink;
3158
+ const result = await SharedLink.findOneAndDelete({ shareId, user }).lean();
3159
+ if (!result) {
3160
+ return null;
3161
+ }
3162
+ return {
3163
+ success: true,
3164
+ shareId,
3165
+ message: 'Share deleted successfully',
3166
+ };
3167
+ }
3168
+ catch (error) {
3169
+ logger.error('[deleteSharedLink] Error deleting shared link', {
3170
+ error: error instanceof Error ? error.message : 'Unknown error',
3171
+ user,
3172
+ shareId,
3173
+ });
3174
+ throw new ShareServiceError('Error deleting shared link', 'SHARE_DELETE_ERROR');
3175
+ }
3176
+ }
3177
+ // Return all methods
3178
+ return {
3179
+ getSharedLink,
3180
+ getSharedLinks,
3181
+ createSharedLink,
3182
+ updateSharedLink,
3183
+ deleteSharedLink,
3184
+ getSharedMessages,
3185
+ deleteAllSharedLinks,
3186
+ };
3187
+ }
3188
+
3189
+ // Factory function that takes mongoose instance and returns the methods
3190
+ function createPluginAuthMethods(mongoose) {
3191
+ const PluginAuth = mongoose.models.PluginAuth;
3192
+ /**
3193
+ * Finds a single plugin auth entry by userId and authField
3194
+ */
3195
+ async function findOnePluginAuth({ userId, authField, }) {
3196
+ try {
3197
+ return await PluginAuth.findOne({ userId, authField }).lean();
3198
+ }
3199
+ catch (error) {
3200
+ throw new Error(`Failed to find plugin auth: ${error instanceof Error ? error.message : 'Unknown error'}`);
3201
+ }
3202
+ }
3203
+ /**
3204
+ * Finds multiple plugin auth entries by userId and pluginKeys
3205
+ */
3206
+ async function findPluginAuthsByKeys({ userId, pluginKeys, }) {
3207
+ try {
3208
+ if (!pluginKeys || pluginKeys.length === 0) {
3209
+ return [];
3210
+ }
3211
+ return await PluginAuth.find({
3212
+ userId,
3213
+ pluginKey: { $in: pluginKeys },
3214
+ }).lean();
3215
+ }
3216
+ catch (error) {
3217
+ throw new Error(`Failed to find plugin auths: ${error instanceof Error ? error.message : 'Unknown error'}`);
3218
+ }
3219
+ }
3220
+ /**
3221
+ * Updates or creates a plugin auth entry
3222
+ */
3223
+ async function updatePluginAuth({ userId, authField, pluginKey, value, }) {
3224
+ try {
3225
+ const existingAuth = await PluginAuth.findOne({ userId, pluginKey, authField }).lean();
3226
+ if (existingAuth) {
3227
+ return await PluginAuth.findOneAndUpdate({ userId, pluginKey, authField }, { $set: { value } }, { new: true, upsert: true }).lean();
3228
+ }
3229
+ else {
3230
+ const newPluginAuth = await new PluginAuth({
3231
+ userId,
3232
+ authField,
3233
+ value,
3234
+ pluginKey,
3235
+ });
3236
+ await newPluginAuth.save();
3237
+ return newPluginAuth.toObject();
3238
+ }
3239
+ }
3240
+ catch (error) {
3241
+ throw new Error(`Failed to update plugin auth: ${error instanceof Error ? error.message : 'Unknown error'}`);
3242
+ }
3243
+ }
3244
+ /**
3245
+ * Deletes plugin auth entries based on provided parameters
3246
+ */
3247
+ async function deletePluginAuth({ userId, authField, pluginKey, all = false, }) {
3248
+ try {
3249
+ if (all) {
3250
+ const filter = { userId };
3251
+ if (pluginKey) {
3252
+ filter.pluginKey = pluginKey;
3253
+ }
3254
+ return await PluginAuth.deleteMany(filter);
3255
+ }
3256
+ if (!authField) {
3257
+ throw new Error('authField is required when all is false');
3258
+ }
3259
+ return await PluginAuth.deleteOne({ userId, authField });
3260
+ }
3261
+ catch (error) {
3262
+ throw new Error(`Failed to delete plugin auth: ${error instanceof Error ? error.message : 'Unknown error'}`);
3263
+ }
3264
+ }
3265
+ /**
3266
+ * Deletes all plugin auth entries for a user
3267
+ */
3268
+ async function deleteAllUserPluginAuths(userId) {
3269
+ try {
3270
+ return await PluginAuth.deleteMany({ userId });
3271
+ }
3272
+ catch (error) {
3273
+ throw new Error(`Failed to delete all user plugin auths: ${error instanceof Error ? error.message : 'Unknown error'}`);
3274
+ }
3275
+ }
3276
+ return {
3277
+ findOnePluginAuth,
3278
+ findPluginAuthsByKeys,
3279
+ updatePluginAuth,
3280
+ deletePluginAuth,
3281
+ deleteAllUserPluginAuths,
3282
+ };
3283
+ }
3284
+
2600
3285
  /**
2601
3286
  * Creates all database methods for all collections
2602
3287
  */
@@ -2606,8 +3291,11 @@ function createMethods(mongoose) {
2606
3291
  ...createSessionMethods(mongoose),
2607
3292
  ...createTokenMethods(mongoose),
2608
3293
  ...createRoleMethods(mongoose),
3294
+ ...createMemoryMethods(mongoose),
3295
+ ...createShareMethods(mongoose),
3296
+ ...createPluginAuthMethods(mongoose),
2609
3297
  };
2610
3298
  }
2611
3299
 
2612
- export { Action as actionSchema, agentSchema, assistantSchema, balanceSchema, bannerSchema, categoriesSchema, conversationTag as conversationTagSchema, convoSchema, createMethods, createModels, file as fileSchema, hashToken, keySchema, logger, logger$1 as meiliLogger, messageSchema, pluginAuthSchema, presetSchema, projectSchema, promptGroupSchema, promptSchema, roleSchema, sessionSchema, shareSchema, signPayload, tokenSchema, toolCallSchema, transactionSchema, userSchema };
3300
+ export { Action as actionSchema, agentSchema, assistantSchema, balanceSchema, bannerSchema, categoriesSchema, conversationTag as conversationTagSchema, convoSchema, createMethods, createModels, file as fileSchema, hashToken, keySchema, logger, logger$1 as meiliLogger, MemoryEntrySchema as memorySchema, messageSchema, pluginAuthSchema, presetSchema, projectSchema, promptGroupSchema, promptSchema, roleSchema, sessionSchema, shareSchema, signPayload, tokenSchema, toolCallSchema, transactionSchema, userSchema };
2613
3301
  //# sourceMappingURL=index.es.js.map