mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-16 16:30:15 +01:00
⬇️ feat: Assistant File Downloads (#2234)
* WIP: basic route for file downloads and file strategy for generating readablestream to pipe as res * chore(DALLE3): add typing for OpenAI client * chore: add `CONSOLE_JSON` notes to dotenv.md * WIP: first pass OpenAI Assistants File Output handling * feat: first pass assistants output file download from openai * chore: yml vs. yaml variation to .gitignore for `librechat.yml` * refactor(retrieveAndProcessFile): remove redundancies * fix(syncMessages): explicit sort of apiMessages to fix message order on abort * chore: add logs for warnings and errors, show toast on frontend * chore: add logger where console was still being used
This commit is contained in:
parent
7945fea0f9
commit
a00756c469
27 changed files with 555 additions and 248 deletions
|
|
@ -2,9 +2,10 @@ const fs = require('fs');
|
|||
const path = require('path');
|
||||
const axios = require('axios');
|
||||
const fetch = require('node-fetch');
|
||||
const { ref, uploadBytes, getDownloadURL, deleteObject } = require('firebase/storage');
|
||||
const { ref, uploadBytes, getDownloadURL, getStream, deleteObject } = require('firebase/storage');
|
||||
const { getBufferMetadata } = require('~/server/utils');
|
||||
const { getFirebaseStorage } = require('./initialize');
|
||||
const { logger } = require('~/config');
|
||||
|
||||
/**
|
||||
* Deletes a file from Firebase Storage.
|
||||
|
|
@ -15,7 +16,7 @@ const { getFirebaseStorage } = require('./initialize');
|
|||
async function deleteFile(basePath, fileName) {
|
||||
const storage = getFirebaseStorage();
|
||||
if (!storage) {
|
||||
console.error('Firebase is not initialized. Cannot delete file from Firebase Storage.');
|
||||
logger.error('Firebase is not initialized. Cannot delete file from Firebase Storage.');
|
||||
throw new Error('Firebase is not initialized');
|
||||
}
|
||||
|
||||
|
|
@ -23,9 +24,9 @@ async function deleteFile(basePath, fileName) {
|
|||
|
||||
try {
|
||||
await deleteObject(storageRef);
|
||||
console.log('File deleted successfully from Firebase Storage');
|
||||
logger.debug('File deleted successfully from Firebase Storage');
|
||||
} catch (error) {
|
||||
console.error('Error deleting file from Firebase Storage:', error.message);
|
||||
logger.error('Error deleting file from Firebase Storage:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +52,7 @@ async function deleteFile(basePath, fileName) {
|
|||
async function saveURLToFirebase({ userId, URL, fileName, basePath = 'images' }) {
|
||||
const storage = getFirebaseStorage();
|
||||
if (!storage) {
|
||||
console.error('Firebase is not initialized. Cannot save file to Firebase Storage.');
|
||||
logger.error('Firebase is not initialized. Cannot save file to Firebase Storage.');
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +64,7 @@ async function saveURLToFirebase({ userId, URL, fileName, basePath = 'images' })
|
|||
await uploadBytes(storageRef, buffer);
|
||||
return await getBufferMetadata(buffer);
|
||||
} catch (error) {
|
||||
console.error('Error uploading file to Firebase Storage:', error.message);
|
||||
logger.error('Error uploading file to Firebase Storage:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +88,7 @@ async function saveURLToFirebase({ userId, URL, fileName, basePath = 'images' })
|
|||
async function getFirebaseURL({ fileName, basePath = 'images' }) {
|
||||
const storage = getFirebaseStorage();
|
||||
if (!storage) {
|
||||
console.error('Firebase is not initialized. Cannot get image URL from Firebase Storage.');
|
||||
logger.error('Firebase is not initialized. Cannot get image URL from Firebase Storage.');
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +97,7 @@ async function getFirebaseURL({ fileName, basePath = 'images' }) {
|
|||
try {
|
||||
return await getDownloadURL(storageRef);
|
||||
} catch (error) {
|
||||
console.error('Error fetching file URL from Firebase Storage:', error.message);
|
||||
logger.error('Error fetching file URL from Firebase Storage:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -212,6 +213,26 @@ async function uploadFileToFirebase({ req, file, file_id }) {
|
|||
return { filepath: downloadURL, bytes };
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a readable stream for a file from Firebase storage.
|
||||
*
|
||||
* @param {string} filepath - The filepath.
|
||||
* @returns {ReadableStream} A readable stream of the file.
|
||||
*/
|
||||
function getFirebaseFileStream(filepath) {
|
||||
try {
|
||||
const storage = getFirebaseStorage();
|
||||
if (!storage) {
|
||||
throw new Error('Firebase is not initialized');
|
||||
}
|
||||
const fileRef = ref(storage, filepath);
|
||||
return getStream(fileRef);
|
||||
} catch (error) {
|
||||
logger.error('Error getting Firebase file stream:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
deleteFile,
|
||||
getFirebaseURL,
|
||||
|
|
@ -219,4 +240,5 @@ module.exports = {
|
|||
deleteFirebaseFile,
|
||||
uploadFileToFirebase,
|
||||
saveBufferToFirebase,
|
||||
getFirebaseFileStream,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue