mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
ℹ️ refactor: Remove use of Agenda for Conversation Imports (#3024)
* chore: remove agenda and npm audit fix * refactor: import conversations without agenda * chore: update package-lock.json and data-provider version to 0.6.7 * fix: import conversations * chore: client npm audit fix
This commit is contained in:
parent
92232afaca
commit
2e559137ae
12 changed files with 52 additions and 402 deletions
|
|
@ -41,7 +41,6 @@
|
||||||
"@langchain/community": "^0.0.46",
|
"@langchain/community": "^0.0.46",
|
||||||
"@langchain/google-genai": "^0.0.11",
|
"@langchain/google-genai": "^0.0.11",
|
||||||
"@langchain/google-vertexai": "^0.0.17",
|
"@langchain/google-vertexai": "^0.0.17",
|
||||||
"agenda": "^5.0.0",
|
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,11 @@ const express = require('express');
|
||||||
const { CacheKeys } = require('librechat-data-provider');
|
const { CacheKeys } = require('librechat-data-provider');
|
||||||
const { initializeClient } = require('~/server/services/Endpoints/assistants');
|
const { initializeClient } = require('~/server/services/Endpoints/assistants');
|
||||||
const { getConvosByPage, deleteConvos, getConvo, saveConvo } = require('~/models/Conversation');
|
const { getConvosByPage, deleteConvos, getConvo, saveConvo } = require('~/models/Conversation');
|
||||||
const { IMPORT_CONVERSATION_JOB_NAME } = require('~/server/utils/import/jobDefinition');
|
|
||||||
const { storage, importFileFilter } = require('~/server/routes/files/multer');
|
const { storage, importFileFilter } = require('~/server/routes/files/multer');
|
||||||
const requireJwtAuth = require('~/server/middleware/requireJwtAuth');
|
const requireJwtAuth = require('~/server/middleware/requireJwtAuth');
|
||||||
const { forkConversation } = require('~/server/utils/import/fork');
|
const { forkConversation } = require('~/server/utils/import/fork');
|
||||||
|
const { importConversations } = require('~/server/utils/import');
|
||||||
const { createImportLimiters } = require('~/server/middleware');
|
const { createImportLimiters } = require('~/server/middleware');
|
||||||
const jobScheduler = require('~/server/utils/jobScheduler');
|
|
||||||
const getLogStores = require('~/cache/getLogStores');
|
const getLogStores = require('~/cache/getLogStores');
|
||||||
const { sleep } = require('~/server/utils');
|
const { sleep } = require('~/server/utils');
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('~/config');
|
||||||
|
|
@ -129,10 +128,9 @@ router.post(
|
||||||
upload.single('file'),
|
upload.single('file'),
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const filepath = req.file.path;
|
/* TODO: optimize to return imported conversations and add manually */
|
||||||
const job = await jobScheduler.now(IMPORT_CONVERSATION_JOB_NAME, filepath, req.user.id);
|
await importConversations({ filepath: req.file.path, requestUserId: req.user.id });
|
||||||
|
res.status(201).json({ message: 'Conversation(s) imported successfully' });
|
||||||
res.status(201).json({ message: 'Import started', jobId: job.id });
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error processing file', error);
|
logger.error('Error processing file', error);
|
||||||
res.status(500).send('Error processing file');
|
res.status(500).send('Error processing file');
|
||||||
|
|
@ -169,24 +167,4 @@ router.post('/fork', async (req, res) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get the status of an import job for polling
|
|
||||||
router.get('/import/jobs/:jobId', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { jobId } = req.params;
|
|
||||||
const { userId, ...jobStatus } = await jobScheduler.getJobStatus(jobId);
|
|
||||||
if (!jobStatus) {
|
|
||||||
return res.status(404).json({ message: 'Job not found.' });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userId !== req.user.id) {
|
|
||||||
return res.status(403).json({ message: 'Unauthorized' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(jobStatus);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('Error getting job details', error);
|
|
||||||
res.status(500).send('Error getting job details');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
const jobScheduler = require('~/server/utils/jobScheduler');
|
|
||||||
const { getImporter } = require('./importers');
|
const { getImporter } = require('./importers');
|
||||||
const { indexSync } = require('~/lib/db');
|
const { indexSync } = require('~/lib/db');
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('~/config');
|
||||||
|
|
||||||
const IMPORT_CONVERSATION_JOB_NAME = 'import conversation';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Job definition for importing a conversation.
|
* Job definition for importing a conversation.
|
||||||
* @param {import('agenda').Job} job - The job object.
|
* @param {{ filepath, requestUserId }} job - The job object.
|
||||||
* @param {Function} done - The done function.
|
|
||||||
*/
|
*/
|
||||||
const importConversationJob = async (job, done) => {
|
const importConversations = async (job) => {
|
||||||
const { filepath, requestUserId } = job.attrs.data;
|
const { filepath, requestUserId } = job;
|
||||||
try {
|
try {
|
||||||
logger.debug(`user: ${requestUserId} | Importing conversation(s) from file...`);
|
logger.debug(`user: ${requestUserId} | Importing conversation(s) from file...`);
|
||||||
const fileData = await fs.readFile(filepath, 'utf8');
|
const fileData = await fs.readFile(filepath, 'utf8');
|
||||||
|
|
@ -22,10 +18,8 @@ const importConversationJob = async (job, done) => {
|
||||||
// Sync Meilisearch index
|
// Sync Meilisearch index
|
||||||
await indexSync();
|
await indexSync();
|
||||||
logger.debug(`user: ${requestUserId} | Finished importing conversations`);
|
logger.debug(`user: ${requestUserId} | Finished importing conversations`);
|
||||||
done();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`user: ${requestUserId} | Failed to import conversation: `, error);
|
logger.error(`user: ${requestUserId} | Failed to import conversation: `, error);
|
||||||
done(error);
|
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
await fs.unlink(filepath);
|
await fs.unlink(filepath);
|
||||||
|
|
@ -35,7 +29,4 @@ const importConversationJob = async (job, done) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call the jobScheduler.define function at startup
|
module.exports = importConversations;
|
||||||
jobScheduler.define(IMPORT_CONVERSATION_JOB_NAME, importConversationJob);
|
|
||||||
|
|
||||||
module.exports = { IMPORT_CONVERSATION_JOB_NAME };
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
const importers = require('./importers');
|
const importers = require('./importers');
|
||||||
|
const importConversations = require('./importConversations');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...importers,
|
...importers,
|
||||||
|
importConversations,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
const Agenda = require('agenda');
|
|
||||||
const { logger } = require('~/config');
|
|
||||||
const mongodb = require('mongodb');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for scheduling and running jobs.
|
|
||||||
* The workflow is as follows: start the job scheduler, define a job, and then schedule the job using defined job name.
|
|
||||||
*/
|
|
||||||
class JobScheduler {
|
|
||||||
constructor() {
|
|
||||||
this.agenda = new Agenda({ db: { address: process.env.MONGO_URI } });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the job scheduler.
|
|
||||||
*/
|
|
||||||
async start() {
|
|
||||||
try {
|
|
||||||
logger.info('Starting Agenda...');
|
|
||||||
await this.agenda.start();
|
|
||||||
logger.info('Agenda successfully started and connected to MongoDB.');
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('Failed to start Agenda:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedules a job to start immediately.
|
|
||||||
* @param {string} jobName - The name of the job to schedule.
|
|
||||||
* @param {string} filepath - The filepath to pass to the job.
|
|
||||||
* @param {string} userId - The ID of the user requesting the job.
|
|
||||||
* @returns {Promise<{ id: string }>} - A promise that resolves with the ID of the scheduled job.
|
|
||||||
* @throws {Error} - If the job fails to schedule.
|
|
||||||
*/
|
|
||||||
async now(jobName, filepath, userId) {
|
|
||||||
try {
|
|
||||||
const job = await this.agenda.now(jobName, { filepath, requestUserId: userId });
|
|
||||||
logger.debug(`Job '${job.attrs.name}' scheduled successfully.`);
|
|
||||||
return { id: job.attrs._id.toString() };
|
|
||||||
} catch (error) {
|
|
||||||
throw new Error(`Failed to schedule job '${jobName}': ${error}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the status of a job.
|
|
||||||
* @param {string} jobId - The ID of the job to get the status of.
|
|
||||||
* @returns {Promise<{ id: string, userId: string, name: string, failReason: string, status: string } | null>} - A promise that resolves with the job status or null if the job is not found.
|
|
||||||
* @throws {Error} - If multiple jobs are found.
|
|
||||||
*/
|
|
||||||
async getJobStatus(jobId) {
|
|
||||||
const job = await this.agenda.jobs({ _id: new mongodb.ObjectId(jobId) });
|
|
||||||
if (!job || job.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (job.length > 1) {
|
|
||||||
// This should never happen
|
|
||||||
throw new Error('Multiple jobs found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const jobDetails = {
|
|
||||||
id: job[0]._id,
|
|
||||||
userId: job[0].attrs.data.requestUserId,
|
|
||||||
name: job[0].attrs.name,
|
|
||||||
failReason: job[0].attrs.failReason,
|
|
||||||
status: !job[0].attrs.lastRunAt
|
|
||||||
? 'scheduled'
|
|
||||||
: job[0].attrs.failedAt
|
|
||||||
? 'failed'
|
|
||||||
: job[0].attrs.lastFinishedAt
|
|
||||||
? 'completed'
|
|
||||||
: 'running',
|
|
||||||
};
|
|
||||||
|
|
||||||
return jobDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines a new job.
|
|
||||||
* @param {string} name - The name of the job.
|
|
||||||
* @param {Function} jobFunction - The function to run when the job is executed.
|
|
||||||
*/
|
|
||||||
define(name, jobFunction) {
|
|
||||||
this.agenda.define(name, async (job, done) => {
|
|
||||||
try {
|
|
||||||
await jobFunction(job, done);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(`Failed to run job '${name}': ${error}`);
|
|
||||||
done(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const jobScheduler = new JobScheduler();
|
|
||||||
jobScheduler.start();
|
|
||||||
|
|
||||||
module.exports = jobScheduler;
|
|
||||||
|
|
@ -71,7 +71,7 @@ function ImportConversations() {
|
||||||
<span>{localize('com_ui_import_conversation_info')}</span>
|
<span>{localize('com_ui_import_conversation_info')}</span>
|
||||||
<label
|
<label
|
||||||
htmlFor={'import-conversations-file'}
|
htmlFor={'import-conversations-file'}
|
||||||
className="flex h-auto cursor-pointer items-center rounded bg-transparent px-2 py-3 text-xs font-medium font-normal transition-colors hover:bg-gray-100 hover:text-green-700 dark:bg-transparent dark:text-white dark:hover:bg-gray-600 dark:hover:text-green-500"
|
className="flex h-auto cursor-pointer items-center rounded bg-transparent px-2 py-3 text-xs font-medium transition-colors hover:bg-gray-100 hover:text-green-700 dark:bg-transparent dark:text-white dark:hover:bg-gray-600 dark:hover:text-green-500"
|
||||||
>
|
>
|
||||||
{allowImport ? (
|
{allowImport ? (
|
||||||
<Import className="mr-1 flex h-4 w-4 items-center stroke-1" />
|
<Import className="mr-1 flex h-4 w-4 items-center stroke-1" />
|
||||||
|
|
|
||||||
|
|
@ -344,81 +344,18 @@ export const useForkConvoMutation = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUploadConversationsMutation = (
|
export const useUploadConversationsMutation = (
|
||||||
_options?: t.MutationOptions<t.TImportJobStatus, FormData>,
|
_options?: t.MutationOptions<t.TImportResponse, FormData>,
|
||||||
) => {
|
) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { onSuccess, onError, onMutate } = _options || {};
|
const { onSuccess, onError, onMutate } = _options || {};
|
||||||
|
|
||||||
// returns the job status or reason of failure
|
return useMutation<t.TImportResponse, unknown, FormData>({
|
||||||
const checkJobStatus = async (jobId) => {
|
|
||||||
try {
|
|
||||||
const response = await dataService.queryImportConversationJobStatus(jobId);
|
|
||||||
return response;
|
|
||||||
} catch (error) {
|
|
||||||
throw new Error('Failed to check job status');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Polls the job status until it is completed, failed, or timed out
|
|
||||||
const pollJobStatus = (jobId, onSuccess, onError) => {
|
|
||||||
let timeElapsed = 0;
|
|
||||||
const timeout = 60000; // Timeout after a minute
|
|
||||||
const pollInterval = 500; // Poll every 500ms
|
|
||||||
const intervalId = setInterval(async () => {
|
|
||||||
try {
|
|
||||||
const statusResponse = await checkJobStatus(jobId);
|
|
||||||
console.log('Polling job status', statusResponse);
|
|
||||||
if (statusResponse.status === 'completed' || statusResponse.status === 'failed') {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
if (statusResponse.status === 'completed') {
|
|
||||||
onSuccess && onSuccess(statusResponse);
|
|
||||||
} else {
|
|
||||||
onError &&
|
|
||||||
onError(
|
|
||||||
new Error(
|
|
||||||
statusResponse.failReason
|
|
||||||
? statusResponse.failReason
|
|
||||||
: 'Failed to import conversations',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timeElapsed += pollInterval; // Increment time elapsed by polling interval
|
|
||||||
if (timeElapsed >= timeout) {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
onError && onError(new Error('Polling timed out'));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
onError && onError(error);
|
|
||||||
}
|
|
||||||
}, pollInterval);
|
|
||||||
};
|
|
||||||
|
|
||||||
return useMutation<t.TImportStartResponse, unknown, FormData>({
|
|
||||||
mutationFn: (formData: FormData) => dataService.importConversationsFile(formData),
|
mutationFn: (formData: FormData) => dataService.importConversationsFile(formData),
|
||||||
onSuccess: (data, variables, context) => {
|
onSuccess: (data, variables, context) => {
|
||||||
|
/* TODO: optimize to return imported conversations and add manually */
|
||||||
queryClient.invalidateQueries([QueryKeys.allConversations]);
|
queryClient.invalidateQueries([QueryKeys.allConversations]);
|
||||||
// Assuming the job ID is in the response data
|
|
||||||
const jobId = data.jobId;
|
|
||||||
if (jobId) {
|
|
||||||
// Start polling for job status
|
|
||||||
pollJobStatus(
|
|
||||||
jobId,
|
|
||||||
(statusResponse) => {
|
|
||||||
// This is the final success callback when the job is completed
|
|
||||||
queryClient.invalidateQueries([QueryKeys.allConversations]); // Optionally refresh conversations query
|
|
||||||
if (onSuccess) {
|
if (onSuccess) {
|
||||||
onSuccess(statusResponse, variables, context);
|
onSuccess(data, variables, context);
|
||||||
}
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
// This is the error callback for job failure or polling errors
|
|
||||||
if (onError) {
|
|
||||||
onError(error, variables, context);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (err, variables, context) => {
|
onError: (err, variables, context) => {
|
||||||
|
|
|
||||||
179
package-lock.json
generated
179
package-lock.json
generated
|
|
@ -49,7 +49,6 @@
|
||||||
"@langchain/community": "^0.0.46",
|
"@langchain/community": "^0.0.46",
|
||||||
"@langchain/google-genai": "^0.0.11",
|
"@langchain/google-genai": "^0.0.11",
|
||||||
"@langchain/google-vertexai": "^0.0.17",
|
"@langchain/google-vertexai": "^0.0.17",
|
||||||
"agenda": "^5.0.0",
|
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
|
|
@ -10673,73 +10672,6 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/agenda": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/agenda/-/agenda-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-jOoa7PvARpst/y2PI8h0wph4NmcjYJ/4wzFhQcHUbNgN+Hte/9h/MzKE0ZmHfIwdsSlnv3rhbBQ3Zd/gwFkThg==",
|
|
||||||
"dependencies": {
|
|
||||||
"cron-parser": "^3.5.0",
|
|
||||||
"date.js": "~0.3.3",
|
|
||||||
"debug": "~4.3.4",
|
|
||||||
"human-interval": "~2.0.1",
|
|
||||||
"moment-timezone": "~0.5.37",
|
|
||||||
"mongodb": "^4.11.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/agenda/node_modules/bson": {
|
|
||||||
"version": "4.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz",
|
|
||||||
"integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"buffer": "^5.6.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/agenda/node_modules/buffer": {
|
|
||||||
"version": "5.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
|
||||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "patreon",
|
|
||||||
"url": "https://www.patreon.com/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "consulting",
|
|
||||||
"url": "https://feross.org/support"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"base64-js": "^1.3.1",
|
|
||||||
"ieee754": "^1.1.13"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/agenda/node_modules/mongodb": {
|
|
||||||
"version": "4.17.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.17.2.tgz",
|
|
||||||
"integrity": "sha512-mLV7SEiov2LHleRJPMPrK2PMyhXFZt2UQLC4VD4pnth3jMjYKHhtqfwwkkvS/NXuo/Fp3vbhaNcXrIDaLRb9Tg==",
|
|
||||||
"dependencies": {
|
|
||||||
"bson": "^4.7.2",
|
|
||||||
"mongodb-connection-string-url": "^2.6.0",
|
|
||||||
"socks": "^2.7.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.9.0"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"@aws-sdk/credential-providers": "^3.186.0",
|
|
||||||
"@mongodb-js/saslprep": "^1.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/agent-base": {
|
"node_modules/agent-base": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
|
|
@ -12909,18 +12841,6 @@
|
||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/cron-parser": {
|
|
||||||
"version": "3.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.5.0.tgz",
|
|
||||||
"integrity": "sha512-wyVZtbRs6qDfFd8ap457w3XVntdvqcwBGxBoTvJQH9KGVKL/fB+h2k3C8AqiVxvUQKN1Ps/Ns46CNViOpVDhfQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"is-nan": "^1.3.2",
|
|
||||||
"luxon": "^1.26.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cross-env": {
|
"node_modules/cross-env": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||||
|
|
@ -13171,27 +13091,6 @@
|
||||||
"url": "https://github.com/sponsors/kossnocorp"
|
"url": "https://github.com/sponsors/kossnocorp"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/date.js": {
|
|
||||||
"version": "0.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/date.js/-/date.js-0.3.3.tgz",
|
|
||||||
"integrity": "sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==",
|
|
||||||
"dependencies": {
|
|
||||||
"debug": "~3.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/date.js/node_modules/debug": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
|
||||||
"dependencies": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/date.js/node_modules/ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
|
||||||
},
|
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
|
|
@ -13351,6 +13250,7 @@
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
|
||||||
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"define-data-property": "^1.0.1",
|
"define-data-property": "^1.0.1",
|
||||||
"has-property-descriptors": "^1.0.0",
|
"has-property-descriptors": "^1.0.0",
|
||||||
|
|
@ -13668,9 +13568,9 @@
|
||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||||
},
|
},
|
||||||
"node_modules/ejs": {
|
"node_modules/ejs": {
|
||||||
"version": "3.1.9",
|
"version": "3.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||||
"integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
|
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jake": "^10.8.5"
|
"jake": "^10.8.5"
|
||||||
|
|
@ -16533,14 +16433,6 @@
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/human-interval": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/human-interval/-/human-interval-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-r4Aotzf+OtKIGQCB3odUowy4GfUDTy3aTWTfLd7ZF2gBCy3XW3v/dJLRefZnOFFnjqs5B1TypvS8WarpBkYUNQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"numbered": "^1.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/human-signals": {
|
"node_modules/human-signals": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
|
|
@ -17071,10 +16963,22 @@
|
||||||
"url": "https://opencollective.com/ioredis"
|
"url": "https://opencollective.com/ioredis"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ip": {
|
"node_modules/ip-address": {
|
||||||
"version": "2.0.1",
|
"version": "9.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
|
||||||
"integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ=="
|
"integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
|
||||||
|
"dependencies": {
|
||||||
|
"jsbn": "1.1.0",
|
||||||
|
"sprintf-js": "^1.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ip-address/node_modules/sprintf-js": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="
|
||||||
},
|
},
|
||||||
"node_modules/ipaddr.js": {
|
"node_modules/ipaddr.js": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
|
|
@ -17350,6 +17254,7 @@
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz",
|
||||||
"integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==",
|
"integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.0",
|
"call-bind": "^1.0.0",
|
||||||
"define-properties": "^1.1.3"
|
"define-properties": "^1.1.3"
|
||||||
|
|
@ -18527,6 +18432,11 @@
|
||||||
"js-yaml": "bin/js-yaml.js"
|
"js-yaml": "bin/js-yaml.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jsbn": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
|
||||||
|
},
|
||||||
"node_modules/jsdom": {
|
"node_modules/jsdom": {
|
||||||
"version": "20.0.3",
|
"version": "20.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz",
|
||||||
|
|
@ -19758,14 +19668,6 @@
|
||||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0"
|
"react": "^16.5.1 || ^17.0.0 || ^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/luxon": {
|
|
||||||
"version": "1.28.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz",
|
|
||||||
"integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==",
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/lz-string": {
|
"node_modules/lz-string": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
|
||||||
|
|
@ -20919,17 +20821,6 @@
|
||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/moment-timezone": {
|
|
||||||
"version": "0.5.45",
|
|
||||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz",
|
|
||||||
"integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"moment": "^2.29.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mongodb": {
|
"node_modules/mongodb": {
|
||||||
"version": "5.9.2",
|
"version": "5.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz",
|
||||||
|
|
@ -21577,11 +21468,6 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/numbered": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-pv/ue2Odr7IfYOO0byC1KgBI10wo5YDauLhxY6/saNzAdAs0r1SotGCPzzCLNPL0xtrAwWRialLu23AAu9xO1g=="
|
|
||||||
},
|
|
||||||
"node_modules/nwsapi": {
|
"node_modules/nwsapi": {
|
||||||
"version": "2.2.7",
|
"version": "2.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
|
||||||
|
|
@ -21637,6 +21523,7 @@
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||||
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
|
|
@ -25849,15 +25736,15 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/socks": {
|
"node_modules/socks": {
|
||||||
"version": "2.7.1",
|
"version": "2.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
|
||||||
"integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
|
"integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ip": "^2.0.0",
|
"ip-address": "^9.0.5",
|
||||||
"smart-buffer": "^4.2.0"
|
"smart-buffer": "^4.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10.13.0",
|
"node": ">= 10.0.0",
|
||||||
"npm": ">= 3.0.0"
|
"npm": ">= 3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -29432,7 +29319,7 @@
|
||||||
},
|
},
|
||||||
"packages/data-provider": {
|
"packages/data-provider": {
|
||||||
"name": "librechat-data-provider",
|
"name": "librechat-data-provider",
|
||||||
"version": "0.6.6",
|
"version": "0.6.7",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/js-yaml": "^4.0.9",
|
"@types/js-yaml": "^4.0.9",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "librechat-data-provider",
|
"name": "librechat-data-provider",
|
||||||
"version": "0.6.6",
|
"version": "0.6.7",
|
||||||
"description": "data services for librechat apps",
|
"description": "data services for librechat apps",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"module": "dist/index.es.js",
|
"module": "dist/index.es.js",
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,6 @@ export const importConversation = () => `${conversationsRoot}/import`;
|
||||||
|
|
||||||
export const forkConversation = () => `${conversationsRoot}/fork`;
|
export const forkConversation = () => `${conversationsRoot}/fork`;
|
||||||
|
|
||||||
export const importConversationJobStatus = (jobId: string) =>
|
|
||||||
`${conversationsRoot}/import/jobs/${jobId}`;
|
|
||||||
|
|
||||||
export const search = (q: string, pageNumber: string) =>
|
export const search = (q: string, pageNumber: string) =>
|
||||||
`/api/search?q=${q}&pageNumber=${pageNumber}`;
|
`/api/search?q=${q}&pageNumber=${pageNumber}`;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -305,22 +305,10 @@ export const uploadFile = (data: FormData): Promise<f.TFileUpload> => {
|
||||||
* @param data - The FormData containing the file to import.
|
* @param data - The FormData containing the file to import.
|
||||||
* @returns A Promise that resolves to the import start response.
|
* @returns A Promise that resolves to the import start response.
|
||||||
*/
|
*/
|
||||||
export const importConversationsFile = (data: FormData): Promise<t.TImportStartResponse> => {
|
export const importConversationsFile = (data: FormData): Promise<t.TImportResponse> => {
|
||||||
return request.postMultiPart(endpoints.importConversation(), data);
|
return request.postMultiPart(endpoints.importConversation(), data);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the status of an import conversation job.
|
|
||||||
*
|
|
||||||
* @param jobId - The ID of the import conversation job.
|
|
||||||
* @returns A promise that resolves to the import job status.
|
|
||||||
*/
|
|
||||||
export const queryImportConversationJobStatus = async (
|
|
||||||
jobId: string,
|
|
||||||
): Promise<t.TImportJobStatus> => {
|
|
||||||
return request.get(endpoints.importConversationJobStatus(jobId));
|
|
||||||
};
|
|
||||||
|
|
||||||
export const uploadAvatar = (data: FormData): Promise<f.AvatarUploadResponse> => {
|
export const uploadAvatar = (data: FormData): Promise<f.AvatarUploadResponse> => {
|
||||||
return request.postMultiPart(endpoints.avatar(), data);
|
return request.postMultiPart(endpoints.avatar(), data);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -315,39 +315,9 @@ export type TRequestPasswordResetResponse = {
|
||||||
/**
|
/**
|
||||||
* Represents the response from the import endpoint.
|
* Represents the response from the import endpoint.
|
||||||
*/
|
*/
|
||||||
export type TImportStartResponse = {
|
export type TImportResponse = {
|
||||||
/**
|
/**
|
||||||
* The message associated with the response.
|
* The message associated with the response.
|
||||||
*/
|
*/
|
||||||
message: string;
|
message: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* The ID of the job associated with the import.
|
|
||||||
*/
|
|
||||||
jobId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the status of an import job.
|
|
||||||
*/
|
|
||||||
export type TImportJobStatus = {
|
|
||||||
/**
|
|
||||||
* The name of the job.
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ID of the job.
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The status of the job.
|
|
||||||
*/
|
|
||||||
status: 'scheduled' | 'running' | 'completed' | 'failed';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The reason the job failed, if applicable.
|
|
||||||
*/
|
|
||||||
failReason?: string;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue