NamH 101268f6f3
feat: integrating cortex (#3001)
* feat: integrating cortex

* Temporary prevent crash

Signed-off-by: James <namnh0122@gmail.com>

* fix yarn lint

Signed-off-by: James <namnh0122@gmail.com>

* refactor: remove core node module - fs - extensions and so on (#3151)

* add migration script for threads, messages and models

Signed-off-by: James <namnh0122@gmail.com>

* remove freq_penalty and presence_penalty if model not supported

Signed-off-by: James <namnh0122@gmail.com>

* add back models in my models

Signed-off-by: James <namnh0122@gmail.com>

* fix api-url for setup API key popup

Signed-off-by: James <namnh0122@gmail.com>

* fix using model name for dropdown model

Signed-off-by: James <namnh0122@gmail.com>

* fix can't click to hotkey

Signed-off-by: James <namnh0122@gmail.com>

* fix: disable some UIs

Signed-off-by: James <namnh0122@gmail.com>

* fix build

Signed-off-by: James <namnh0122@gmail.com>

* reduce calling HF api

Signed-off-by: James <namnh0122@gmail.com>

* some ui update

Signed-off-by: James <namnh0122@gmail.com>

* feat: modal migration UI  (#3153)

* feat: handle popup migration

* chore: update loader

* chore: integrate script migration

* chore: cleanup import

* chore: moving out spinner loader

* chore: update check thread message success migrate

* chore: add handle script into retry button

* remove warning from joi

Signed-off-by: James <namnh0122@gmail.com>

* chore: fix duplicate children

* fix: path after migrating model

Signed-off-by: James <namnh0122@gmail.com>

* chore: apply mutation for config

* chore: prevent calling too many create assistant api

Signed-off-by: James <namnh0122@gmail.com>

* using cortexso

Signed-off-by: James <namnh0122@gmail.com>

* update download api

Signed-off-by: James <namnh0122@gmail.com>

* fix use on slider item

Signed-off-by: James <namnh0122@gmail.com>

* fix: ui no download model or simple onboarding (#3166)

* fix download huggingface model match with slider item

Signed-off-by: James <namnh0122@gmail.com>

* update owner_logo to logo and author

Signed-off-by: James <namnh0122@gmail.com>

* update new cortexso

Signed-off-by: James <namnh0122@gmail.com>

* Add install python step for macos

* add engine table

Signed-off-by: James <namnh0122@gmail.com>

* fix local icons

Signed-off-by: James <namnh0122@gmail.com>

* feat: add search feature for model hub

Signed-off-by: James <namnh0122@gmail.com>

* fix misalign switch

Signed-off-by: James <namnh0122@gmail.com>

* fix: delete thread not focus on other thread

Signed-off-by: James <namnh0122@gmail.com>

* add get model from hugging face

Signed-off-by: James <namnh0122@gmail.com>

* fix download from hugging face

Signed-off-by: James <namnh0122@gmail.com>

* small update

Signed-off-by: James <namnh0122@gmail.com>

* update

Signed-off-by: James <namnh0122@gmail.com>

* fix system monitor rounded only on the left

Signed-off-by: James <namnh0122@gmail.com>

* chore: update ui new hub screen (#3174)

* chore: update ui new hub screen

* chore: update layout centerpanel thread and hub screen

* chore: update detail model by group

* update cortexso 0.1.13

Signed-off-by: James <namnh0122@gmail.com>

* chore: add file size

Signed-off-by: James <namnh0122@gmail.com>

* chore: put engine to experimental feature

Signed-off-by: James <namnh0122@gmail.com>

* chore: open cortex folder

Signed-off-by: James <namnh0122@gmail.com>

* chore: add back user avatar

Signed-off-by: James <namnh0122@gmail.com>

* chore: minor UI hub (#3182)

* chore: add back right click thread list and update 3 dots are overlapping with the text

* chore: update position dropdown list my models

* chore: make on-device tab showing 6 items instead of 4

* chore: update style description modals detail model

* chore: update isGeneration loader and author name on modal

* feat: integrate cortex single executable

Signed-off-by: James <namnh0122@gmail.com>

* fix build

Signed-off-by: James <namnh0122@gmail.com>

* chore: added blank state

* chore: update ui component blank state

* bump cortex binary version

* fix: logic show modal migration (#3165)

* fix: logic show modal migration

* chore: fixed logic

* chore: read contain format gguf local models

* chore: change return hasLocalModel

* chore: intiial skipmigration state

* chore: filter embedding model

* fix: delete top thread not focus on any other thread

* chore: added UI no result component search models group (#3188)

* fix: remote model should show all when user config that engine

Signed-off-by: James <namnh0122@gmail.com>

* chore: set state thread and models migration using getOnInit (#3189)

* chore: set state thread and models migration using getOnInit

* chore: add state as dependecies hooks

* chore: system monitor panel show engine model (#3192)

* fix: remove config api, replace with engine

Signed-off-by: James <namnh0122@gmail.com>

* update

Signed-off-by: James <namnh0122@gmail.com>

* update reactquery

Signed-off-by: James <namnh0122@gmail.com>

* bump cortex 0.4.35

* feat: add waiting for cortex popup

Signed-off-by: James <namnh0122@gmail.com>

* chore: add loader detail model popup (#3195)

* chore: model start loader (#3197)

* chore: added model loader when user starting chat without model active

* chore: update copies loader

* fix: select min file size if recommended quant does not exist

Signed-off-by: James <namnh0122@gmail.com>

* chore: temporary hide gpu config

* fix: tensorrt not shown

Signed-off-by: James <namnh0122@gmail.com>

* fix lint

Signed-off-by: James <namnh0122@gmail.com>

* fix tests

Signed-off-by: James <namnh0122@gmail.com>

* fix e2e tests (wip)

Signed-off-by: James <namnh0122@gmail.com>

* update

Signed-off-by: James <namnh0122@gmail.com>

* fix: adding element and correct test to adapt new UI

* fix: temp skip unstable part

* fix: only show models which can be supported

Signed-off-by: James <namnh0122@gmail.com>

* Update version.txt

* update send message

Signed-off-by: James <namnh0122@gmail.com>

* fix: not allow user send message when is generating

Signed-off-by: James <namnh0122@gmail.com>

* chore: temp skip Playwright test due to env issue

* chore: temp skip Playwright test due to env issue

* update

Signed-off-by: James <namnh0122@gmail.com>

* chore: minor-ui-feedback (#3202)

---------

Signed-off-by: James <namnh0122@gmail.com>
Co-authored-by: Louis <louis@jan.ai>
Co-authored-by: Faisal Amir <urmauur@gmail.com>
Co-authored-by: Hien To <tominhhien97@gmail.com>
Co-authored-by: Van Pham <64197333+Van-QA@users.noreply.github.com>
Co-authored-by: Van-QA <van@jan.ai>
2024-07-26 17:52:43 +07:00

181 lines
6.0 KiB
TypeScript

import { memo, useCallback, useMemo, useState } from 'react'
import { LocalEngines, Model } from '@janhq/core'
import { Badge, Button, useClickOutside } from '@janhq/joi'
import { useAtomValue } from 'jotai'
import {
MoreVerticalIcon,
PlayIcon,
StopCircleIcon,
Trash2Icon,
} from 'lucide-react'
import { twMerge } from 'tailwind-merge'
import useModelStart from '@/hooks/useModelStart'
import useModels from '@/hooks/useModels'
import { activeModelsAtom } from '@/helpers/atoms/Model.atom'
type Props = {
model: Model
}
const ModelItem: React.FC<Props> = ({ model }) => {
const activeModels = useAtomValue(activeModelsAtom)
const startModel = useModelStart()
const [more, setMore] = useState(false)
const { stopModel, deleteModel } = useModels()
const [menu, setMenu] = useState<HTMLDivElement | null>(null)
const [toggle, setToggle] = useState<HTMLDivElement | null>(null)
useClickOutside(() => setMore(false), null, [menu, toggle])
const isActive = useMemo(
() => activeModels.map((m) => m.model).includes(model.model),
[activeModels, model.model]
)
const onModelActionClick = useCallback(
(modelId: string) => {
if (isActive) {
stopModel(modelId)
} else {
startModel.mutate(modelId)
}
},
[isActive, startModel, stopModel]
)
const onDeleteModelClicked = useCallback(
async (modelId: string) => {
await stopModel(modelId)
await deleteModel(modelId)
},
[stopModel, deleteModel]
)
const isLocalModel = LocalEngines.find(
(e) => model.engine != null && e === model.engine
)
return (
<div className="border border-b-0 border-[hsla(var(--app-border))] bg-[hsla(var(--tertiary-bg))] p-4 first:rounded-t-lg last:rounded-b-lg last:border-b">
<div className="flex flex-col items-start justify-start gap-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex w-1/2 gap-x-8">
<div className="flex w-full items-center justify-between">
<h6
className={twMerge(
'line-clamp-1 max-w-[200px] font-medium',
model.engine !== 'cortex.llamacpp' &&
'max-w-none text-[hsla(var(--text-secondary))]'
)}
title={model.model}
>
{model.model}
</h6>
{model.engine === 'cortex.llamacpp' && (
<div className="flex gap-x-8">
<p
className="line-clamp-1 max-w-[120px] text-[hsla(var(--text-secondary))] xl:max-w-none"
title={model.model}
>
{model.model}
</p>
</div>
)}
</div>
</div>
{isLocalModel && (
<div className="flex gap-x-4">
<Badge theme="secondary" className="sm:mr-16">
{model.version != null ? `v${model.version}` : '-'}
</Badge>
<div className="relative flex items-center gap-x-4">
{isActive ? (
<Badge
theme="success"
variant="soft"
className="inline-flex items-center space-x-2"
>
<span className="h-2 w-2 rounded-full bg-green-500" />
<span>Active</span>
</Badge>
) : (
<Badge
theme="secondary"
className="inline-flex items-center space-x-2"
>
<span className="h-2 w-2 rounded-full bg-gray-500" />
<span>Inactive</span>
</Badge>
)}
<div
className="inline-flex cursor-pointer"
ref={setToggle}
onClick={() => {
setMore(!more)
}}
>
<Button theme="icon">
<MoreVerticalIcon />
</Button>
{more && (
<div
className="shadow-lg absolute right-8 top-0 z-20 w-52 overflow-hidden rounded-lg border border-[hsla(var(--app-border))] bg-[hsla(var(--app-bg))]"
ref={setMenu}
>
<div
className={twMerge(
'flex items-center space-x-2 px-4 py-2 hover:bg-[hsla(var(--dropdown-menu-hover-bg))]'
)}
onClick={() => {
onModelActionClick(model.model)
setMore(false)
}}
>
{isActive ? (
<StopCircleIcon
size={16}
className="text-[hsla(var(--text-secondary))]"
/>
) : (
<PlayIcon
size={16}
className="text-[hsla(var(--text-secondary))]"
/>
)}
<span className="text-bold capitalize">
{isActive ? 'Stop' : 'Start'}
&nbsp;Model
</span>
</div>
<div
className={twMerge(
'flex cursor-pointer items-center space-x-2 px-4 py-2 hover:bg-[hsla(var(--dropdown-menu-hover-bg))]'
)}
onClick={() => onDeleteModelClicked(model.model)}
>
<Trash2Icon
size={16}
className="text-[hsla(var(--destructive-bg))]"
/>
<span className="text-bold text-[hsla(var(--destructive-bg))]">
Delete Model
</span>
</div>
</div>
)}
</div>
</div>
</div>
)}
</div>
</div>
)
}
export default memo(ModelItem)