🛠️ 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:
Danny Avila 2024-02-27 10:21:06 -05:00 committed by GitHub
parent 08d4b3cc8a
commit 04eeb59d47
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 98 additions and 57 deletions

View file

@ -447,6 +447,8 @@ class BaseClient {
}
const completion = await this.sendCompletion(payload, opts);
this.abortController.requestCompleted = true;
const responseMessage = {
messageId: responseMessageId,
conversationId,

View file

@ -67,7 +67,6 @@ function createLLM({
return new ChatOpenAI(
{
streaming,
verbose: true,
credentials,
configuration,
...azureOptions,

View file

@ -92,6 +92,20 @@ const AskController = async (req, res, next, initializeClient, addTitle) => {
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 = {
user,
parentMessageId,

View file

@ -90,6 +90,20 @@ const EditController = async (req, res, next, initializeClient) => {
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 {
const { client } = await initializeClient({ req, res, endpointOption });

View file

@ -39,6 +39,7 @@ router.post('/abort', handleAbort());
*/
router.post('/', validateModel, buildEndpointOption, setHeaders, async (req, res) => {
logger.debug('[/assistants/chat/] req.body', req.body);
const {
text,
model,
@ -96,7 +97,73 @@ router.post('/', validateModel, buildEndpointOption, setHeaders, async (req, res
const cache = getLogStores(CacheKeys.ABORT_KEYS);
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 {
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) {
throw new Error('Missing thread_id for existing conversation');
}
@ -318,62 +385,7 @@ router.post('/', validateModel, buildEndpointOption, setHeaders, async (req, res
});
}
} catch (error) {
if (error.message === 'Run cancelled') {
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' });
}
await handleError(error);
}
});