| const { logger } = require('@librechat/data-schemas'); |
| const { EToolResources, FileContext } = require('librechat-data-provider'); |
| const { File } = require('~/db/models'); |
|
|
| |
| |
| |
| |
| |
| |
| const findFileById = async (file_id, options = {}) => { |
| return await File.findOne({ file_id, ...options }).lean(); |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| const getFiles = async (filter, _sortOptions, selectFields = { text: 0 }) => { |
| const sortOptions = { updatedAt: -1, ..._sortOptions }; |
| return await File.find(filter).select(selectFields).sort(sortOptions).lean(); |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| const getToolFilesByIds = async (fileIds, toolResourceSet) => { |
| if (!fileIds || !fileIds.length || !toolResourceSet?.size) { |
| return []; |
| } |
|
|
| try { |
| const filter = { |
| file_id: { $in: fileIds }, |
| $or: [], |
| }; |
|
|
| if (toolResourceSet.has(EToolResources.context)) { |
| filter.$or.push({ text: { $exists: true, $ne: null }, context: FileContext.agents }); |
| } |
| if (toolResourceSet.has(EToolResources.file_search)) { |
| filter.$or.push({ embedded: true }); |
| } |
| if (toolResourceSet.has(EToolResources.execute_code)) { |
| filter.$or.push({ 'metadata.fileIdentifier': { $exists: true } }); |
| } |
|
|
| const selectFields = { text: 0 }; |
| const sortOptions = { updatedAt: -1 }; |
|
|
| return await getFiles(filter, sortOptions, selectFields); |
| } catch (error) { |
| logger.error('[getToolFilesByIds] Error retrieving tool files:', error); |
| throw new Error('Error retrieving tool files'); |
| } |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| const createFile = async (data, disableTTL) => { |
| const fileData = { |
| ...data, |
| expiresAt: new Date(Date.now() + 3600 * 1000), |
| }; |
|
|
| if (disableTTL) { |
| delete fileData.expiresAt; |
| } |
|
|
| return await File.findOneAndUpdate({ file_id: data.file_id }, fileData, { |
| new: true, |
| upsert: true, |
| }).lean(); |
| }; |
|
|
| |
| |
| |
| |
| |
| const updateFile = async (data) => { |
| const { file_id, ...update } = data; |
| const updateOperation = { |
| $set: update, |
| $unset: { expiresAt: '' }, |
| }; |
| return await File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean(); |
| }; |
|
|
| |
| |
| |
| |
| |
| const updateFileUsage = async (data) => { |
| const { file_id, inc = 1 } = data; |
| const updateOperation = { |
| $inc: { usage: inc }, |
| $unset: { expiresAt: '', temp_file_id: '' }, |
| }; |
| return await File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean(); |
| }; |
|
|
| |
| |
| |
| |
| |
| const deleteFile = async (file_id) => { |
| return await File.findOneAndDelete({ file_id }).lean(); |
| }; |
|
|
| |
| |
| |
| |
| |
| const deleteFileByFilter = async (filter) => { |
| return await File.findOneAndDelete(filter).lean(); |
| }; |
|
|
| |
| |
| |
| |
| |
| const deleteFiles = async (file_ids, user) => { |
| let deleteQuery = { file_id: { $in: file_ids } }; |
| if (user) { |
| deleteQuery = { user: user }; |
| } |
| return await File.deleteMany(deleteQuery); |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| async function batchUpdateFiles(updates) { |
| if (!updates || updates.length === 0) { |
| return; |
| } |
|
|
| const bulkOperations = updates.map((update) => ({ |
| updateOne: { |
| filter: { file_id: update.file_id }, |
| update: { $set: { filepath: update.filepath } }, |
| }, |
| })); |
|
|
| const result = await File.bulkWrite(bulkOperations); |
| logger.info(`Updated ${result.modifiedCount} files with new S3 URLs`); |
| } |
|
|
| module.exports = { |
| findFileById, |
| getFiles, |
| getToolFilesByIds, |
| createFile, |
| updateFile, |
| updateFileUsage, |
| deleteFile, |
| deleteFiles, |
| deleteFileByFilter, |
| batchUpdateFiles, |
| }; |
|
|