mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🧠 refactor: Memory Timeout after Completion and Guarantee Stream Final Event (#8955)
This commit is contained in:
parent
4eeadddfe6
commit
0c9284c8ae
2 changed files with 54 additions and 10 deletions
|
|
@ -402,6 +402,34 @@ class AgentClient extends BaseClient {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a promise that resolves with the memory promise result or undefined after a timeout
|
||||||
|
* @param {Promise<(TAttachment | null)[] | undefined>} memoryPromise - The memory promise to await
|
||||||
|
* @param {number} timeoutMs - Timeout in milliseconds (default: 3000)
|
||||||
|
* @returns {Promise<(TAttachment | null)[] | undefined>}
|
||||||
|
*/
|
||||||
|
async awaitMemoryWithTimeout(memoryPromise, timeoutMs = 3000) {
|
||||||
|
if (!memoryPromise) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const timeoutPromise = new Promise((_, reject) =>
|
||||||
|
setTimeout(() => reject(new Error('Memory processing timeout')), timeoutMs),
|
||||||
|
);
|
||||||
|
|
||||||
|
const attachments = await Promise.race([memoryPromise, timeoutPromise]);
|
||||||
|
return attachments;
|
||||||
|
} catch (error) {
|
||||||
|
if (error.message === 'Memory processing timeout') {
|
||||||
|
logger.warn('[AgentClient] Memory processing timed out after 3 seconds');
|
||||||
|
} else {
|
||||||
|
logger.error('[AgentClient] Error processing memory:', error);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Promise<string | undefined>}
|
* @returns {Promise<string | undefined>}
|
||||||
*/
|
*/
|
||||||
|
|
@ -1002,12 +1030,10 @@ class AgentClient extends BaseClient {
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (memoryPromise) {
|
const attachments = await this.awaitMemoryWithTimeout(memoryPromise);
|
||||||
const attachments = await memoryPromise;
|
|
||||||
if (attachments && attachments.length > 0) {
|
if (attachments && attachments.length > 0) {
|
||||||
this.artifactPromises.push(...attachments);
|
this.artifactPromises.push(...attachments);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
await this.recordCollectedUsage({ context: 'message' });
|
await this.recordCollectedUsage({ context: 'message' });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|
@ -1016,12 +1042,10 @@ class AgentClient extends BaseClient {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (memoryPromise) {
|
const attachments = await this.awaitMemoryWithTimeout(memoryPromise);
|
||||||
const attachments = await memoryPromise;
|
|
||||||
if (attachments && attachments.length > 0) {
|
if (attachments && attachments.length > 0) {
|
||||||
this.artifactPromises.push(...attachments);
|
this.artifactPromises.push(...attachments);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
logger.error(
|
logger.error(
|
||||||
'[api/server/controllers/agents/client.js #sendCompletion] Operation aborted',
|
'[api/server/controllers/agents/client.js #sendCompletion] Operation aborted',
|
||||||
err,
|
err,
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,26 @@ const AgentController = async (req, res, next, initializeClient, addTitle) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Edge case: sendMessage completed but abort happened during sendCompletion
|
||||||
|
// We need to ensure a final event is sent
|
||||||
|
else if (!res.headersSent && !res.finished) {
|
||||||
|
logger.debug(
|
||||||
|
'[AgentController] Handling edge case: `sendMessage` completed but aborted during `sendCompletion`',
|
||||||
|
);
|
||||||
|
|
||||||
|
const finalResponse = { ...response };
|
||||||
|
finalResponse.error = true;
|
||||||
|
|
||||||
|
sendEvent(res, {
|
||||||
|
final: true,
|
||||||
|
conversation,
|
||||||
|
title: conversation.title,
|
||||||
|
requestMessage: userMessage,
|
||||||
|
responseMessage: finalResponse,
|
||||||
|
error: { message: 'Request was aborted during completion' },
|
||||||
|
});
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
|
||||||
// Save user message if needed
|
// Save user message if needed
|
||||||
if (!client.skipSaveUserMessage) {
|
if (!client.skipSaveUserMessage) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue