feat: users should be able to switch models mid-thread (#1226)

## Problem
Right now users have to start a new thread to use another model which causes a lot of confusion to our users.

fixes #1201
This commit is contained in:
Louis 2023-12-27 15:35:27 +07:00 committed by GitHub
parent 150af523e1
commit a7f186cc5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 62 deletions

View File

@ -72,69 +72,55 @@ export default function DropdownListSidebar() {
if (!activeThread) { if (!activeThread) {
return null return null
} }
const finishInit = threadStates[activeThread.id].isFinishInit ?? true
return ( return (
<Tooltip> <>
<TooltipTrigger className="w-full"> <Select value={selected?.id} onValueChange={onValueSelected}>
<Select <SelectTrigger className="w-full">
disabled={finishInit} <SelectValue placeholder="Choose model to start">
value={selected?.id} {downloadedModels.filter((x) => x.id === selected?.id)[0]?.name}
onValueChange={finishInit ? undefined : onValueSelected} </SelectValue>
> </SelectTrigger>
<SelectTrigger className="w-full"> <SelectContent className="right-5 block w-full min-w-[300px] pr-0">
<SelectValue placeholder="Choose model to start"> <div className="flex w-full items-center space-x-2 px-4 py-2">
{downloadedModels.filter((x) => x.id === selected?.id)[0]?.name} <MonitorIcon size={20} className="text-muted-foreground" />
</SelectValue> <span>Local</span>
</SelectTrigger> </div>
<SelectContent className="right-5 block w-full min-w-[300px] pr-0"> <div className="border-b border-border" />
<div className="flex w-full items-center space-x-2 px-4 py-2"> {downloadedModels.length === 0 ? (
<MonitorIcon size={20} className="text-muted-foreground" /> <div className="px-4 py-2">
<span>Local</span> <p>{`Oops, you don't have a model yet.`}</p>
</div> </div>
<div className="border-b border-border" /> ) : (
{downloadedModels.length === 0 ? ( <SelectGroup>
<div className="px-4 py-2"> {downloadedModels.map((x, i) => (
<p>{`Oops, you don't have a model yet.`}</p> <SelectItem
</div> key={i}
) : ( value={x.id}
<SelectGroup> className={twMerge(x.id === selected?.id && 'bg-secondary')}
{downloadedModels.map((x, i) => ( >
<SelectItem <div className="flex w-full justify-between">
key={i} <span className="line-clamp-1 block">{x.name}</span>
value={x.id} <span className="font-bold text-muted-foreground">
className={twMerge(x.id === selected?.id && 'bg-secondary')} {toGigabytes(x.metadata.size)}
> </span>
<div className="flex w-full justify-between"> </div>
<span className="line-clamp-1 block">{x.name}</span> </SelectItem>
<span className="font-bold text-muted-foreground"> ))}
{toGigabytes(x.metadata.size)} </SelectGroup>
</span> )}
</div> <div className="border-b border-border" />
</SelectItem> <div className="w-full px-4 py-2">
))} <Button
</SelectGroup> block
)} className="bg-blue-100 font-bold text-blue-600 hover:bg-blue-100 hover:text-blue-600"
<div className="border-b border-border" /> onClick={() => setMainViewState(MainViewState.Hub)}
<div className="w-full px-4 py-2"> >
<Button Explore The Hub
block </Button>
className="bg-blue-100 font-bold text-blue-600 hover:bg-blue-100 hover:text-blue-600" </div>
onClick={() => setMainViewState(MainViewState.Hub)} </SelectContent>
> </Select>
Explore The Hub
</Button>
</div>
</SelectContent>
</Select>
</TooltipTrigger>
{finishInit && (
<TooltipContent sideOffset={10}>
<span>Start a new thread to change the model</span>
<TooltipArrow />
</TooltipContent>
)}
{selected?.engine === InferenceEngine.openai && ( {selected?.engine === InferenceEngine.openai && (
<div className="mt-4"> <div className="mt-4">
@ -154,6 +140,6 @@ export default function DropdownListSidebar() {
/> />
</div> </div>
)} )}
</Tooltip> </>
) )
} }

View File

@ -138,7 +138,10 @@ export default function useSendChatMessage() {
const activeThreadState = threadStates[activeThread.id] const activeThreadState = threadStates[activeThread.id]
// if the thread is not initialized, we need to initialize it first // if the thread is not initialized, we need to initialize it first
if (!activeThreadState.isFinishInit) { if (
!activeThreadState.isFinishInit ||
activeThread.assistants[0].model.id !== selectedModel?.id
) {
if (!selectedModel) { if (!selectedModel) {
toaster({ title: 'Please select a model' }) toaster({ title: 'Please select a model' })
return return