From 53021c3688be4a2e4215474d0a5992a2841e696a Mon Sep 17 00:00:00 2001 From: Dmitri Nasonov Date: Sun, 8 Sep 2024 14:51:58 +0100 Subject: [PATCH 1/3] A: Updated system message to not be inserted when max token limit is hit R: Consistency --- src/utils/messageUtils.ts | 74 +++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/src/utils/messageUtils.ts b/src/utils/messageUtils.ts index 9b1e42f21..8f7f23483 100644 --- a/src/utils/messageUtils.ts +++ b/src/utils/messageUtils.ts @@ -1,8 +1,13 @@ - import useStore from '@store/store'; import { Tiktoken } from '@dqbd/tiktoken/lite'; -import { isImageContent, isTextContent, MessageInterface, TextContentInterface, TotalTokenUsed } from '@type/chat'; +import { + isImageContent, + isTextContent, + MessageInterface, + TextContentInterface, + TotalTokenUsed, +} from '@type/chat'; import { ModelOptions } from './modelReader'; const cl100k_base = await import('@dqbd/tiktoken/encoders/cl100k_base.json'); @@ -30,7 +35,9 @@ export const getChatGPTEncoding = ( const serialized = [ messages .map(({ role, content }) => { - return `<|im_start|>${role}${roleSep}${(content[0] as TextContentInterface).text}<|im_end|>`; + return `<|im_start|>${role}${roleSep}${ + (content[0] as TextContentInterface).text + }<|im_end|>`; }) .join(msgSep), `<|im_start|>assistant${roleSep}`, @@ -52,38 +59,38 @@ export const limitMessageTokens = ( const limitedMessages: MessageInterface[] = []; let tokenCount = 0; - const isSystemFirstMessage = messages[0]?.role === 'system'; - let retainSystemMessage = false; + // const isSystemFirstMessage = messages[0]?.role === 'system'; + // let retainSystemMessage = false; - // Check if the first message is a system message and if it fits within the token limit - if (isSystemFirstMessage) { - const systemTokenCount = countTokens([messages[0]], model); - if (systemTokenCount < limit) { - tokenCount += systemTokenCount; - retainSystemMessage = true; - } - } + // // Check if the first message is a system message and if it fits within the token limit + // if (isSystemFirstMessage) { + // const systemTokenCount = countTokens([messages[0]], model); + // if (systemTokenCount < limit) { + // tokenCount += systemTokenCount; + // retainSystemMessage = true; + // } + // } // Iterate through messages in reverse order, adding them to the limitedMessages array // until the token limit is reached (excludes first message) - for (let i = messages.length - 1; i >= 1; i--) { + for (let i = messages.length - 1; i >= 0; i--) { const count = countTokens([messages[i]], model); if (count + tokenCount > limit) break; tokenCount += count; limitedMessages.unshift({ ...messages[i] }); } - // Process first message - if (retainSystemMessage) { - // Insert the system message in the third position from the end - limitedMessages.splice(-3, 0, { ...messages[0] }); - } else if (!isSystemFirstMessage && messages.length > 0) { - // Check if the first message (non-system) can fit within the limit - const firstMessageTokenCount = countTokens([messages[0]], model); - if (firstMessageTokenCount + tokenCount < limit) { - limitedMessages.unshift({ ...messages[0] }); - } - } + // // Process first message + // if (retainSystemMessage) { + // // Insert the system message in the third position from the end + // limitedMessages.splice(-3, 0, { ...messages[0] }); + // } else if (!isSystemFirstMessage && messages.length > 0) { + // // Check if the first message (non-system) can fit within the limit + // const firstMessageTokenCount = countTokens([messages[0]], model); + // if (firstMessageTokenCount + tokenCount < limit) { + // limitedMessages.unshift({ ...messages[0] }); + // } + // } return limitedMessages; }; @@ -99,8 +106,12 @@ export const updateTotalTokenUsed = ( ); // Filter text and image prompts - const textPrompts = promptMessages.filter(e => e.content.some(isTextContent)); - const imgPrompts = promptMessages.filter(e => e.content.some(isImageContent)); + const textPrompts = promptMessages.filter((e) => + e.content.some(isTextContent) + ); + const imgPrompts = promptMessages.filter((e) => + e.content.some(isImageContent) + ); // Count tokens const newPromptTokens = countTokens(textPrompts, model); @@ -108,14 +119,17 @@ export const updateTotalTokenUsed = ( const newCompletionTokens = countTokens([completionMessage], model); // Destructure existing token counts or default to 0 - const { promptTokens = 0, completionTokens = 0, imageTokens = 0 } = - updatedTotalTokenUsed[model] ?? {}; + const { + promptTokens = 0, + completionTokens = 0, + imageTokens = 0, + } = updatedTotalTokenUsed[model] ?? {}; // Update token counts updatedTotalTokenUsed[model] = { promptTokens: promptTokens + newPromptTokens, completionTokens: completionTokens + newCompletionTokens, - imageTokens: imageTokens + newImageTokens + imageTokens: imageTokens + newImageTokens, }; // Set the updated token counts in the store From 82cbcfef8f303eb4249fc7962f58487d15bb93ab Mon Sep 17 00:00:00 2001 From: Dmitri Nasonov Date: Sun, 8 Sep 2024 15:51:19 +0100 Subject: [PATCH 2/3] version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce81ed929..8f3dd405c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "better-chatgpt", "private": true, - "version": "1.8.2", + "version": "1.8.3", "type": "module", "homepage": "./", "main": "electron/index.cjs", From 9d36b2cdf160b33d79837f11f3c6bb3da1a26e2a Mon Sep 17 00:00:00 2001 From: Dmitri Nasonov Date: Sun, 8 Sep 2024 15:59:44 +0100 Subject: [PATCH 3/3] Added latex support for OpenAI --- .../Chat/ChatContent/Message/View/ContentView.tsx | 5 ++++- src/utils/chat.ts | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/components/Chat/ChatContent/Message/View/ContentView.tsx b/src/components/Chat/ChatContent/Message/View/ContentView.tsx index 70d28faad..bde062de1 100644 --- a/src/components/Chat/ChatContent/Message/View/ContentView.tsx +++ b/src/components/Chat/ChatContent/Message/View/ContentView.tsx @@ -38,6 +38,7 @@ import MarkdownModeButton from './Button/MarkdownModeButton'; import CodeBlock from '../CodeBlock'; import PopupModal from '@components/PopupModal'; +import { preprocessLaTeX } from '@utils/chat'; const ContentView = memo( ({ @@ -144,7 +145,9 @@ const ContentView = memo( p, }} > - {(content[0] as TextContentInterface).text} + {inlineLatex + ? preprocessLaTeX((content[0] as TextContentInterface).text) + : (content[0] as TextContentInterface).text} ) : ( diff --git a/src/utils/chat.ts b/src/utils/chat.ts index 7d3eabf8c..5f136f5d2 100644 --- a/src/utils/chat.ts +++ b/src/utils/chat.ts @@ -51,3 +51,18 @@ export const downloadMarkdown = (markdown: string, fileName: string) => { link.click(); link.remove(); }; + +export const preprocessLaTeX = (content: string) => { + // Replace block-level LaTeX delimiters \[ \] with $$ $$ + + const blockProcessedContent = content.replace( + /\\\[(.*?)\\\]/gs, + (_, equation) => `$$${equation}$$` + ); + // Replace inline LaTeX delimiters \( \) with $ $ + const inlineProcessedContent = blockProcessedContent.replace( + /\\\((.*?)\\\)/gs, + (_, equation) => `$${equation}$` + ); + return inlineProcessedContent; +}; \ No newline at end of file