refactor: original changes

This commit is contained in:
Danny Avila 2025-05-30 04:28:22 -04:00
parent fa9177180f
commit f9c0e9853f
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
83 changed files with 413 additions and 505 deletions

View file

@ -1,5 +1,6 @@
const mongoose = require('mongoose');
const crypto = require('node:crypto');
const { Agent } = require('@librechat/data-schemas');
const { SystemRoles, Tools, actionDelimiter } = require('librechat-data-provider');
const { GLOBAL_PROJECT_NAME, EPHEMERAL_AGENT_ID, mcp_delimiter } =
require('librechat-data-provider').Constants;
@ -14,8 +15,6 @@ const getLogStores = require('~/cache/getLogStores');
const { getActions } = require('./Action');
const { logger } = require('~/config');
const db = require('~/lib/db/connectDb');
/**
* Create an agent with the provided data.
* @param {Object} agentData - The agent data to create.
@ -35,7 +34,7 @@ const createAgent = async (agentData) => {
},
],
};
return (await db.models.Agent.create(initialAgentData)).toObject();
return (await Agent.create(initialAgentData)).toObject();
};
/**
@ -46,7 +45,7 @@ const createAgent = async (agentData) => {
* @param {string} searchParameter.author - The user ID of the agent's author.
* @returns {Promise<Agent|null>} The agent document as a plain object, or null if not found.
*/
const getAgent = async (searchParameter) => await db.models.Agent.findOne(searchParameter).lean();
const getAgent = async (searchParameter) => await Agent.findOne(searchParameter).lean();
/**
* Load an agent based on the provided ID
@ -268,7 +267,6 @@ const updateAgent = async (searchParameter, updateData, options = {}) => {
const { updatingUserId = null, forceVersion = false } = options;
const mongoOptions = { new: true, upsert: false };
const Agent = db.models?.Agent;
const currentAgent = await Agent.findOne(searchParameter);
if (currentAgent) {
const { __v, _id, id, versions, author, ...versionData } = currentAgent.toObject();
@ -362,7 +360,6 @@ const updateAgent = async (searchParameter, updateData, options = {}) => {
* @returns {Promise<Agent>} The updated agent.
*/
const addAgentResourceFile = async ({ req, agent_id, tool_resource, file_id }) => {
const Agent = db.models?.Agent;
const searchParameter = { id: agent_id };
let agent = await getAgent(searchParameter);
if (!agent) {
@ -428,7 +425,7 @@ const removeAgentResourceFiles = async ({ agent_id, files }) => {
}
const updatePullData = { $pull: pullOps };
const agentAfterPull = await db.models.Agent.findOneAndUpdate(searchParameter, updatePullData, {
const agentAfterPull = await Agent.findOneAndUpdate(searchParameter, updatePullData, {
new: true,
}).lean();
@ -458,7 +455,7 @@ const removeAgentResourceFiles = async ({ agent_id, files }) => {
* @returns {Promise<void>} Resolves when the agent has been successfully deleted.
*/
const deleteAgent = async (searchParameter) => {
const agent = await db.models.Agent.findOneAndDelete(searchParameter);
const agent = await Agent.findOneAndDelete(searchParameter);
if (agent) {
await removeAgentFromAllProjects(agent.id);
}
@ -483,7 +480,7 @@ const getListAgents = async (searchParameter) => {
query = { $or: [globalQuery, query] };
}
const agents = (
await db.models.Agent.find(query, {
await Agent.find(query, {
id: 1,
_id: 0,
name: 1,
@ -580,7 +577,6 @@ const updateAgentProjects = async ({ user, agentId, projectIds, removeProjectIds
* @throws {Error} If the agent is not found or the specified version does not exist.
*/
const revertAgentVersion = async (searchParameter, versionIndex) => {
const Agent = db.models?.Agent;
const agent = await Agent.findOne(searchParameter);
if (!agent) {
throw new Error('Agent not found');

View file

@ -8,6 +8,7 @@ process.env.CREDS_IV = '0123456789abcdef';
const mongoose = require('mongoose');
const { v4: uuidv4 } = require('uuid');
const { Agent } = require('@librechat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
const {
addAgentResourceFile,
@ -19,9 +20,6 @@ const {
getListAgents,
updateAgentProjects,
} = require('./Agent');
const db = require('~/lib/db/connectDb');
let Agent;
describe('Agent Resource File Operations', () => {
let mongoServer;
@ -29,9 +27,7 @@ describe('Agent Resource File Operations', () => {
beforeAll(async () => {
mongoServer = await MongoMemoryServer.create();
const mongoUri = mongoServer.getUri();
await db.connectDb(mongoUri);
Agent = db.models.Agent;
await mongoose.connect(mongoUri);
});
afterAll(async () => {

View file

@ -1,4 +1,4 @@
const db = require('~/lib/db/connectDb');
const { Assistant } = require('@librechat/data-schemas');
/**
* Update an assistant with new data without overwriting existing properties,
@ -12,7 +12,7 @@ const db = require('~/lib/db/connectDb');
*/
const updateAssistantDoc = async (searchParams, updateData) => {
const options = { new: true, upsert: true };
return await db.models.Assistant.findOneAndUpdate(searchParams, updateData, options).lean();
return await Assistant.findOneAndUpdate(searchParams, updateData, options).lean();
};
/**
@ -23,7 +23,7 @@ const updateAssistantDoc = async (searchParams, updateData) => {
* @param {string} searchParams.user - The user ID of the assistant's author.
* @returns {Promise<AssistantDocument|null>} The assistant document as a plain object, or null if not found.
*/
const getAssistant = async (searchParams) => await db.models.Assistant.findOne(searchParams).lean();
const getAssistant = async (searchParams) => await Assistant.findOne(searchParams).lean();
/**
* Retrieves all assistants that match the given search parameters.
@ -33,7 +33,7 @@ const getAssistant = async (searchParams) => await db.models.Assistant.findOne(s
* @returns {Promise<Array<AssistantDocument>>} A promise that resolves to an array of assistant documents as plain objects.
*/
const getAssistants = async (searchParams, select = null) => {
let query = db.models.Assistant.find(searchParams);
let query = Assistant.find(searchParams);
if (select) {
query = query.select(select);
@ -51,7 +51,7 @@ const getAssistants = async (searchParams, select = null) => {
* @returns {Promise<void>} Resolves when the assistant has been successfully deleted.
*/
const deleteAssistant = async (searchParams) => {
return await db.models.Assistant.findOneAndDelete(searchParams);
return await Assistant.findOneAndDelete(searchParams);
};
module.exports = {

View file

@ -1,5 +1,4 @@
const logger = require('~/config/winston');
const db = require('~/lib/db/connectDb');
const { Banner, logger } = require('@librechat/data-schemas');
/**
* Retrieves the current active banner.
@ -8,7 +7,7 @@ const db = require('~/lib/db/connectDb');
const getBanner = async (user) => {
try {
const now = new Date();
const banner = await db.models.Banner.findOne({
const banner = await Banner.findOne({
displayFrom: { $lte: now },
$or: [{ displayTo: { $gte: now } }, { displayTo: null }],
type: 'banner',

View file

@ -1,6 +1,5 @@
const { Conversation, logger } = require('@librechat/data-schemas');
const { getMessages, deleteMessages } = require('./Message');
const logger = require('~/config/winston');
const db = require('~/lib/db/connectDb');
/**
* Searches for a conversation by conversationId and returns a lean document with only conversationId and user.
* @param {string} conversationId - The conversation's ID.
@ -8,7 +7,7 @@ const db = require('~/lib/db/connectDb');
*/
const searchConversation = async (conversationId) => {
try {
return await db.models.Conversation.findOne({ conversationId }, 'conversationId user').lean();
return await Conversation.findOne({ conversationId }, 'conversationId user').lean();
} catch (error) {
logger.error('[searchConversation] Error searching conversation', error);
throw new Error('Error searching conversation');
@ -23,7 +22,7 @@ const searchConversation = async (conversationId) => {
*/
const getConvo = async (user, conversationId) => {
try {
return await db.models.Conversation.findOne({ user, conversationId }).lean();
return await Conversation.findOne({ user, conversationId }).lean();
} catch (error) {
logger.error('[getConvo] Error getting single conversation', error);
return { message: 'Error getting single conversation' };
@ -40,7 +39,7 @@ const deleteNullOrEmptyConversations = async () => {
],
};
const result = await db.models.Conversation.deleteMany(filter);
const result = await Conversation.deleteMany(filter);
// Delete associated messages
const messageDeleteResult = await deleteMessages(filter);
@ -66,7 +65,7 @@ const deleteNullOrEmptyConversations = async () => {
*/
const getConvoFiles = async (conversationId) => {
try {
return (await db.models.Conversation.findOne({ conversationId }, 'files').lean())?.files ?? [];
return (await Conversation.findOne({ conversationId }, 'files').lean())?.files ?? [];
} catch (error) {
logger.error('[getConvoFiles] Error getting conversation files', error);
throw new Error('Error getting conversation files');
@ -112,7 +111,7 @@ module.exports = {
}
/** Note: the resulting Model object is necessary for Meilisearch operations */
const conversation = await db.models.Conversation.findOneAndUpdate(
const conversation = await Conversation.findOneAndUpdate(
{ conversationId, user: req.user.id },
updateOperation,
{
@ -141,7 +140,7 @@ module.exports = {
},
}));
const result = await db.models.Conversation.bulkWrite(bulkOps);
const result = await Conversation.bulkWrite(bulkOps);
return result;
} catch (error) {
logger.error('[saveBulkConversations] Error saving conversations in bulk', error);
@ -153,7 +152,6 @@ module.exports = {
{ cursor, limit = 25, isArchived = false, tags, search, order = 'desc' } = {},
) => {
const filters = [{ user }];
const { Conversation } = db.models;
if (isArchived) {
filters.push({ isArchived: true });
} else {
@ -217,7 +215,7 @@ module.exports = {
const conversationIds = convoIds.map((convo) => convo.conversationId);
const results = await db.models.Conversation.find({
const results = await Conversation.find({
user,
conversationId: { $in: conversationIds },
$or: [{ expiredAt: { $exists: false } }, { expiredAt: null }],
@ -286,7 +284,6 @@ module.exports = {
deleteConvos: async (user, filter) => {
try {
const userFilter = { ...filter, user };
const { Conversation } = db.models;
const conversations = await Conversation.find(userFilter).select('conversationId');
const conversationIds = conversations.map((c) => c.conversationId);

View file

@ -1,5 +1,4 @@
const logger = require('~/config/winston');
const db = require('~/lib/db/connectDb');
const { ConversationTag, Conversation, logger } = require('@librechat/data-schemas');
/**
* Retrieves all conversation tags for a user.
@ -8,7 +7,7 @@ const db = require('~/lib/db/connectDb');
*/
const getConversationTags = async (user) => {
try {
return await db.models.ConversationTag.find({ user }).sort({ position: 1 }).lean();
return await ConversationTag.find({ user }).sort({ position: 1 }).lean();
} catch (error) {
logger.error('[getConversationTags] Error getting conversation tags', error);
throw new Error('Error getting conversation tags');
@ -29,7 +28,6 @@ const createConversationTag = async (user, data) => {
try {
const { tag, description, addToConversation, conversationId } = data;
const { ConversationTag, Conversation } = db.models;
const existingTag = await ConversationTag.findOne({ user, tag }).lean();
if (existingTag) {
return existingTag;
@ -84,7 +82,6 @@ const updateConversationTag = async (user, oldTag, data) => {
try {
const { tag: newTag, description, position } = data;
const { ConversationTag, Conversation } = db.models;
const existingTag = await ConversationTag.findOne({ user, tag: oldTag }).lean();
if (!existingTag) {
return null;
@ -145,7 +142,7 @@ const adjustPositions = async (user, oldPosition, newPosition) => {
$lt: Math.max(oldPosition, newPosition),
};
await db.models.ConversationTag.updateMany(
await ConversationTag.updateMany(
{
user,
position,
@ -162,7 +159,6 @@ const adjustPositions = async (user, oldPosition, newPosition) => {
*/
const deleteConversationTag = async (user, tag) => {
try {
const { ConversationTag, Conversation } = db.models;
const deletedTag = await ConversationTag.findOneAndDelete({ user, tag }).lean();
if (!deletedTag) {
return null;
@ -191,7 +187,6 @@ const deleteConversationTag = async (user, tag) => {
*/
const updateTagsForConversation = async (user, conversationId, tags) => {
try {
const { ConversationTag, Conversation } = db.models;
const conversation = await Conversation.findOne({ user, conversationId }).lean();
if (!conversation) {
throw new Error('Conversation not found');

View file

@ -1,7 +1,7 @@
const mongoose = require('mongoose');
const { File } = require('@librechat/data-schemas');
const { EToolResources } = require('librechat-data-provider');
const { logger } = require('~/config');
const db = require('~/lib/db/connectDb');
/**
* Finds a file by its file_id with additional query options.
@ -10,7 +10,7 @@ const db = require('~/lib/db/connectDb');
* @returns {Promise<MongoFile>} A promise that resolves to the file document or null.
*/
const findFileById = async (file_id, options = {}) => {
return await db.models.File.findOne({ file_id, ...options }).lean();
return await File.findOne({ file_id, ...options }).lean();
};
/**
@ -23,7 +23,7 @@ const findFileById = async (file_id, options = {}) => {
*/
const getFiles = async (filter, _sortOptions, selectFields = { text: 0 }) => {
const sortOptions = { updatedAt: -1, ..._sortOptions };
return await db.models.File.find(filter).select(selectFields).sort(sortOptions).lean();
return await File.find(filter).select(selectFields).sort(sortOptions).lean();
};
/**
@ -79,7 +79,7 @@ const createFile = async (data, disableTTL) => {
delete fileData.expiresAt;
}
return await db.models.File.findOneAndUpdate({ file_id: data.file_id }, fileData, {
return await File.findOneAndUpdate({ file_id: data.file_id }, fileData, {
new: true,
upsert: true,
}).lean();
@ -96,7 +96,7 @@ const updateFile = async (data) => {
$set: update,
$unset: { expiresAt: '' }, // Remove the expiresAt field to prevent TTL
};
return await db.models.File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean();
return await File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean();
};
/**
@ -110,7 +110,7 @@ const updateFileUsage = async (data) => {
$inc: { usage: inc },
$unset: { expiresAt: '', temp_file_id: '' },
};
return await db.models.File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean();
return await File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean();
};
/**
@ -119,7 +119,7 @@ const updateFileUsage = async (data) => {
* @returns {Promise<MongoFile>} A promise that resolves to the deleted file document or null.
*/
const deleteFile = async (file_id) => {
return await db.models.File.findOneAndDelete({ file_id }).lean();
return await File.findOneAndDelete({ file_id }).lean();
};
/**
@ -128,7 +128,7 @@ const deleteFile = async (file_id) => {
* @returns {Promise<MongoFile>} A promise that resolves to the deleted file document or null.
*/
const deleteFileByFilter = async (filter) => {
return await db.models.File.findOneAndDelete(filter).lean();
return await File.findOneAndDelete(filter).lean();
};
/**
@ -141,7 +141,7 @@ const deleteFiles = async (file_ids, user) => {
if (user) {
deleteQuery = { user: user };
}
return await db.models.File.deleteMany(deleteQuery);
return await File.deleteMany(deleteQuery);
};
/**

View file

@ -1,6 +1,5 @@
const { z } = require('zod');
const { logger } = require('~/config');
const db = require('~/lib/db/connectDb');
const { Message, logger } = require('@librechat/data-schemas');
const idSchema = z.string().uuid();
/**
@ -67,7 +66,7 @@ async function saveMessage(req, params, metadata) {
logger.info(`---\`saveMessage\` context: ${metadata?.context}`);
update.tokenCount = 0;
}
const message = await db.models.Message.findOneAndUpdate(
const message = await Message.findOneAndUpdate(
{ messageId: params.messageId, user: req.user.id },
update,
{ upsert: true, new: true },
@ -85,7 +84,7 @@ async function saveMessage(req, params, metadata) {
try {
// Try to find the existing message with this ID
const existingMessage = await db.models.Message.findOne({
const existingMessage = await Message.findOne({
messageId: params.messageId,
user: req.user.id,
});
@ -138,7 +137,7 @@ async function bulkSaveMessages(messages, overrideTimestamp = false) {
upsert: true,
},
}));
const result = await db.models.Message.bulkWrite(bulkOps);
const result = await Message.bulkWrite(bulkOps);
return result;
} catch (err) {
logger.error('Error saving messages in bulk:', err);
@ -180,7 +179,7 @@ async function recordMessage({
...rest,
};
return await db.models.Message.findOneAndUpdate({ user, messageId }, message, {
return await Message.findOneAndUpdate({ user, messageId }, message, {
upsert: true,
new: true,
});
@ -204,7 +203,7 @@ async function recordMessage({
*/
async function updateMessageText(req, { messageId, text }) {
try {
await db.models?.Message.updateOne({ messageId, user: req.user.id }, { text });
await Message.updateOne({ messageId, user: req.user.id }, { text });
} catch (err) {
logger.error('Error updating message text:', err);
throw err;
@ -232,7 +231,7 @@ async function updateMessageText(req, { messageId, text }) {
async function updateMessage(req, message, metadata) {
try {
const { messageId, ...update } = message;
const updatedMessage = await db.models.Message.findOneAndUpdate(
const updatedMessage = await Message.findOneAndUpdate(
{ messageId, user: req.user.id },
update,
{
@ -276,10 +275,10 @@ async function updateMessage(req, message, metadata) {
*/
async function deleteMessagesSince(req, { messageId, conversationId }) {
try {
const message = await db.models.Message.findOne({ messageId, user: req.user.id }).lean();
const message = await Message.findOne({ messageId, user: req.user.id }).lean();
if (message) {
const query = db.models.Message.find({ conversationId, user: req.user.id });
const query = Message.find({ conversationId, user: req.user.id });
return await query.deleteMany({
createdAt: { $gt: message.createdAt },
});
@ -303,10 +302,10 @@ async function deleteMessagesSince(req, { messageId, conversationId }) {
async function getMessages(filter, select) {
try {
if (select) {
return await db.models.Message.find(filter).select(select).sort({ createdAt: 1 }).lean();
return await Message.find(filter).select(select).sort({ createdAt: 1 }).lean();
}
return await db.models.Message.find(filter).sort({ createdAt: 1 }).lean();
return await Message.find(filter).sort({ createdAt: 1 }).lean();
} catch (err) {
logger.error('Error getting messages:', err);
throw err;
@ -323,7 +322,7 @@ async function getMessages(filter, select) {
*/
async function getMessage({ user, messageId }) {
try {
return await db.models.Message.findOne({
return await Message.findOne({
user,
messageId,
}).lean();
@ -344,7 +343,7 @@ async function getMessage({ user, messageId }) {
*/
async function deleteMessages(filter) {
try {
return await db.models.Message.deleteMany(filter);
return await Message.deleteMany(filter);
} catch (err) {
logger.error('Error deleting messages:', err);
throw err;

View file

@ -1,9 +1,8 @@
const { logger } = require('~/config');
const db = require('~/lib/db/connectDb');
const { Preset, logger } = require('@librechat/data-schemas');
const getPreset = async (user, presetId) => {
try {
return await db.models.Preset.findOne({ user, presetId }).lean();
return await Preset.findOne({ user, presetId }).lean();
} catch (error) {
logger.error('[getPreset] Error getting single preset', error);
return { message: 'Error getting single preset' };
@ -14,7 +13,7 @@ module.exports = {
getPreset,
getPresets: async (user, filter) => {
try {
const presets = await db.models.Preset.find({ ...filter, user }).lean();
const presets = await Preset.find({ ...filter, user }).lean();
const defaultValue = 10000;
presets.sort((a, b) => {
@ -39,7 +38,6 @@ module.exports = {
const setter = { $set: {} };
const { user: _, ...cleanPreset } = preset;
const update = { presetId, ...cleanPreset };
const Preset = db.models.Preset;
if (preset.tools && Array.isArray(preset.tools)) {
update.tools =
preset.tools
@ -77,7 +75,7 @@ module.exports = {
deletePresets: async (user, filter) => {
// let toRemove = await Preset.find({ ...filter, user }).select('presetId');
// const ids = toRemove.map((instance) => instance.presetId);
let deleteCount = await db.models.Preset.deleteMany({ ...filter, user });
let deleteCount = await Preset.deleteMany({ ...filter, user });
return deleteCount;
},
};

View file

@ -1,5 +1,5 @@
const { Project } = require('@librechat/data-schemas');
const { GLOBAL_PROJECT_NAME } = require('librechat-data-provider').Constants;
const db = require('~/lib/db/connectDb');
/**
* Retrieve a project by ID and convert the found project document to a plain object.
@ -9,7 +9,7 @@ const db = require('~/lib/db/connectDb');
* @returns {Promise<IMongoProject>} A plain object representing the project document, or `null` if no project is found.
*/
const getProjectById = async function (projectId, fieldsToSelect = null) {
const query = db.models.Project.findById(projectId);
const query = Project.findById(projectId);
if (fieldsToSelect) {
query.select(fieldsToSelect);
@ -36,7 +36,7 @@ const getProjectByName = async function (projectName, fieldsToSelect = null) {
select: fieldsToSelect,
};
return await db.models.Project.findOneAndUpdate(query, update, options);
return await Project.findOneAndUpdate(query, update, options);
};
/**
@ -47,7 +47,7 @@ const getProjectByName = async function (projectName, fieldsToSelect = null) {
* @returns {Promise<IMongoProject>} The updated project document.
*/
const addGroupIdsToProject = async function (projectId, promptGroupIds) {
return await db.models.Project.findByIdAndUpdate(
return await Project.findByIdAndUpdate(
projectId,
{ $addToSet: { promptGroupIds: { $each: promptGroupIds } } },
{ new: true },
@ -62,7 +62,7 @@ const addGroupIdsToProject = async function (projectId, promptGroupIds) {
* @returns {Promise<IMongoProject>} The updated project document.
*/
const removeGroupIdsFromProject = async function (projectId, promptGroupIds) {
return await db.models.Project.findByIdAndUpdate(
return await Project.findByIdAndUpdate(
projectId,
{ $pull: { promptGroupIds: { $in: promptGroupIds } } },
{ new: true },
@ -76,7 +76,7 @@ const removeGroupIdsFromProject = async function (projectId, promptGroupIds) {
* @returns {Promise<void>}
*/
const removeGroupFromAllProjects = async (promptGroupId) => {
await db.models.Project.updateMany({}, { $pull: { promptGroupIds: promptGroupId } });
await Project.updateMany({}, { $pull: { promptGroupIds: promptGroupId } });
};
/**
@ -87,7 +87,7 @@ const removeGroupFromAllProjects = async (promptGroupId) => {
* @returns {Promise<IMongoProject>} The updated project document.
*/
const addAgentIdsToProject = async function (projectId, agentIds) {
return await db.models.Project.findByIdAndUpdate(
return await Project.findByIdAndUpdate(
projectId,
{ $addToSet: { agentIds: { $each: agentIds } } },
{ new: true },
@ -102,7 +102,7 @@ const addAgentIdsToProject = async function (projectId, agentIds) {
* @returns {Promise<IMongoProject>} The updated project document.
*/
const removeAgentIdsFromProject = async function (projectId, agentIds) {
return await db.models.Project.findByIdAndUpdate(
return await Project.findByIdAndUpdate(
projectId,
{ $pull: { agentIds: { $in: agentIds } } },
{ new: true },
@ -116,7 +116,7 @@ const removeAgentIdsFromProject = async function (projectId, agentIds) {
* @returns {Promise<void>}
*/
const removeAgentFromAllProjects = async (agentId) => {
await db.models.Project.updateMany({}, { $pull: { agentIds: agentId } });
await Project.updateMany({}, { $pull: { agentIds: agentId } });
};
module.exports = {

View file

@ -1,4 +1,5 @@
const { ObjectId } = require('mongodb');
const { Prompt, PromptGroup, logger } = require('@librechat/data-schemas');
const { SystemRoles, SystemCategories, Constants } = require('librechat-data-provider');
const {
getProjectByName,
@ -7,8 +8,6 @@ const {
removeGroupFromAllProjects,
} = require('./Project');
const { escapeRegExp } = require('~/server/utils');
const { logger } = require('~/config');
const db = require('~/lib/db/connectDb');
/**
* Create a pipeline for the aggregation to get prompt groups
@ -133,7 +132,7 @@ const getAllPromptGroups = async (req, filter) => {
}
const promptGroupsPipeline = createAllGroupsPipeline(combinedQuery);
return await db.models.PromptGroup.aggregate(promptGroupsPipeline).exec();
return await PromptGroup.aggregate(promptGroupsPipeline).exec();
} catch (error) {
console.error('Error getting all prompt groups', error);
return { message: 'Error getting all prompt groups' };
@ -233,7 +232,7 @@ const deletePromptGroup = async ({ _id, author, role }) => {
throw new Error('Prompt group not found');
}
await db.models.Prompt.deleteMany(groupQuery);
await Prompt.deleteMany(groupQuery);
await removeGroupFromAllProjects(_id);
return { message: 'Prompt group deleted successfully' };
};
@ -250,7 +249,6 @@ module.exports = {
createPromptGroup: async (saveData) => {
try {
const { prompt, group, author, authorName } = saveData;
const { Prompt, PromptGroup } = db.models;
let newPromptGroup = await PromptGroup.findOneAndUpdate(
{ ...group, author, authorName, productionId: null },
@ -306,7 +304,6 @@ module.exports = {
/** @type {TPrompt} */
let newPrompt;
const { Prompt } = db.models;
try {
newPrompt = await Prompt.create(newPromptData);
} catch (error) {
@ -326,7 +323,7 @@ module.exports = {
},
getPrompts: async (filter) => {
try {
return await db.models.Prompt.find(filter).sort({ createdAt: -1 }).lean();
return await Prompt.find(filter).sort({ createdAt: -1 }).lean();
} catch (error) {
logger.error('Error getting prompts', error);
return { message: 'Error getting prompts' };
@ -337,7 +334,7 @@ module.exports = {
if (filter.groupId) {
filter.groupId = new ObjectId(filter.groupId);
}
return await db.models.Prompt.findOne(filter).lean();
return await Prompt.findOne(filter).lean();
} catch (error) {
logger.error('Error getting prompt', error);
return { message: 'Error getting prompt' };
@ -350,7 +347,7 @@ module.exports = {
*/
getRandomPromptGroups: async (filter) => {
try {
const result = await db.models.PromptGroup.aggregate([
const result = await PromptGroup.aggregate([
{
$match: {
category: { $ne: '' },
@ -383,7 +380,7 @@ module.exports = {
},
getPromptGroupsWithPrompts: async (filter) => {
try {
return await db.models.PromptGroup.findOne(filter)
return await PromptGroup.findOne(filter)
.populate({
path: 'prompts',
select: '-_id -__v -user',
@ -397,7 +394,7 @@ module.exports = {
},
getPromptGroup: async (filter) => {
try {
return await db.models.PromptGroup.findOne(filter).lean();
return await PromptGroup.findOne(filter).lean();
} catch (error) {
logger.error('Error getting prompt group', error);
return { message: 'Error getting prompt group' };
@ -418,7 +415,6 @@ module.exports = {
*/
deletePrompt: async ({ promptId, groupId, author, role }) => {
const query = { _id: promptId, groupId, author };
const { Prompt, PromptGroup } = db.models;
if (role === SystemRoles.ADMIN) {
delete query.author;
}
@ -483,7 +479,7 @@ module.exports = {
}
const updateData = { ...data, ...updateOps };
const updatedDoc = await db.models.PromptGroup.findOneAndUpdate(filter, updateData, {
const updatedDoc = await PromptGroup.findOneAndUpdate(filter, updateData, {
new: true,
upsert: false,
});
@ -505,7 +501,6 @@ module.exports = {
*/
makePromptProduction: async (promptId) => {
try {
const { Prompt, PromptGroup } = db.models;
const prompt = await Prompt.findById(promptId).lean();
if (!prompt) {
@ -530,7 +525,7 @@ module.exports = {
},
updatePromptLabels: async (_id, labels) => {
try {
const response = await db.models.Prompt.updateOne({ _id }, { $set: { labels } });
const response = await Prompt.updateOne({ _id }, { $set: { labels } });
if (response.matchedCount === 0) {
return { message: 'Prompt not found' };
}

View file

@ -6,9 +6,8 @@ const {
permissionsSchema,
removeNullishValues,
} = require('librechat-data-provider');
const { Role, logger } = require('@librechat/data-schemas');
const getLogStores = require('~/cache/getLogStores');
const { logger } = require('~/config');
const db = require('~/lib/db/connectDb');
/**
* Retrieve a role by name and convert the found role document to a plain object.
@ -21,7 +20,6 @@ const db = require('~/lib/db/connectDb');
*/
const getRoleByName = async function (roleName, fieldsToSelect = null) {
const cache = getLogStores(CacheKeys.ROLES);
const { Role } = db.models;
try {
const cachedRole = await cache.get(roleName);
if (cachedRole) {
@ -55,7 +53,7 @@ const getRoleByName = async function (roleName, fieldsToSelect = null) {
const updateRoleByName = async function (roleName, updates) {
const cache = getLogStores(CacheKeys.ROLES);
try {
const role = await db.models.Role.findOneAndUpdate(
const role = await Role.findOneAndUpdate(
{ name: roleName },
{ $set: updates },
{ new: true, lean: true },
@ -76,7 +74,6 @@ const updateRoleByName = async function (roleName, updates) {
* @param {Object.<PermissionTypes, Object.<Permissions, boolean>>} permissionsUpdate - Permissions to update and their values.
*/
async function updateAccessPermissions(roleName, permissionsUpdate) {
const { Role } = db.models;
// Filter and clean the permission updates based on our schema definition.
const updates = {};
for (const [permissionType, permissions] of Object.entries(permissionsUpdate)) {
@ -180,7 +177,6 @@ async function updateAccessPermissions(roleName, permissionsUpdate) {
* @returns {Promise<void>}
*/
const initializeRoles = async function () {
const { Role } = db.models;
for (const roleName of [SystemRoles.ADMIN, SystemRoles.USER]) {
let role = await Role.findOne({ name: roleName });
const defaultPerms = roleDefaults[roleName].permissions;
@ -210,7 +206,6 @@ const initializeRoles = async function () {
* @returns {Promise<number>} Number of roles migrated.
*/
const migrateRoleSchema = async function (roleName) {
const { Role } = db.models;
try {
// Get roles to migrate
let roles;

View file

@ -1,4 +1,5 @@
const mongoose = require('mongoose');
const { Role, logger } = require('@librechat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
const {
SystemRoles,
@ -9,8 +10,6 @@ const {
const { getRoleByName, updateAccessPermissions, initializeRoles } = require('~/models/Role');
const getLogStores = require('~/cache/getLogStores');
const db = require('~/lib/db/connectDb');
// Mock the cache
jest.mock('~/cache/getLogStores', () =>
jest.fn().mockReturnValue({
@ -21,14 +20,11 @@ jest.mock('~/cache/getLogStores', () =>
);
let mongoServer;
let Role;
beforeAll(async () => {
mongoServer = await MongoMemoryServer.create();
const mongoUri = mongoServer.getUri();
await db.connectDb(mongoUri);
Role = db.models.Role;
await mongoose.connect(mongoUri);
});
afterAll(async () => {

View file

@ -1,8 +1,7 @@
const { nanoid } = require('nanoid');
const { Constants } = require('librechat-data-provider');
const db = require('~/lib/db/connectDb');
const { SharedLink, Conversation, logger } = require('@librechat/data-schemas');
const { getMessages } = require('./Message');
const logger = require('~/config/winston');
class ShareServiceError extends Error {
constructor(message, code) {
@ -73,7 +72,7 @@ function anonymizeMessages(messages, newConvoId) {
async function getSharedMessages(shareId) {
try {
const share = await db.models.SharedLink.findOne({ shareId, isPublic: true })
const share = await SharedLink.findOne({ shareId, isPublic: true })
.populate({
path: 'messages',
select: '-_id -__v -user',
@ -148,7 +147,7 @@ async function getSharedLinks(user, pageParam, pageSize, isPublic, sortBy, sortD
query.conversationId = { $in: query.conversationId };
}
const sharedLinks = await db.models.SharedLink.find(query)
const sharedLinks = await SharedLink.find(query)
.sort(sort)
.limit(pageSize + 1)
.select('-__v -user')
@ -181,7 +180,7 @@ async function getSharedLinks(user, pageParam, pageSize, isPublic, sortBy, sortD
async function deleteAllSharedLinks(user) {
try {
const result = await db.models.SharedLink.deleteMany({ user });
const result = await SharedLink.deleteMany({ user });
return {
message: 'All shared links deleted successfully',
deletedCount: result.deletedCount,
@ -199,7 +198,6 @@ async function createSharedLink(user, conversationId) {
if (!user || !conversationId) {
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
}
const { SharedLink, Conversation } = db.models;
try {
const [existingShare, conversationMessages] = await Promise.all([
SharedLink.findOne({ conversationId, isPublic: true }).select('-_id -__v -user').lean(),
@ -241,7 +239,7 @@ async function getSharedLink(user, conversationId) {
}
try {
const share = await db.models.SharedLink.findOne({ conversationId, user, isPublic: true })
const share = await SharedLink.findOne({ conversationId, user, isPublic: true })
.select('shareId -_id')
.lean();
@ -265,7 +263,6 @@ async function updateSharedLink(user, shareId) {
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
}
const { SharedLink } = db.models;
try {
const share = await SharedLink.findOne({ shareId }).select('-_id -__v -user').lean();
@ -316,7 +313,7 @@ async function deleteSharedLink(user, shareId) {
}
try {
const result = await db.models.SharedLink.findOneAndDelete({ shareId, user }).lean();
const result = await SharedLink.findOneAndDelete({ shareId, user }).lean();
if (!result) {
return null;

View file

@ -1,5 +1,5 @@
const { Token } = require('@librechat/data-schemas');
const { encryptV2 } = require('~/server/utils/crypto');
const db = require('~/lib/db/connectDb');
/**
* Handles the OAuth token by creating or updating the token.
@ -29,7 +29,6 @@ async function handleOAuthToken({
expiresIn: parseInt(expiresIn, 10) || 3600,
};
const { Token } = db.models;
const existingToken = await Token.findToken({ userId, identifier });
if (existingToken) {
return await Token.updateToken({ identifier }, tokenData);

View file

@ -1,4 +1,4 @@
const db = require('~/lib/db/connectDb');
const { ToolCall } = require('@librechat/data-schemas');
/**
* Create a new tool call
* @param {IToolCallData} toolCallData - The tool call data
@ -6,7 +6,7 @@ const db = require('~/lib/db/connectDb');
*/
async function createToolCall(toolCallData) {
try {
return await db.models.ToolCall.create(toolCallData);
return await ToolCall.create(toolCallData);
} catch (error) {
throw new Error(`Error creating tool call: ${error.message}`);
}
@ -19,7 +19,7 @@ async function createToolCall(toolCallData) {
*/
async function getToolCallById(id) {
try {
return await db.models.ToolCall.findById(id).lean();
return await ToolCall.findById(id).lean();
} catch (error) {
throw new Error(`Error fetching tool call: ${error.message}`);
}
@ -33,7 +33,7 @@ async function getToolCallById(id) {
*/
async function getToolCallsByMessage(messageId, userId) {
try {
return await db.models.ToolCall.find({ messageId, user: userId }).lean();
return await ToolCall.find({ messageId, user: userId }).lean();
} catch (error) {
throw new Error(`Error fetching tool calls: ${error.message}`);
}
@ -47,7 +47,7 @@ async function getToolCallsByMessage(messageId, userId) {
*/
async function getToolCallsByConvo(conversationId, userId) {
try {
return await db.models.ToolCall.find({ conversationId, user: userId }).lean();
return await ToolCall.find({ conversationId, user: userId }).lean();
} catch (error) {
throw new Error(`Error fetching tool calls: ${error.message}`);
}
@ -61,7 +61,7 @@ async function getToolCallsByConvo(conversationId, userId) {
*/
async function updateToolCall(id, updateData) {
try {
return await db.models.ToolCall.findByIdAndUpdate(id, updateData, { new: true }).lean();
return await ToolCall.findByIdAndUpdate(id, updateData, { new: true }).lean();
} catch (error) {
throw new Error(`Error updating tool call: ${error.message}`);
}
@ -79,7 +79,7 @@ async function deleteToolCalls(userId, conversationId) {
if (conversationId) {
query.conversationId = conversationId;
}
return await db.models.ToolCall.deleteMany(query);
return await ToolCall.deleteMany(query);
} catch (error) {
throw new Error(`Error deleting tool call: ${error.message}`);
}

View file

@ -1,9 +1,7 @@
const mongoose = require('mongoose');
const { transactionSchema } = require('@librechat/data-schemas');
const { Balance, Transaction, logger } = require('@librechat/data-schemas');
const { getBalanceConfig } = require('~/server/services/Config');
const { getMultiplier, getCacheMultiplier } = require('./tx');
const { logger } = require('~/config');
const db = require('~/lib/db/connectDb');
const cancelRate = 1.15;
@ -23,7 +21,6 @@ const updateBalance = async ({ user, incrementValue, setValues }) => {
let maxRetries = 10; // Number of times to retry on conflict
let delay = 50; // Initial retry delay in ms
let lastError = null;
const { Balance } = db.models;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
let currentBalanceDoc;
@ -165,7 +162,6 @@ function calculateTokenValue(txn) {
* @returns {Promise<object>} - The created transaction.
*/
async function createAutoRefillTransaction(txData) {
const Transaction = db.models.Transaction;
if (txData.rawAmount != null && isNaN(txData.rawAmount)) {
return;
}
@ -198,7 +194,7 @@ async function createTransaction(txData) {
return;
}
const transaction = new db.models.Transaction(txData);
const transaction = new Transaction(txData);
transaction.endpointTokenConfig = txData.endpointTokenConfig;
calculateTokenValue(transaction);
@ -228,7 +224,7 @@ async function createTransaction(txData) {
* @param {txData} txData - Transaction data.
*/
async function createStructuredTransaction(txData) {
const transaction = new db.models.Transaction({
const transaction = new Transaction({
...txData,
endpointTokenConfig: txData.endpointTokenConfig,
});
@ -329,7 +325,7 @@ function calculateStructuredTokenValue(txn) {
*/
async function getTransactions(filter) {
try {
return await db.models.Transaction.find(filter).lean();
return await Transaction.find(filter).lean();
} catch (error) {
logger.error('Error querying transactions:', error);
throw error;

View file

@ -1,24 +1,19 @@
const mongoose = require('mongoose');
const { Balance } = require('@librechat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
const { spendTokens, spendStructuredTokens } = require('./spendTokens');
const { getBalanceConfig } = require('~/server/services/Config');
const { getMultiplier, getCacheMultiplier } = require('./tx');
const db = require('~/lib/db/connectDb');
const { createTransaction } = require('./Transaction');
// Mock the custom config module so we can control the balance flag.
jest.mock('~/server/services/Config');
let mongoServer;
let Balance;
let Transaction;
beforeAll(async () => {
mongoServer = await MongoMemoryServer.create();
const mongoUri = mongoServer.getUri();
await db.connectDb(mongoUri);
Balance = db.models.Balance;
Transaction = db.models.Transaction;
await mongoose.connect(mongoUri);
});
afterAll(async () => {

View file

@ -1,9 +1,9 @@
const { Balance } = require('@librechat/data-schemas');
const { ViolationTypes } = require('librechat-data-provider');
const { createAutoRefillTransaction } = require('./Transaction');
const { logViolation } = require('~/cache');
const { getMultiplier } = require('./tx');
const { logger } = require('~/config');
const db = require('~/lib/db/connectDb');
function isInvalidDate(date) {
return isNaN(date);
@ -26,7 +26,7 @@ const checkBalanceRecord = async function ({
const tokenCost = amount * multiplier;
// Retrieve the balance record
let record = await db.models.Balance.findOne({ user }).lean();
let record = await Balance.findOne({ user }).lean();
if (!record) {
logger.debug('[Balance.check] No balance record found for user', { user });
return {

View file

@ -1,7 +1,7 @@
const mongoose = require('mongoose');
const { Message } = require('@librechat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
const { getMessages, bulkSaveMessages } = require('./Message');
const db = require('~/lib/db/connectDb');
// Original version of buildTree function
function buildTree({ messages, fileMap }) {
@ -43,13 +43,10 @@ function buildTree({ messages, fileMap }) {
}
let mongod;
let Message;
beforeAll(async () => {
mongod = await MongoMemoryServer.create();
const uri = mongod.getUri();
await db.connectDb(uri);
Message = db.models.Message;
await mongoose.connect(uri);
});
afterAll(async () => {

View file

@ -1,7 +1,6 @@
const mongoose = require('mongoose');
const { Token, logger } = require('@librechat/data-schemas');
const { getRandomValues, hashToken } = require('~/server/utils/crypto');
const logger = require('~/config/winston');
const db = require('~/lib/db/connectDb');
/**
* @module inviteUser
@ -23,7 +22,7 @@ const createInvite = async (email) => {
const fakeUserId = new mongoose.Types.ObjectId();
await db.models.Token.createToken({
await Token.createToken({
userId: fakeUserId,
email,
token: hash,
@ -50,7 +49,7 @@ const getInvite = async (encodedToken, email) => {
try {
const token = decodeURIComponent(encodedToken);
const hash = await hashToken(token);
const invite = await db.models.Token.findToken({ token: hash, email });
const invite = await Token.findToken({ token: hash, email });
if (!invite) {
throw new Error('Invite not found or email does not match');

View file

@ -1,7 +1,7 @@
const mongoose = require('mongoose');
const { MongoMemoryServer } = require('mongodb-memory-server');
const { Transaction, Balance } = require('@librechat/data-schemas');
const { spendTokens, spendStructuredTokens } = require('./spendTokens');
const db = require('~/lib/db/connectDb');
const { createTransaction, createAutoRefillTransaction } = require('./Transaction');
// Mock the logger to prevent console output during tests
@ -20,15 +20,9 @@ describe('spendTokens', () => {
let mongoServer;
let userId;
let Transaction;
let Balance;
beforeAll(async () => {
mongoServer = await MongoMemoryServer.create();
const mongoUri = mongoServer.getUri();
await db.connectDb(mongoUri);
Balance = db.models.Balance;
Transaction = db.models.Transaction;
await mongoose.connect(mongoServer.getUri());
});
afterAll(async () => {