mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
🛠️ chore: Abort AI Requests on Close & Remove Verbose Logs for Plugins (#1914)
* chore: remove verbose logging of ChatOpenAI * feat: abort AI requests on request close
This commit is contained in:
parent
08d4b3cc8a
commit
04eeb59d47
5 changed files with 98 additions and 57 deletions
|
|
@ -447,6 +447,8 @@ class BaseClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
const completion = await this.sendCompletion(payload, opts);
|
const completion = await this.sendCompletion(payload, opts);
|
||||||
|
this.abortController.requestCompleted = true;
|
||||||
|
|
||||||
const responseMessage = {
|
const responseMessage = {
|
||||||
messageId: responseMessageId,
|
messageId: responseMessageId,
|
||||||
conversationId,
|
conversationId,
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@ function createLLM({
|
||||||
return new ChatOpenAI(
|
return new ChatOpenAI(
|
||||||
{
|
{
|
||||||
streaming,
|
streaming,
|
||||||
verbose: true,
|
|
||||||
credentials,
|
credentials,
|
||||||
configuration,
|
configuration,
|
||||||
...azureOptions,
|
...azureOptions,
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,20 @@ const AskController = async (req, res, next, initializeClient, addTitle) => {
|
||||||
|
|
||||||
const { abortController, onStart } = createAbortController(req, res, getAbortData);
|
const { abortController, onStart } = createAbortController(req, res, getAbortData);
|
||||||
|
|
||||||
|
res.on('close', () => {
|
||||||
|
logger.debug('[AskController] Request closed');
|
||||||
|
if (!abortController) {
|
||||||
|
return;
|
||||||
|
} else if (abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
} else if (abortController.requestCompleted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
abortController.abort();
|
||||||
|
logger.debug('[AskController] Request aborted on close');
|
||||||
|
});
|
||||||
|
|
||||||
const messageOptions = {
|
const messageOptions = {
|
||||||
user,
|
user,
|
||||||
parentMessageId,
|
parentMessageId,
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,20 @@ const EditController = async (req, res, next, initializeClient) => {
|
||||||
|
|
||||||
const { abortController, onStart } = createAbortController(req, res, getAbortData);
|
const { abortController, onStart } = createAbortController(req, res, getAbortData);
|
||||||
|
|
||||||
|
res.on('close', () => {
|
||||||
|
logger.debug('[EditController] Request closed');
|
||||||
|
if (!abortController) {
|
||||||
|
return;
|
||||||
|
} else if (abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
} else if (abortController.requestCompleted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
abortController.abort();
|
||||||
|
logger.debug('[EditController] Request aborted on close');
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { client } = await initializeClient({ req, res, endpointOption });
|
const { client } = await initializeClient({ req, res, endpointOption });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ router.post('/abort', handleAbort());
|
||||||
*/
|
*/
|
||||||
router.post('/', validateModel, buildEndpointOption, setHeaders, async (req, res) => {
|
router.post('/', validateModel, buildEndpointOption, setHeaders, async (req, res) => {
|
||||||
logger.debug('[/assistants/chat/] req.body', req.body);
|
logger.debug('[/assistants/chat/] req.body', req.body);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
text,
|
text,
|
||||||
model,
|
model,
|
||||||
|
|
@ -96,7 +97,73 @@ router.post('/', validateModel, buildEndpointOption, setHeaders, async (req, res
|
||||||
const cache = getLogStores(CacheKeys.ABORT_KEYS);
|
const cache = getLogStores(CacheKeys.ABORT_KEYS);
|
||||||
const cacheKey = `${req.user.id}:${conversationId}`;
|
const cacheKey = `${req.user.id}:${conversationId}`;
|
||||||
|
|
||||||
|
const handleError = async (error) => {
|
||||||
|
if (error.message === 'Run cancelled') {
|
||||||
|
return res.end();
|
||||||
|
}
|
||||||
|
if (error.message === 'Request closed') {
|
||||||
|
logger.debug('[/assistants/chat/] Request aborted on close');
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error('[/assistants/chat/]', error);
|
||||||
|
|
||||||
|
if (!openai || !thread_id || !run_id) {
|
||||||
|
return res.status(500).json({ error: 'The Assistant run failed to initialize' });
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await cache.delete(cacheKey);
|
||||||
|
const cancelledRun = await openai.beta.threads.runs.cancel(thread_id, run_id);
|
||||||
|
logger.debug('Cancelled run:', cancelledRun);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[abortRun] Error cancelling run', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
await sleep(2000);
|
||||||
|
try {
|
||||||
|
const run = await openai.beta.threads.runs.retrieve(thread_id, run_id);
|
||||||
|
await recordUsage({
|
||||||
|
...run.usage,
|
||||||
|
model: run.model,
|
||||||
|
user: req.user.id,
|
||||||
|
conversationId,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[/assistants/chat/] Error fetching or processing run', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const runMessages = await checkMessageGaps({
|
||||||
|
openai,
|
||||||
|
run_id,
|
||||||
|
thread_id,
|
||||||
|
conversationId,
|
||||||
|
latestMessageId: responseMessageId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const finalEvent = {
|
||||||
|
title: 'New Chat',
|
||||||
|
final: true,
|
||||||
|
conversation: await getConvo(req.user.id, conversationId),
|
||||||
|
runMessages,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (res.headersSent && finalEvent) {
|
||||||
|
return sendMessage(res, finalEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(finalEvent);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[/assistants/chat/] Error finalizing error process', error);
|
||||||
|
return res.status(500).json({ error: 'The Assistant run failed' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
res.on('close', async () => {
|
||||||
|
await handleError(new Error('Request closed'));
|
||||||
|
});
|
||||||
|
|
||||||
if (convoId && !_thread_id) {
|
if (convoId && !_thread_id) {
|
||||||
throw new Error('Missing thread_id for existing conversation');
|
throw new Error('Missing thread_id for existing conversation');
|
||||||
}
|
}
|
||||||
|
|
@ -318,62 +385,7 @@ router.post('/', validateModel, buildEndpointOption, setHeaders, async (req, res
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.message === 'Run cancelled') {
|
await handleError(error);
|
||||||
return res.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.error('[/assistants/chat/]', error);
|
|
||||||
|
|
||||||
if (!openai || !thread_id || !run_id) {
|
|
||||||
return res.status(500).json({ error: 'The Assistant run failed to initialize' });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await cache.delete(cacheKey);
|
|
||||||
const cancelledRun = await openai.beta.threads.runs.cancel(thread_id, run_id);
|
|
||||||
logger.debug('Cancelled run:', cancelledRun);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('[abortRun] Error cancelling run', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
await sleep(2000);
|
|
||||||
try {
|
|
||||||
const run = await openai.beta.threads.runs.retrieve(thread_id, run_id);
|
|
||||||
await recordUsage({
|
|
||||||
...run.usage,
|
|
||||||
model: run.model,
|
|
||||||
user: req.user.id,
|
|
||||||
conversationId,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('[/assistants/chat/] Error fetching or processing run', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const runMessages = await checkMessageGaps({
|
|
||||||
openai,
|
|
||||||
run_id,
|
|
||||||
thread_id,
|
|
||||||
conversationId,
|
|
||||||
latestMessageId: responseMessageId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const finalEvent = {
|
|
||||||
title: 'New Chat',
|
|
||||||
final: true,
|
|
||||||
conversation: await getConvo(req.user.id, conversationId),
|
|
||||||
runMessages,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (res.headersSent && finalEvent) {
|
|
||||||
return sendMessage(res, finalEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(finalEvent);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('[/assistants/chat/] Error finalizing error process', error);
|
|
||||||
return res.status(500).json({ error: 'The Assistant run failed' });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue