Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- src/modules/aifn/autotitle/autoTitle.ts весь файл
- import { aixChatGenerateText_Simple } from '~/modules/aix/client/aix.client';
- import { excludeSystemMessages } from '~/common/stores/chat/chat.conversation';
- import { getConversation, useChatStore } from '~/common/stores/chat/store-chats';
- import { getDomainModelIdOrThrow } from '~/common/stores/llms/store-llms';
- import { messageFragmentsReduceText } from '~/common/stores/chat/chat.message';
- /**
- * Creates the AI titles for conversations, by taking snippets of recent messages and asking AI what's that about.
- * @returns true if the title was actually replaced (for instance, it may not be needed)
- */
- export async function autoConversationTitle(conversationId: string, forceReplace: boolean): Promise<boolean> {
- // use valid fast model
- let autoTitleLlmId;
- try {
- autoTitleLlmId = getDomainModelIdOrThrow(['fastUtil'], false, false, 'conversation-titler');
- } catch (error) {
- console.log(`autoConversationTitle: ${error}`);
- return false;
- }
- // only operate on valid conversations, without any title
- const conversation = getConversation(conversationId);
- if (!conversation || (!forceReplace && (conversation.autoTitle || conversation.userTitle)))
- return false;
- const { setAutoTitle, setUserTitle } = useChatStore.getState();
- if (forceReplace) {
- setUserTitle(conversationId, '');
- setAutoTitle(conversationId, '✏️...');
- }
- // --- MODIFICATION START ---
- const MAX_MESSAGES_TO_CONSIDER = 5; // How many of the latest messages to look at
- const MAX_CHARS_PER_MESSAGE_SNIPPET = 3500; // Max characters to take from each message
- const messagesToProcess = excludeSystemMessages(conversation.messages).slice(-MAX_MESSAGES_TO_CONSIDER);
- const historyLines: string[] = messagesToProcess.map(m => {
- const rolePrefix = m.role === 'user' ? 'You' : 'Assistant';
- let messageText = messageFragmentsReduceText(m.fragments).trim(); // Get full message text and trim whitespace
- // Truncate the message text if it's longer than our desired snippet length
- if (messageText.length > MAX_CHARS_PER_MESSAGE_SNIPPET) {
- messageText = messageText.substring(0, MAX_CHARS_PER_MESSAGE_SNIPPET) + '...';
- }
- // Replace newlines within the snippet with spaces to make it a single "line" for the LLM prompt
- // This helps keep the input format clean and prevents the LLM from misinterpreting parts of a single message as separate messages.
- messageText = messageText.replace(/\n+/g, ' ');
- return `- ${rolePrefix}: ${messageText}`;
- });
- // --- MODIFICATION END ---
- // If no history lines could be generated (e.g., all considered messages were empty)
- if (historyLines.length === 0 && messagesToProcess.length > 0) {
- // This case might happen if all messages were empty strings after processing.
- // Or if messagesToProcess was empty to begin with.
- console.log('autoConversationTitle: No history lines generated for LLM, though messages were present or none to process.');
- if (forceReplace) setAutoTitle(conversationId, ''); // Clear the "✏️..."
- return false;
- }
- // If there were no messages to process at all
- if (messagesToProcess.length === 0) {
- console.log('autoConversationTitle: No messages to process for title generation.');
- if (forceReplace) setAutoTitle(conversationId, '');
- return false;
- }
- try {
- // LLM chat-generate call
- // Adjusted the prompt to reflect that we are sending "snippets" which might be truncated.
- let title = await aixChatGenerateText_Simple(
- autoTitleLlmId,
- 'You are an AI Conversation Titles Assistant, an expert in creating CLEAR, INFORMATIVE, and EASILY SEARCHABLE chat titles.',
- `Your primary goal is to craft a title that not only summarizes the core subject but also makes the chat easily identifiable and searchable among many others. The title field is limited, so conciseness is crucial.
- Analyze the given conversation snippets (each snippet is from a message and may be truncated if the original message was long) and extract a compelling and informative title.
- **Key Requirements for the Title:**
- 1. **Content Focus & Searchability:** Prioritize key information, entities, or the main purpose/outcome of the discussion. The title MUST be meaningful enough to distinguish this chat from others when searching.
- 2. **Specific Topics/Articles:** If the discussion CLEARLY revolves around a specific article, document, project, or named topic, YOU MUST STRIVE to include its name (or a concise, recognizable version of it) in the title. This is critical for later retrieval.
- 3. **Length:** Strictly aim for approximately **3-6 words**. Brevity combined with maximum informativeness is key.
- 4. **Style:** You are ENCOURAGED to use relevant EMOJIS and appropriate CAPITALIZATION to make titles more expressive and visually distinct, aiding quick scanning.
- Respond ONLY with the generated title itself. Do not include any other text, explanations, or introductory phrases.
- \`\`\`
- ${historyLines.join('\n')}
- \`\`\``,
- 'chat-ai-title', conversationId,
- );
- // parse title
- title = title
- ?.trim()
- ?.replaceAll('"', '')
- ?.replace('Title: ', '')
- ?.replace('title: ', '');
- // data write
- if (title) {
- setAutoTitle(conversationId, title);
- return true;
- }
- } catch (error: any) {
- // not critical at all
- console.log('Failed to auto-title conversation', conversationId, { error });
- if (forceReplace)
- setAutoTitle(conversationId, '');
- }
- return false;
- }
- =============================
- src/modules/blocks/markdown/CustomMarkdownRenderer.tsx только preprocessMarkdown
- function preprocessMarkdown(markdownText: string) {
- try {
- // for performance, disable the preprocessor if the text is too long
- if (markdownText.length > MAX_PREPROCESSOR_LENGTH) {
- if (!warnedAboutLength) {
- console.warn('[DEV] Preprocessing markdown: text too long, skipping');
- warnedAboutLength = true;
- }
- return markdownText;
- }
- return markdownText
- // NEW: Replace underscores with spaces within \text{} and similar LaTeX commands
- // e.g., \text{first_order} becomes \text{first order}
- // This is to address specific KaTeX parsing issues where '_' inside \text is problematic.
- .replace(/\\(text|mathrm|mathbf|mathit|textit|mathsf|texttt|operatorname)\{([^}]*)\}/g, (match, command, content) => {
- const modifiedContent = content.replace(/_/g, ' ');
- return `\\${command}{${modifiedContent}}`;
- })
- // Replace LaTeX delimiters with $$...$$
- // Replace inline LaTeX delimiters \( and \) with $$
- // [2025-04-20] NOTE: it was reported that we had infinite recursion on the (.*?) version of inline math; as such, we now stay on the same line
- .replace(INLINE_LATEX_REGEX, (_match, leadingSpace, mathContent) =>
- `${leadingSpace}$$${mathContent}$$`,
- )
- // Replace block LaTeX delimiters \[ and \] with $$
- .replace(BLOCK_LATEX_REGEX, (_match, leadingSpace, mathContent) =>
- `${leadingSpace}$$${mathContent}$$`,
- )
- // Replace <mark>...</mark> with ==...==, but not in multiple lines, or if preceded by a backtick (disabled, was (?<!`))
- .replace(/<mark>([\s\S]*?)<\/mark>/g, (_match, p1) => wrapWithMarkdownSyntax(p1, '=='))
- // Replace <del>...</del> with ~~...~~, but not in multiple lines, or if preceded by a backtick (disabled, was (?<!`))
- .replace(/<del>([\s\S]*?)<\/del>/g, (_match, p1) => wrapWithMarkdownSyntax(p1, '~~'));
- } catch (error: any) {
- if (!warnedAboutPreprocessor) {
- console.warn('[DEV] Issue with the markdown preprocessor. Please open a bug with the offending text.', { error, markdownText });
- warnedAboutPreprocessor = true;
- }
- return markdownText;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement