mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-15 15:08:10 +01:00
* 🐛 fix: Prevent deleted conversations from being recreated by async title generation
When a user deletes a chat while auto-generated title is still in progress,
`saveConvo` with `upsert: true` recreates the deleted conversation as a ghost
entry with only a title and no messages. This adds a `noUpsert` metadata option
to `saveConvo` and uses it in both agent and assistant title generation paths,
so the title save is skipped if the conversation no longer exists.
* test: conversation creation logic with noUpsert option
Added new tests to validate the behavior of the `saveConvo` function with the `noUpsert` option. This includes scenarios where a conversation should not be created if it doesn't exist, updating an existing conversation when `noUpsert` is true, and ensuring that upsert behavior remains the default when `noUpsert` is not provided. These changes improve the flexibility and reliability of conversation management.
* test: Clean up Conversation.spec.js by removing commented-out code
Removed unnecessary comments from the Conversation.spec.js test file to improve readability and maintainability. This includes comments related to database verification and temporary conversation handling, streamlining the test cases for better clarity.
89 lines
2.7 KiB
JavaScript
89 lines
2.7 KiB
JavaScript
const { isEnabled, sanitizeTitle } = require('@librechat/api');
|
|
const { logger } = require('@librechat/data-schemas');
|
|
const { CacheKeys } = require('librechat-data-provider');
|
|
const { saveConvo } = require('~/models/Conversation');
|
|
const getLogStores = require('~/cache/getLogStores');
|
|
const initializeClient = require('./initalize');
|
|
|
|
/**
|
|
* Generates a conversation title using OpenAI SDK
|
|
* @param {Object} params
|
|
* @param {OpenAI} params.openai - The OpenAI SDK client instance
|
|
* @param {string} params.text - User's message text
|
|
* @param {string} params.responseText - Assistant's response text
|
|
* @returns {Promise<string>}
|
|
*/
|
|
const generateTitle = async ({ openai, text, responseText }) => {
|
|
const titlePrompt = `Please generate a concise title (max 40 characters) for a conversation that starts with:
|
|
User: ${text}
|
|
Assistant: ${responseText}
|
|
|
|
Title:`;
|
|
|
|
const completion = await openai.chat.completions.create({
|
|
model: 'gpt-3.5-turbo',
|
|
messages: [
|
|
{
|
|
role: 'user',
|
|
content: titlePrompt,
|
|
},
|
|
],
|
|
temperature: 0.7,
|
|
max_tokens: 20,
|
|
});
|
|
|
|
const title = completion.choices[0]?.message?.content?.trim() || 'New conversation';
|
|
return sanitizeTitle(title);
|
|
};
|
|
|
|
/**
|
|
* Adds a title to a conversation asynchronously
|
|
* @param {ServerRequest} req
|
|
* @param {Object} params
|
|
* @param {string} params.text - User's message text
|
|
* @param {string} params.responseText - Assistant's response text
|
|
* @param {string} params.conversationId - Conversation ID
|
|
*/
|
|
const addTitle = async (req, { text, responseText, conversationId }) => {
|
|
const { TITLE_CONVO = 'true' } = process.env ?? {};
|
|
if (!isEnabled(TITLE_CONVO)) {
|
|
return;
|
|
}
|
|
|
|
// Skip title generation for temporary conversations
|
|
if (req?.body?.isTemporary) {
|
|
return;
|
|
}
|
|
|
|
const titleCache = getLogStores(CacheKeys.GEN_TITLE);
|
|
const key = `${req.user.id}-${conversationId}`;
|
|
|
|
try {
|
|
const { openai } = await initializeClient({ req });
|
|
const title = await generateTitle({ openai, text, responseText });
|
|
await titleCache.set(key, title, 120000);
|
|
|
|
await saveConvo(
|
|
req,
|
|
{
|
|
conversationId,
|
|
title,
|
|
},
|
|
{ context: 'api/server/services/Endpoints/assistants/addTitle.js', noUpsert: true },
|
|
);
|
|
} catch (error) {
|
|
logger.error('[addTitle] Error generating title:', error);
|
|
const fallbackTitle = text.length > 40 ? text.substring(0, 37) + '...' : text;
|
|
await titleCache.set(key, fallbackTitle, 120000);
|
|
await saveConvo(
|
|
req,
|
|
{
|
|
conversationId,
|
|
title: fallbackTitle,
|
|
},
|
|
{ context: 'api/server/services/Endpoints/assistants/addTitle.js', noUpsert: true },
|
|
);
|
|
}
|
|
};
|
|
|
|
module.exports = addTitle;
|