import React, { Fragment, useCallback, useState } from 'react'
import Image from 'next/image'
import { Model, RemoteEngine, RemoteEngines } from '@janhq/core'
import { Input } from '@janhq/joi'
import { useSetAtom } from 'jotai'
import { SearchIcon, PlusIcon } from 'lucide-react'
import { twMerge } from 'tailwind-merge'
import Spinner from '@/containers/Loader/Spinner'
import useModelHub from '@/hooks/useModelHub'
import BuiltInModelCard from '@/screens/HubScreen2/components/BuiltInModelCard'
import { HfModelEntry } from '@/utils/huggingface'
import { getTitleByCategory } from '@/utils/model-engine'
import { MainViewState, mainViewStateAtom } from '@/helpers/atoms/App.atom'
import { localModelModalStageAtom } from '@/helpers/atoms/DownloadLocalModel.atom'
import { hubFilterAtom } from '@/helpers/atoms/Hub.atom'
import { setUpRemoteModelStageAtom } from '@/helpers/atoms/SetupRemoteModel.atom'
const OnDeviceStarterScreen = () => {
const { data } = useModelHub()
const [searchValue, setSearchValue] = useState('')
const setLocalModelModalStage = useSetAtom(localModelModalStageAtom)
const setUpRemoteModelStage = useSetAtom(setUpRemoteModelStageAtom)
const setMainViewState = useSetAtom(mainViewStateAtom)
const setFilter = useSetAtom(hubFilterAtom)
const onItemClick = useCallback(
(name: string) => {
setLocalModelModalStage('MODEL_LIST', name)
},
[setLocalModelModalStage]
)
if (!data)
return (
)
const builtInModels: HfModelEntry[] =
data.modelCategories.get('BuiltInModels') || []
const huggingFaceModels: HfModelEntry[] =
data.modelCategories.get('HuggingFace') || []
const engineModelMap = new Map()
for (const [key, value] of data.modelCategories) {
if (key !== 'HuggingFace' && key !== 'BuiltInModels') {
engineModelMap.set(key as unknown as typeof RemoteEngines, value)
}
}
const models: HfModelEntry[] = builtInModels.concat(huggingFaceModels)
const filteredModels = models.filter((model) => {
return model.name.toLowerCase().includes(searchValue.toLowerCase())
})
const recommendModels = models.filter((model) => {
return (
model.name.toLowerCase().includes('cortexso/tinyllama') ||
model.name.toLowerCase().includes('cortexso/mistral')
)
})
return (
setSearchValue(e.target.value)}
placeholder="Search..."
prefixIcon={
}
/>
{!filteredModels.length ? (
) : (
filteredModels.map((model) => (
onItemClick(model.name)}
>
{model.name.replaceAll('cortexso/', '')}
))
)}
On-device Models
{
setFilter('On-device')
setMainViewState(MainViewState.Hub)
}}
>
See All
{recommendModels.map((model) => (
))}
Cloud Models
{Array.from(engineModelMap.entries())
.slice(0, 3)
.map(([engine, models]) => {
const engineLogo: string | undefined = models.find(
(entry) => entry.model?.metadata?.logo != null
)?.model?.metadata?.logo
const apiKeyUrl: string | undefined = models.find(
(entry) => entry.model?.metadata?.api_key_url != null
)?.model?.metadata?.api_key_url
const defaultModel: Model | undefined = models.find(
(entry) => entry.model != null
)?.model
return (
{
setUpRemoteModelStage(
'SETUP_API_KEY',
engine as unknown as RemoteEngine,
{
logo: engineLogo,
api_key_url: apiKeyUrl,
model: defaultModel,
}
)
}}
>
{engineLogo ? (
) : (
)}
{getTitleByCategory(engine as unknown as RemoteEngine)}
)
})}
{
setFilter('Cloud')
setMainViewState(MainViewState.Hub)
}}
>
See All
)
}
export default OnDeviceStarterScreen