diff --git a/app/client/platforms/openai.ts b/app/client/platforms/openai.ts index 4d6f28845412..664ff872ba31 100644 --- a/app/client/platforms/openai.ts +++ b/app/client/platforms/openai.ts @@ -160,6 +160,7 @@ export class ChatGPTApi implements LLMApi { let requestPayload: RequestPayload | DalleRequestPayload; const isDalle3 = _isDalle3(options.config.model); + const isO1 = options.config.model.startsWith("o1"); if (isDalle3) { const prompt = getMessageTextContent( options.messages.slice(-1)?.pop() as any, @@ -181,30 +182,32 @@ export class ChatGPTApi implements LLMApi { const content = visionModel ? await preProcessImageContent(v.content) : getMessageTextContent(v); - messages.push({ role: v.role, content }); + if (!(isO1 && v.role === "system")) + messages.push({ role: v.role, content }); } + // O1 not support image, tools (plugin in ChatGPTNextWeb) and system, stream, logprobs, temperature, top_p, n, presence_penalty, frequency_penalty yet. requestPayload = { messages, - stream: options.config.stream, + stream: !isO1 ? options.config.stream : false, model: modelConfig.model, - temperature: modelConfig.temperature, - presence_penalty: modelConfig.presence_penalty, - frequency_penalty: modelConfig.frequency_penalty, - top_p: modelConfig.top_p, + temperature: !isO1 ? modelConfig.temperature : 1, + presence_penalty: !isO1 ? modelConfig.presence_penalty : 0, + frequency_penalty: !isO1 ? modelConfig.frequency_penalty : 0, + top_p: !isO1 ? modelConfig.top_p : 1, // max_tokens: Math.max(modelConfig.max_tokens, 1024), // Please do not ask me why not send max_tokens, no reason, this param is just shit, I dont want to explain anymore. }; // add max_tokens to vision model - if (visionModel && modelConfig.model.includes("preview")) { + if (visionModel) { requestPayload["max_tokens"] = Math.max(modelConfig.max_tokens, 4000); } } console.log("[Request] openai payload: ", requestPayload); - const shouldStream = !isDalle3 && !!options.config.stream; + const shouldStream = !isDalle3 && !!options.config.stream && !isO1; const controller = new AbortController(); options.onController?.(controller); @@ -313,7 +316,7 @@ export class ChatGPTApi implements LLMApi { // make a fetch request const requestTimeoutId = setTimeout( () => controller.abort(), - isDalle3 ? REQUEST_TIMEOUT_MS * 2 : REQUEST_TIMEOUT_MS, // dalle3 using b64_json is slow. + isDalle3 || isO1 ? REQUEST_TIMEOUT_MS * 2 : REQUEST_TIMEOUT_MS, // dalle3 using b64_json is slow. ); const res = await fetch(chatPath, chatPayload); diff --git a/app/components/artifacts.tsx b/app/components/artifacts.tsx index ac0d713b3f80..d725ee6596ee 100644 --- a/app/components/artifacts.tsx +++ b/app/components/artifacts.tsx @@ -80,7 +80,7 @@ export const HTMLPreview = forwardRef( }, [props.autoHeight, props.height, iframeHeight]); const srcDoc = useMemo(() => { - const script = ``; + const script = ``; if (props.code.includes("")) { props.code.replace("", "" + script); } diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 300367151c77..dafb98464219 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -507,6 +507,8 @@ export function ChatActions(props: { const currentStyle = chatStore.currentSession().mask.modelConfig?.style ?? "vivid"; + const isMobileScreen = useMobileScreen(); + useEffect(() => { const show = isVisionModel(currentModel); setShowUploadImage(show); @@ -761,11 +763,13 @@ export function ChatActions(props: { /> )} - props.setShowShortcutKeyModal(true)} - text={Locale.Chat.ShortcutKey.Title} - icon={} - /> + {!isMobileScreen && ( + props.setShowShortcutKeyModal(true)} + text={Locale.Chat.ShortcutKey.Title} + icon={} + /> + )} ); } diff --git a/app/components/markdown.tsx b/app/components/markdown.tsx index dc11c572d7e2..b57fd74904cf 100644 --- a/app/components/markdown.tsx +++ b/app/components/markdown.tsx @@ -237,9 +237,26 @@ function escapeBrackets(text: string) { ); } +function tryWrapHtmlCode(text: string) { + // try add wrap html code (fixed: html codeblock include 2 newline) + return text + .replace( + /([`]*?)(\w*?)([\n\r]*?)()/g, + (match, quoteStart, lang, newLine, doctype) => { + return !quoteStart ? "\n```html\n" + doctype : match; + }, + ) + .replace( + /(<\/body>)([\r\n\s]*?)(<\/html>)([\n\r]*?)([`]*?)([\n\r]*?)/g, + (match, bodyEnd, space, htmlEnd, newLine, quoteEnd) => { + return !quoteEnd ? bodyEnd + space + htmlEnd + "\n```\n" : match; + }, + ); +} + function _MarkDownContent(props: { content: string }) { const escapedContent = useMemo(() => { - return escapeBrackets(escapeDollarNumber(props.content)); + return tryWrapHtmlCode(escapeBrackets(escapeDollarNumber(props.content))); }, [props.content]); return ( diff --git a/app/constant.ts b/app/constant.ts index eb82d3c66002..3d33a047e902 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -250,6 +250,8 @@ export const KnowledgeCutOffDate: Record = { "gpt-4o-mini": "2023-10", "gpt-4o-mini-2024-07-18": "2023-10", "gpt-4-vision-preview": "2023-04", + "o1-mini": "2023-10", + "o1-preview": "2023-10", // After improvements, // it's now easier to add "KnowledgeCutOffDate" instead of stupid hardcoding it, as was done previously. "gemini-pro": "2023-12", @@ -276,6 +278,8 @@ const openaiModels = [ "gpt-4-turbo-2024-04-09", "gpt-4-1106-preview", "dall-e-3", + "o1-mini", + "o1-preview" ]; const googleModels = [ diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 78835d24da9a..2a19c9332058 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -9,7 +9,7 @@ }, "package": { "productName": "NextChat", - "version": "2.15.1" + "version": "2.15.2" }, "tauri": { "allowlist": {