feat: move stop inference button into the send button
This commit is contained in:
parent
ef85220910
commit
4f41dab9b5
@ -227,6 +227,11 @@ export default class JanInferenceNitroExtension implements InferenceExtension {
|
|||||||
events.emit(EventName.OnMessageUpdate, message);
|
events.emit(EventName.OnMessageUpdate, message);
|
||||||
},
|
},
|
||||||
error: async (err) => {
|
error: async (err) => {
|
||||||
|
if (instance.isCancelled) {
|
||||||
|
message.status = MessageStatus.Ready;
|
||||||
|
events.emit(EventName.OnMessageUpdate, message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const messageContent: ThreadContent = {
|
const messageContent: ThreadContent = {
|
||||||
type: ContentType.Text,
|
type: ContentType.Text,
|
||||||
text: {
|
text: {
|
||||||
|
|||||||
@ -217,6 +217,11 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension {
|
|||||||
events.emit(EventName.OnMessageUpdate, message);
|
events.emit(EventName.OnMessageUpdate, message);
|
||||||
},
|
},
|
||||||
error: async (err) => {
|
error: async (err) => {
|
||||||
|
if (instance.isCancelled) {
|
||||||
|
message.status = MessageStatus.Ready;
|
||||||
|
events.emit(EventName.OnMessageUpdate, message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const messageContent: ThreadContent = {
|
const messageContent: ThreadContent = {
|
||||||
type: ContentType.Text,
|
type: ContentType.Text,
|
||||||
text: {
|
text: {
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import {
|
import {
|
||||||
EventName,
|
|
||||||
MessageStatus,
|
MessageStatus,
|
||||||
ExtensionType,
|
ExtensionType,
|
||||||
ThreadMessage,
|
ThreadMessage,
|
||||||
events,
|
|
||||||
ChatCompletionRole,
|
ChatCompletionRole,
|
||||||
} from '@janhq/core'
|
} from '@janhq/core'
|
||||||
import { ConversationalExtension, InferenceExtension } from '@janhq/core'
|
import { ConversationalExtension } from '@janhq/core'
|
||||||
import { useAtomValue, useSetAtom } from 'jotai'
|
import { useAtomValue, useSetAtom } from 'jotai'
|
||||||
import { RefreshCcw, Copy, Trash2Icon, StopCircle } from 'lucide-react'
|
import { RefreshCcw, Copy, Trash2Icon } from 'lucide-react'
|
||||||
|
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
@ -29,17 +27,6 @@ const MessageToolbar = ({ message }: { message: ThreadMessage }) => {
|
|||||||
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
||||||
const { resendChatMessage } = useSendChatMessage()
|
const { resendChatMessage } = useSendChatMessage()
|
||||||
|
|
||||||
const onStopInferenceClick = async () => {
|
|
||||||
events.emit(EventName.OnInferenceStopped, {})
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
events.emit(EventName.OnMessageUpdate, {
|
|
||||||
...message,
|
|
||||||
status: MessageStatus.Ready,
|
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onDeleteClick = async () => {
|
const onDeleteClick = async () => {
|
||||||
deleteMessage(message.id ?? '')
|
deleteMessage(message.id ?? '')
|
||||||
if (thread) {
|
if (thread) {
|
||||||
@ -60,26 +47,19 @@ const MessageToolbar = ({ message }: { message: ThreadMessage }) => {
|
|||||||
resendChatMessage(message)
|
resendChatMessage(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.status !== MessageStatus.Ready) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={twMerge('flex flex-row items-center')}>
|
<div className={twMerge('flex flex-row items-center')}>
|
||||||
<div className="flex overflow-hidden rounded-md border border-border bg-background/20">
|
<div className="flex overflow-hidden rounded-md border border-border bg-background/20">
|
||||||
{message.status === MessageStatus.Pending && (
|
{message.id === messages[messages.length - 1]?.id && (
|
||||||
<div
|
<div
|
||||||
className="cursor-pointer border-r border-border px-2 py-2 hover:bg-background/80"
|
className="cursor-pointer border-r border-border px-2 py-2 hover:bg-background/80"
|
||||||
onClick={onStopInferenceClick}
|
onClick={onRegenerateClick}
|
||||||
>
|
>
|
||||||
<StopCircle size={14} />
|
<RefreshCcw size={14} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{message.status !== MessageStatus.Pending &&
|
|
||||||
message.id === messages[messages.length - 1]?.id && (
|
|
||||||
<div
|
|
||||||
className="cursor-pointer border-r border-border px-2 py-2 hover:bg-background/80"
|
|
||||||
onClick={onRegenerateClick}
|
|
||||||
>
|
|
||||||
<RefreshCcw size={14} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div
|
<div
|
||||||
className="cursor-pointer border-r border-border px-2 py-2 hover:bg-background/80"
|
className="cursor-pointer border-r border-border px-2 py-2 hover:bg-background/80"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -91,14 +71,12 @@ const MessageToolbar = ({ message }: { message: ThreadMessage }) => {
|
|||||||
>
|
>
|
||||||
<Copy size={14} />
|
<Copy size={14} />
|
||||||
</div>
|
</div>
|
||||||
{message.status === MessageStatus.Ready && (
|
<div
|
||||||
<div
|
className="cursor-pointer px-2 py-2 hover:bg-background/80"
|
||||||
className="cursor-pointer px-2 py-2 hover:bg-background/80"
|
onClick={onDeleteClick}
|
||||||
onClick={onDeleteClick}
|
>
|
||||||
>
|
<Trash2Icon size={14} />
|
||||||
<Trash2Icon size={14} />
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import { ChangeEvent, Fragment, KeyboardEvent, useEffect, useRef } from 'react'
|
import { ChangeEvent, Fragment, KeyboardEvent, useEffect, useRef } from 'react'
|
||||||
|
|
||||||
|
import { EventName, MessageStatus, events } from '@janhq/core'
|
||||||
import { Button, Textarea } from '@janhq/uikit'
|
import { Button, Textarea } from '@janhq/uikit'
|
||||||
|
|
||||||
import { useAtom, useAtomValue } from 'jotai'
|
import { useAtom, useAtomValue } from 'jotai'
|
||||||
|
|
||||||
|
import { StopCircle } from 'lucide-react'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
import LogoMark from '@/containers/Brand/Logo/Mark'
|
import LogoMark from '@/containers/Brand/Logo/Mark'
|
||||||
@ -26,6 +28,7 @@ import ThreadList from '@/screens/Chat/ThreadList'
|
|||||||
|
|
||||||
import Sidebar, { showRightSideBarAtom } from './Sidebar'
|
import Sidebar, { showRightSideBarAtom } from './Sidebar'
|
||||||
|
|
||||||
|
import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom'
|
||||||
import {
|
import {
|
||||||
activeThreadAtom,
|
activeThreadAtom,
|
||||||
getActiveThreadIdAtom,
|
getActiveThreadIdAtom,
|
||||||
@ -40,6 +43,7 @@ const ChatScreen = () => {
|
|||||||
|
|
||||||
const { activeModel, stateModel } = useActiveModel()
|
const { activeModel, stateModel } = useActiveModel()
|
||||||
const { setMainViewState } = useMainViewState()
|
const { setMainViewState } = useMainViewState()
|
||||||
|
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
||||||
|
|
||||||
const [currentPrompt, setCurrentPrompt] = useAtom(currentPromptAtom)
|
const [currentPrompt, setCurrentPrompt] = useAtom(currentPromptAtom)
|
||||||
const activeThreadState = useAtomValue(activeThreadStateAtom)
|
const activeThreadState = useAtomValue(activeThreadStateAtom)
|
||||||
@ -94,6 +98,10 @@ const ChatScreen = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onStopInferenceClick = async () => {
|
||||||
|
events.emit(EventName.OnInferenceStopped, {})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full w-full">
|
<div className="flex h-full w-full">
|
||||||
<div className="flex h-full w-60 flex-shrink-0 flex-col overflow-y-auto border-r border-border bg-background dark:bg-background/50">
|
<div className="flex h-full w-60 flex-shrink-0 flex-col overflow-y-auto border-r border-border bg-background dark:bg-background/50">
|
||||||
@ -159,14 +167,26 @@ const ChatScreen = () => {
|
|||||||
onPromptChange(e)
|
onPromptChange(e)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Button
|
{messages[messages.length - 1]?.status !== MessageStatus.Pending ? (
|
||||||
size="lg"
|
<Button
|
||||||
disabled={disabled || stateModel.loading || !activeThread}
|
size="lg"
|
||||||
themes={'primary'}
|
disabled={disabled || stateModel.loading || !activeThread}
|
||||||
onClick={sendChatMessage}
|
themes="primary"
|
||||||
>
|
className="min-w-[100px]"
|
||||||
Send
|
onClick={sendChatMessage}
|
||||||
</Button>
|
>
|
||||||
|
Send
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
size="lg"
|
||||||
|
themes="danger"
|
||||||
|
onClick={onStopInferenceClick}
|
||||||
|
className="min-w-[100px]"
|
||||||
|
>
|
||||||
|
<StopCircle size={24} />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user