diff --git a/src/apps/chat/components/message/CleanerMessage.tsx b/src/apps/chat/components/message/CleanerMessage.tsx index 645569166..440d0bba5 100644 --- a/src/apps/chat/components/message/CleanerMessage.tsx +++ b/src/apps/chat/components/message/CleanerMessage.tsx @@ -8,6 +8,7 @@ import { DMessage, messageFragmentsReduceText } from '~/common/stores/chat/chat. import { TokenBadgeMemo } from '../composer/TokenBadge'; import { makeMessageAvatar, messageBackground } from './ChatMessage'; +import { isErrorChatMessage } from './explainServiceErrors'; /** @@ -58,7 +59,7 @@ export function CleanerMessage(props: { message: DMessage, selected: boolean, re const fromAssistant = messageRole === 'assistant'; - const isAssistantError = fromAssistant && (messageText.startsWith('[Issue] ') || messageText.startsWith('[OpenAI Issue]')); + const isAssistantError = fromAssistant && isErrorChatMessage(messageText); const backgroundColor = messageBackground(messageRole, !!messageUpdated, isAssistantError); diff --git a/src/apps/chat/components/message/ContentPartText.tsx b/src/apps/chat/components/message/ContentPartText.tsx index 543619f42..132a40d64 100644 --- a/src/apps/chat/components/message/ContentPartText.tsx +++ b/src/apps/chat/components/message/ContentPartText.tsx @@ -51,7 +51,7 @@ export function ContentPartText(props: { onFragmentReplace?.(fragmentId, createTextContentFragment(newText)); }, [fragmentId, messageText, onFragmentReplace]); - const { errorMessage } = React.useMemo( + const errorMessage = React.useMemo( () => explainServiceErrors(messageText, fromAssistant, props.messageOriginLLM), [fromAssistant, messageText, props.messageOriginLLM], ); @@ -59,8 +59,8 @@ export function ContentPartText(props: { // if errored, render an Auto-Error message if (errorMessage) { return ( - -
+ +
); } diff --git a/src/apps/chat/components/message/explainServiceErrors.tsx b/src/apps/chat/components/message/explainServiceErrors.tsx index aedb6fc67..ff3be5007 100644 --- a/src/apps/chat/components/message/explainServiceErrors.tsx +++ b/src/apps/chat/components/message/explainServiceErrors.tsx @@ -3,62 +3,59 @@ import * as React from 'react'; import { Link } from '~/common/components/Link'; +export function isErrorChatMessage(text: string) { + return ['**[Service Issue] ', '[Issue] ', '[OpenAI Issue] '].some(prefix => text.startsWith(prefix)); +} + export function explainServiceErrors(text: string, isAssistant: boolean, modelId?: string) { - const isAssistantError = isAssistant && (text.startsWith('[Issue] ') || text.startsWith('[OpenAI Issue]')); - let errorMessage: React.JSX.Element | null = null; + const isAssistantError = isAssistant && isErrorChatMessage(text); if (!isAssistantError) - return { errorMessage, isAssistantError }; + return null; - // [OpenAI] "Service Temporarily Unavailable (503)", {"code":503,"message":"Service Unavailable.","param":null,"type":"cf_service_unavailable"} - if (text.includes('"cf_service_unavailable"')) { - errorMessage = <> - The OpenAI servers appear to be having trouble at the moment. Kindly follow - the OpenAI Status page - for up to date information, and at your option try again. - ; - } - // ... - else if (text.startsWith('OpenAI API error: 429 Too Many Requests')) { - // TODO: retry at the api/chat level a few times instead of showing this error - errorMessage = <> - The model appears to be occupied at the moment. Kindly select GPT-3.5 Turbo, - or give it another go by selecting Run again from the message menu. - ; - } else if (text.includes('"model_not_found"')) { - // note that "model_not_found" is different than "The model `gpt-xyz` does not exist" message - errorMessage = <> - The API key appears to be unauthorized for {modelId || 'this model'}. You can change to GPT-3.5 - Turbo and simultaneously request - access to the desired model. - ; - } else if (text.includes('"context_length_exceeded"')) { - // TODO: propose to summarize or split the input? - const pattern = /maximum context length is (\d+) tokens.+resulted in (\d+) tokens/; - const match = pattern.exec(text); - const usedText = match ? {parseInt(match[2] || '0').toLocaleString()} tokens > {parseInt(match[1] || '0').toLocaleString()} : ''; - errorMessage = <> - This thread surpasses the maximum size allowed for {modelId || 'this model'}. {usedText}. - Please consider removing some earlier messages from the conversation, start a new conversation, - choose a model with larger context, or submit a shorter new message. - {!usedText && ` -- ${text}`} - ; - } - // [OpenAI] {"error":{"message":"Incorrect API key provided: ...","type":"invalid_request_error","param":null,"code":"invalid_api_key"}} - else if (text.includes('"invalid_api_key"')) { - errorMessage = <> - The API key appears to be incorrect or to have expired. - Please check your - API key and update it in Models. - ; - } else if (text.includes('"insufficient_quota"')) { - errorMessage = <> - The API key appears to have insufficient quota. Please - check your usage and - make sure the usage is under the limits. - ; - } - // else - // errorMessage = <>{text || 'Unknown error'}; + switch (true) { + case text.includes('"insufficient_quota"'): + return <> + {/*The model appears to be occupied at the moment. Kindly try another model, try again after some time,*/} + {/*or give it another go by selecting Run again from the message menu.*/} + The OpenAI API key appears to have insufficient quota. Please + check your usage and + make sure the usage is under the limits. + ; - return { isAssistantError, errorMessage }; + case text.includes('"invalid_api_key"'): + return <> + The OpenAI API key appears to be incorrect or to have expired. + Please check your + API key and update it in Models. + ; + + // [OpenAI] "Service Temporarily Unavailable (503)", {"code":503,"message":"Service Unavailable.","param":null,"type":"cf_service_unavailable"} + case text.includes('"cf_service_unavailable"'): + return <> + The OpenAI servers appear to be having trouble at the moment. Kindly follow + the OpenAI Status page + for up to date information, and at your option try again. + ; + + case text.includes('"model_not_found"'): + return <> + The API key appears to be unauthorized for {modelId || 'this model'}. You can change to GPT-3.5 + Turbo and simultaneously request + access to the desired model. + ; + + case text.includes('"context_length_exceeded"'): + const pattern = /maximum context length is (\d+) tokens.+resulted in (\d+) tokens/; + const match = pattern.exec(text); + const usedText = match ? {parseInt(match[2] || '0').toLocaleString()} tokens > {parseInt(match[1] || '0').toLocaleString()} : ''; + return <> + This thread surpasses the maximum size allowed for {modelId || 'this model'}. {usedText}. + Please consider removing some earlier messages from the conversation, start a new conversation, + choose a model with larger context, or submit a shorter new message. + {!usedText && ` -- ${text}`} + ; + + default: + return undefined; + } } \ No newline at end of file diff --git a/src/apps/chat/editors/browse-load.ts b/src/apps/chat/editors/browse-load.ts index 1e9cc93f9..ca3e5c453 100644 --- a/src/apps/chat/editors/browse-load.ts +++ b/src/apps/chat/editors/browse-load.ts @@ -20,14 +20,14 @@ export const runBrowseGetPageUpdatingState = async (cHandler: ConversationHandle try { const page = await callBrowseFetchPage(url); - const pageContent = page.content.markdown || page.content.text || page.content.html || 'Issue: page load did not produce an answer: no text found'; + const pageContent = page.content.markdown || page.content.text || page.content.html || 'Issue: Browsing did not produce a page content.'; cHandler.messageFragmentReplace(assistantMessageId, placeholderFragmentId, createTextContentFragment(pageContent), true); return true; } catch (error: any) { console.error(error); - const pageError = 'Issue: browse did not produce an answer (error: ' + (error?.message || error?.toString() || 'unknown') + ').'; + const pageError = 'Issue: Browsing did not produce a page.\n(error: ' + (error?.message || error?.toString() || 'unknown') + ').'; cHandler.messageFragmentReplace(assistantMessageId, placeholderFragmentId, createErrorContentFragment(pageError), true); return false; diff --git a/src/apps/chat/editors/image-generate.ts b/src/apps/chat/editors/image-generate.ts index 15862c871..74f7ba466 100644 --- a/src/apps/chat/editors/image-generate.ts +++ b/src/apps/chat/editors/image-generate.ts @@ -49,7 +49,7 @@ export async function runImageGenerationUpdatingState(cHandler: ConversationHand return true; } catch (error: any) { - const drawError = `Issue: Sorry, I couldn't create an image for you. ${error?.message || error?.toString() || 'Unknown error'}`; + const drawError = `Issue: Sorry, I couldn't create an image for you.\n${error?.message || error?.toString() || 'Unknown error'}`; cHandler.messageFragmentReplace(assistantMessageId, placeholderFragmentId, createErrorContentFragment(drawError), true); return false;