chore: error message update (#1473)
This commit is contained in:
parent
e0b04e8a76
commit
f82cf0d014
@ -61,6 +61,8 @@ export enum MessageStatus {
|
|||||||
Pending = 'pending',
|
Pending = 'pending',
|
||||||
/** Message loaded with error. **/
|
/** Message loaded with error. **/
|
||||||
Error = 'error',
|
Error = 'error',
|
||||||
|
/** Message is cancelled streaming */
|
||||||
|
Stopped = "stopped"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -240,19 +240,11 @@ export default class JanInferenceNitroExtension implements InferenceExtension {
|
|||||||
},
|
},
|
||||||
error: async (err) => {
|
error: async (err) => {
|
||||||
if (instance.isCancelled || message.content.length) {
|
if (instance.isCancelled || message.content.length) {
|
||||||
message.status = MessageStatus.Error;
|
message.status = MessageStatus.Stopped;
|
||||||
events.emit(EventName.OnMessageUpdate, message);
|
events.emit(EventName.OnMessageUpdate, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const messageContent: ThreadContent = {
|
message.status = MessageStatus.Error;
|
||||||
type: ContentType.Text,
|
|
||||||
text: {
|
|
||||||
value: "Error occurred: " + err.message,
|
|
||||||
annotations: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
message.content = [messageContent];
|
|
||||||
message.status = MessageStatus.Ready;
|
|
||||||
events.emit(EventName.OnMessageUpdate, message);
|
events.emit(EventName.OnMessageUpdate, message);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -92,10 +92,7 @@ export default function EventHandler({ children }: { children: ReactNode }) {
|
|||||||
message.content,
|
message.content,
|
||||||
message.status
|
message.status
|
||||||
)
|
)
|
||||||
if (
|
if (message.status !== MessageStatus.Pending) {
|
||||||
message.status === MessageStatus.Ready ||
|
|
||||||
message.status === MessageStatus.Error
|
|
||||||
) {
|
|
||||||
// Mark the thread as not waiting for response
|
// Mark the thread as not waiting for response
|
||||||
updateThreadWaiting(message.thread_id, false)
|
updateThreadWaiting(message.thread_id, false)
|
||||||
|
|
||||||
|
|||||||
@ -2,17 +2,9 @@ import { Fragment } from 'react'
|
|||||||
|
|
||||||
import ScrollToBottom from 'react-scroll-to-bottom'
|
import ScrollToBottom from 'react-scroll-to-bottom'
|
||||||
|
|
||||||
import {
|
import { InferenceEngine, MessageStatus } from '@janhq/core'
|
||||||
ChatCompletionRole,
|
|
||||||
ConversationalExtension,
|
|
||||||
ExtensionType,
|
|
||||||
InferenceEngine,
|
|
||||||
MessageStatus,
|
|
||||||
} from '@janhq/core'
|
|
||||||
import { Button } from '@janhq/uikit'
|
import { Button } from '@janhq/uikit'
|
||||||
import { useAtomValue, useSetAtom } from 'jotai'
|
import { useAtomValue } from 'jotai'
|
||||||
|
|
||||||
import { RefreshCcw } from 'lucide-react'
|
|
||||||
|
|
||||||
import LogoMark from '@/containers/Brand/Logo/Mark'
|
import LogoMark from '@/containers/Brand/Logo/Mark'
|
||||||
|
|
||||||
@ -22,45 +14,16 @@ import { useGetDownloadedModels } from '@/hooks/useGetDownloadedModels'
|
|||||||
|
|
||||||
import { useMainViewState } from '@/hooks/useMainViewState'
|
import { useMainViewState } from '@/hooks/useMainViewState'
|
||||||
|
|
||||||
import useSendChatMessage from '@/hooks/useSendChatMessage'
|
|
||||||
|
|
||||||
import ChatItem from '../ChatItem'
|
import ChatItem from '../ChatItem'
|
||||||
|
|
||||||
import { extensionManager } from '@/extension'
|
import ErrorMessage from '../ErrorMessage'
|
||||||
import {
|
|
||||||
deleteMessageAtom,
|
import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom'
|
||||||
getCurrentChatMessagesAtom,
|
|
||||||
} from '@/helpers/atoms/ChatMessage.atom'
|
|
||||||
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
|
||||||
|
|
||||||
const ChatBody: React.FC = () => {
|
const ChatBody: React.FC = () => {
|
||||||
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
||||||
const { downloadedModels } = useGetDownloadedModels()
|
const { downloadedModels } = useGetDownloadedModels()
|
||||||
const { setMainViewState } = useMainViewState()
|
const { setMainViewState } = useMainViewState()
|
||||||
const thread = useAtomValue(activeThreadAtom)
|
|
||||||
const deleteMessage = useSetAtom(deleteMessageAtom)
|
|
||||||
const { resendChatMessage } = useSendChatMessage()
|
|
||||||
|
|
||||||
const regenerateMessage = async () => {
|
|
||||||
const lastMessageIndex = messages.length - 1
|
|
||||||
const message = messages[lastMessageIndex]
|
|
||||||
if (message.role !== ChatCompletionRole.User) {
|
|
||||||
// Delete last response before regenerating
|
|
||||||
deleteMessage(message.id ?? '')
|
|
||||||
if (thread) {
|
|
||||||
await extensionManager
|
|
||||||
.get<ConversationalExtension>(ExtensionType.Conversational)
|
|
||||||
?.writeMessages(
|
|
||||||
thread.id,
|
|
||||||
messages.filter((msg) => msg.id !== message.id)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
const targetMessage = messages[lastMessageIndex - 1]
|
|
||||||
if (targetMessage) resendChatMessage(targetMessage)
|
|
||||||
} else {
|
|
||||||
resendChatMessage(message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloadedModels.length === 0)
|
if (downloadedModels.length === 0)
|
||||||
return (
|
return (
|
||||||
@ -118,26 +81,10 @@ const ChatBody: React.FC = () => {
|
|||||||
{messages.map((message, index) => (
|
{messages.map((message, index) => (
|
||||||
<div key={message.id}>
|
<div key={message.id}>
|
||||||
<ChatItem {...message} key={message.id} />
|
<ChatItem {...message} key={message.id} />
|
||||||
{message.status === MessageStatus.Error &&
|
{(message.status === MessageStatus.Error ||
|
||||||
|
message.status === MessageStatus.Stopped) &&
|
||||||
index === messages.length - 1 && (
|
index === messages.length - 1 && (
|
||||||
<div
|
<ErrorMessage message={message} />
|
||||||
key={message.id}
|
|
||||||
className="mt-10 flex flex-col items-center"
|
|
||||||
>
|
|
||||||
<span className="mb-3 text-center text-sm font-medium text-gray-500">
|
|
||||||
Oops! The generation was interrupted. Let's give it
|
|
||||||
another go!
|
|
||||||
</span>
|
|
||||||
<Button
|
|
||||||
className="w-min"
|
|
||||||
themes="outline"
|
|
||||||
onClick={regenerateMessage}
|
|
||||||
>
|
|
||||||
<RefreshCcw size={14} className="" />
|
|
||||||
<span className="w-2" />
|
|
||||||
Regenerate
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
93
web/screens/Chat/ErrorMessage/index.tsx
Normal file
93
web/screens/Chat/ErrorMessage/index.tsx
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import {
|
||||||
|
ChatCompletionRole,
|
||||||
|
ConversationalExtension,
|
||||||
|
ExtensionType,
|
||||||
|
MessageStatus,
|
||||||
|
ThreadMessage,
|
||||||
|
} from '@janhq/core'
|
||||||
|
import { Button } from '@janhq/uikit'
|
||||||
|
import { useAtomValue, useSetAtom } from 'jotai'
|
||||||
|
import { RefreshCcw } from 'lucide-react'
|
||||||
|
|
||||||
|
import useSendChatMessage from '@/hooks/useSendChatMessage'
|
||||||
|
|
||||||
|
import { extensionManager } from '@/extension'
|
||||||
|
import {
|
||||||
|
deleteMessageAtom,
|
||||||
|
getCurrentChatMessagesAtom,
|
||||||
|
} from '@/helpers/atoms/ChatMessage.atom'
|
||||||
|
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
|
const ErrorMessage = ({ message }: { message: ThreadMessage }) => {
|
||||||
|
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
||||||
|
const thread = useAtomValue(activeThreadAtom)
|
||||||
|
const deleteMessage = useSetAtom(deleteMessageAtom)
|
||||||
|
const { resendChatMessage } = useSendChatMessage()
|
||||||
|
|
||||||
|
const regenerateMessage = async () => {
|
||||||
|
const lastMessageIndex = messages.length - 1
|
||||||
|
const message = messages[lastMessageIndex]
|
||||||
|
if (message.role !== ChatCompletionRole.User) {
|
||||||
|
// Delete last response before regenerating
|
||||||
|
deleteMessage(message.id ?? '')
|
||||||
|
if (thread) {
|
||||||
|
await extensionManager
|
||||||
|
.get<ConversationalExtension>(ExtensionType.Conversational)
|
||||||
|
?.writeMessages(
|
||||||
|
thread.id,
|
||||||
|
messages.filter((msg) => msg.id !== message.id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const targetMessage = messages[lastMessageIndex - 1]
|
||||||
|
if (targetMessage) resendChatMessage(targetMessage)
|
||||||
|
} else {
|
||||||
|
resendChatMessage(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{message.status === MessageStatus.Stopped && (
|
||||||
|
<div key={message.id} className="mt-10 flex flex-col items-center">
|
||||||
|
<span className="mb-3 text-center text-sm font-medium text-gray-500">
|
||||||
|
Oops! The generation was interrupted. Let's give it another go!
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
className="w-min"
|
||||||
|
themes="outline"
|
||||||
|
onClick={regenerateMessage}
|
||||||
|
>
|
||||||
|
<RefreshCcw size={14} className="" />
|
||||||
|
<span className="w-2" />
|
||||||
|
Regenerate
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{message.status === MessageStatus.Error && (
|
||||||
|
<div key={message.id} className="mt-10 flex flex-col items-center">
|
||||||
|
<span className="mb-3 text-center text-sm font-medium text-gray-500">
|
||||||
|
<p>Apologies, something's amiss!</p>
|
||||||
|
Jan's in beta. Find troubleshooting guides{' '}
|
||||||
|
<a
|
||||||
|
href="https://jan.ai/guides/troubleshooting"
|
||||||
|
target="_blank"
|
||||||
|
className="text-blue-600 hover:underline dark:text-blue-300"
|
||||||
|
>
|
||||||
|
here
|
||||||
|
</a>{' '}
|
||||||
|
or reach out to us on{' '}
|
||||||
|
<a
|
||||||
|
href="https://discord.gg/AsJ8krTT3N"
|
||||||
|
target="_blank"
|
||||||
|
className="text-blue-600 hover:underline dark:text-blue-300"
|
||||||
|
>
|
||||||
|
Discord
|
||||||
|
</a>{' '}
|
||||||
|
for assistance.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default ErrorMessage
|
||||||
@ -104,10 +104,7 @@ const SimpleTextMessage: React.FC<ThreadMessage> = (props) => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (props.status !== MessageStatus.Pending) {
|
||||||
props.status === MessageStatus.Ready ||
|
|
||||||
props.status === MessageStatus.Error
|
|
||||||
) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const currentTimestamp = new Date().getTime() // Get current time in milliseconds
|
const currentTimestamp = new Date().getTime() // Get current time in milliseconds
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user