feat: add more options for cortex popup (#3236)

update
This commit is contained in:
NamH 2024-08-05 14:31:31 +07:00 committed by GitHub
parent 37a3c4f844
commit 5e06ed8a12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 89 additions and 37 deletions

View File

@ -1,4 +1,4 @@
import { Fragment, useEffect, useState } from 'react' import { Fragment, useEffect, useState, useCallback } from 'react'
import { Modal } from '@janhq/joi' import { Modal } from '@janhq/joi'
import { useAtom } from 'jotai' import { useAtom } from 'jotai'
@ -13,6 +13,7 @@ import Tab, { ModelTab } from './Tab'
import { localModelModalStageAtom } from '@/helpers/atoms/DownloadLocalModel.atom' import { localModelModalStageAtom } from '@/helpers/atoms/DownloadLocalModel.atom'
const DownloadLocalModelModal: React.FC = () => { const DownloadLocalModelModal: React.FC = () => {
const [availableModels, setAvailableModels] = useState<string[]>([])
const [{ stage, modelHandle }, setLocalModelModalStage] = useAtom( const [{ stage, modelHandle }, setLocalModelModalStage] = useAtom(
localModelModalStageAtom localModelModalStageAtom
) )
@ -31,9 +32,21 @@ const DownloadLocalModelModal: React.FC = () => {
}, []) }, [])
const modelName = modelHandle?.split('/')[1] ?? '' const modelName = modelHandle?.split('/')[1] ?? ''
if (!modelHandle) return null const isFromCortexHub = modelHandle?.includes('cortexso') ?? false
const isFromCortexHub = modelHandle.includes('cortexso') const onModelBranchChanged = useCallback(
(models: string[]) => {
const isFromCortexHub = modelHandle?.includes('cortexso') ?? false
if (isFromCortexHub) {
setAvailableModels(models)
} else {
setAvailableModels(modelHandle != null ? [modelHandle] : [])
}
},
[modelHandle]
)
if (!modelHandle) return null
return ( return (
<Modal <Modal
@ -43,11 +56,11 @@ const DownloadLocalModelModal: React.FC = () => {
content={ content={
<Fragment> <Fragment>
<HeaderModal <HeaderModal
modelId={modelHandle} modelHandle={modelHandle}
name={modelName} name={modelName}
onActionClick={() => {}} onActionClick={() => {}}
modelIdVariants={[modelHandle]}
isLocalModel={true} isLocalModel={true}
availableModels={availableModels}
/> />
<Tab <Tab
tab={tab} tab={tab}
@ -55,7 +68,10 @@ const DownloadLocalModelModal: React.FC = () => {
/> />
{tab === 'Versions' && {tab === 'Versions' &&
(isFromCortexHub ? ( (isFromCortexHub ? (
<ListModel modelHandle={modelHandle} /> <ListModel
modelHandle={modelHandle}
onBranchSelected={onModelBranchChanged}
/>
) : ( ) : (
<HfListModel modelHandle={modelHandle} /> <HfListModel modelHandle={modelHandle} />
))} ))}

View File

@ -1,4 +1,4 @@
import { Fragment, useCallback, useRef, useState } from 'react' import { Fragment, useCallback, useEffect, useRef, useState } from 'react'
import Image from 'next/image' import Image from 'next/image'
@ -10,27 +10,60 @@ import { twMerge } from 'tailwind-merge'
import DropdownModal from './DropdownModal' import DropdownModal from './DropdownModal'
type Props = { type Props = {
modelIdVariants: string[]
modelId: string
name: string name: string
modelHandle?: string
availableModels: string[]
onActionClick: () => void onActionClick: () => void
isLocalModel?: boolean isLocalModel?: boolean
} }
const HeaderModal: React.FC<Props> = ({ const HeaderModal: React.FC<Props> = ({
modelIdVariants,
modelId,
name, name,
modelHandle,
availableModels,
onActionClick, onActionClick,
isLocalModel = false, isLocalModel = false,
}) => { }) => {
const [selectedVariant, setSelectedVariant] = useState<string>(modelId) const [options, setOptions] = useState<{ name: string; value: string }[]>([])
const [selectedVariant, setSelectedVariant] = useState<string | undefined>()
const textRef = useRef<HTMLDivElement>(null) const textRef = useRef<HTMLDivElement>(null)
const options = modelIdVariants.map((variant) => ({ useEffect(() => {
const isFromCortexHub = modelHandle?.includes('cortexso') ?? false
if (!isLocalModel) {
setOptions(
availableModels.map((variant) => ({
name: variant, name: variant,
value: variant, value: variant,
})) }))
)
if (availableModels.length > 0) {
setSelectedVariant(availableModels[0])
}
return
}
if (isLocalModel && !isFromCortexHub) {
setOptions([
{
name: modelHandle ?? '',
value: modelHandle ?? '',
},
])
setSelectedVariant(modelHandle)
return
}
setOptions(
availableModels.map((variant) => ({
name: `${name}:${variant}`,
value: `${name}:${variant}`,
}))
)
if (availableModels.length > 0) {
setSelectedVariant(`${name}:${availableModels[0]}`)
}
}, [availableModels, name, modelHandle, isLocalModel])
const onCopyClicked = useCallback(() => { const onCopyClicked = useCallback(() => {
navigator.clipboard.writeText(textRef.current?.innerText ?? '') navigator.clipboard.writeText(textRef.current?.innerText ?? '')
@ -38,6 +71,8 @@ const HeaderModal: React.FC<Props> = ({
const title = name.charAt(0).toUpperCase() + name.slice(1) const title = name.charAt(0).toUpperCase() + name.slice(1)
if (!selectedVariant) return null
return ( return (
<div className="flex items-center"> <div className="flex items-center">
<span className="text-xl font-semibold leading-8">{title}</span> <span className="text-xl font-semibold leading-8">{title}</span>

View File

@ -33,14 +33,16 @@ import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
type Props = { type Props = {
modelHandle: string modelHandle: string
onBranchSelected?: (availableSelections: string[]) => void
} }
const ListModel: React.FC<Props> = ({ modelHandle }) => { const ListModel: React.FC<Props> = ({ modelHandle, onBranchSelected }) => {
const { data: engineData } = useEngineQuery() const { data: engineData } = useEngineQuery()
const { data, isLoading } = useHfEngineToBranchesQuery(modelHandle)
const [engineFilter, setEngineFilter] = useState<EngineType | undefined>( const [engineFilter, setEngineFilter] = useState<EngineType | undefined>(
undefined undefined
) )
const { data, isLoading } = useHfEngineToBranchesQuery(modelHandle)
const engineSelections: { name: string; value: string }[] = useMemo(() => { const engineSelections: { name: string; value: string }[] = useMemo(() => {
if (!data || !engineData) return [] if (!data || !engineData) return []
@ -63,17 +65,26 @@ const ListModel: React.FC<Props> = ({ modelHandle }) => {
return result return result
}, [data, engineData]) }, [data, engineData])
const modelBranches: CortexHubModel[] = useMemo((): CortexHubModel[] => {
if (!data) return []
return (data[engineFilter as EngineType] as CortexHubModel[]) ?? []
}, [data, engineFilter])
useEffect(() => { useEffect(() => {
if (engineSelections.length === 0) return if (engineSelections.length === 0) return
setEngineFilter(engineSelections[0].value as EngineType) setEngineFilter(engineSelections[0].value as EngineType)
}, [engineSelections]) const models = modelBranches.map((m) => m.name)
onBranchSelected?.(models)
}, [engineSelections, modelBranches, onBranchSelected])
const modelBranches: CortexHubModel[] = [] const onSelectionChanged = useCallback(
if (data) { (selectionValue: string) => {
const branches = data[engineFilter as EngineType] as CortexHubModel[] setEngineFilter(selectionValue as EngineType)
if (!branches || branches.length === 0) return const models = modelBranches.map((m) => m.name)
modelBranches.push(...branches) onBranchSelected?.(models)
} },
[setEngineFilter, onBranchSelected, modelBranches]
)
if (isLoading) if (isLoading)
return ( return (
@ -90,7 +101,7 @@ const ListModel: React.FC<Props> = ({ modelHandle }) => {
value={engineFilter} value={engineFilter}
className="gap-1.5 whitespace-nowrap px-4 py-2 font-semibold" className="gap-1.5 whitespace-nowrap px-4 py-2 font-semibold"
options={engineSelections} options={engineSelections}
onValueChange={(value) => setEngineFilter(value as EngineType)} onValueChange={onSelectionChanged}
/> />
</div> </div>
<div className="mt-3 w-full overflow-hidden rounded-md border border-[hsla(var(--app-border))]"> <div className="mt-3 w-full overflow-hidden rounded-md border border-[hsla(var(--app-border))]">

View File

@ -31,8 +31,7 @@ const SetUpRemoteModelModal: React.FC = () => {
<HeaderModal <HeaderModal
name={modelName} name={modelName}
onActionClick={navigateToSetUpApiKey} onActionClick={navigateToSetUpApiKey}
modelId={modelId} availableModels={[modelId]}
modelIdVariants={[modelId]}
/> />
<ModelTitle <ModelTitle
className="text-[hsla(var(--text-secondary)] my-4" className="text-[hsla(var(--text-secondary)] my-4"

View File

@ -20,7 +20,6 @@ const ImportingModelItem = ({ model }: Props) => {
}, []) }, [])
const onDeleteModelClick = useCallback(() => {}, []) const onDeleteModelClick = useCallback(() => {}, [])
console.log('namh model', model)
const displayStatus = useMemo(() => { const displayStatus = useMemo(() => {
if (model.status === 'FAILED') { if (model.status === 'FAILED') {
return 'Failed' return 'Failed'

View File

@ -29,14 +29,6 @@ const ImportingModelModal = () => {
const importModels = async () => { const importModels = async () => {
for (const model of importingModels) { for (const model of importingModels) {
await downloadModel(model.path) await downloadModel(model.path)
// const parsedResult = await result?.json()
// if (
// parsedResult['message'] &&
// parsedResult['message'] === 'Download model started successfully.'
// ) {
// // update importingModels
// }
// console.log(`NamH result ${JSON.stringify(parsedResult)}`)
} }
} }
importModels() importModels()