import { useCallback, useEffect, useState } from 'react' import { Compatibility, GpuSetting, InstallationState, abortDownload, systemInformation, } from '@janhq/core' import { Badge, Button, Progress, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipTrigger, } from '@janhq/uikit' import { InfoCircledIcon } from '@radix-ui/react-icons' import { useAtomValue } from 'jotai' import { Marked, Renderer } from 'marked' import UpdateExtensionModal from './UpdateExtensionModal' import { extensionManager } from '@/extension' import Extension from '@/extension/Extension' import { installingExtensionAtom } from '@/helpers/atoms/Extension.atom' type Props = { item: Extension } const TensorRtExtensionItem: React.FC = ({ item }) => { const [compatibility, setCompatibility] = useState( undefined ) const [installState, setInstallState] = useState('NotRequired') const installingExtensions = useAtomValue(installingExtensionAtom) const [isGpuSupported, setIsGpuSupported] = useState(false) const [promptUpdateModal, setPromptUpdateModal] = useState(false) const isInstalling = installingExtensions.some( (e) => e.extensionId === item.name ) const progress = isInstalling ? installingExtensions.find((e) => e.extensionId === item.name) ?.percentage ?? -1 : -1 useEffect(() => { const getSystemInfos = async () => { const info = await systemInformation() if (!info) { setIsGpuSupported(false) return } const gpuSettings: GpuSetting | undefined = info.gpuSetting if (!gpuSettings || gpuSettings.gpus.length === 0) { setIsGpuSupported(false) return } const arch = gpuSettings.gpus[0].arch if (!arch) { setIsGpuSupported(false) return } const supportedGpuArch = ['ampere', 'ada'] setIsGpuSupported(supportedGpuArch.includes(arch)) } getSystemInfos() }, []) useEffect(() => { const getExtensionInstallationState = async () => { const extension = extensionManager.get(item.name ?? '') if (!extension) return if (typeof extension?.installationState === 'function') { const installState = await extension.installationState() setInstallState(installState) } } getExtensionInstallationState() }, [item.name, isInstalling]) useEffect(() => { const extension = extensionManager.get(item.name ?? '') if (!extension) return setCompatibility(extension.compatibility()) }, [setCompatibility, item.name]) const onInstallClick = useCallback(async () => { const extension = extensionManager.get(item.name ?? '') if (!extension) return await extension.install() }, [item.name]) const onCancelInstallingClick = () => { const extension = installingExtensions.find( (e) => e.extensionId === item.name ) if (extension?.localPath) { abortDownload(extension.localPath) } } const description = marked.parse(item.description ?? '', { async: false }) return (
TensorRT-LLM Extension

v{item.version}

Experimental
{ // eslint-disable-next-line @typescript-eslint/naming-convention
}
{(!compatibility || compatibility['platform']?.includes(PLATFORM)) && isGpuSupported ? (
setPromptUpdateModal(true)} onCancelClick={onCancelInstallingClick} />
) : (
Incompatible{' '} {compatibility && !compatibility['platform']?.includes(PLATFORM) ? ( Only available on{' '} {compatibility?.platform ?.map((e: string) => e === 'win32' ? 'Windows' : e === 'linux' ? 'Linux' : 'MacOS' ) .join(', ')} ) : ( Your GPUs are not compatible with this extension )}
)} {promptUpdateModal && ( )}
) } type InstallStateProps = { installProgress: number installState: InstallationState onInstallClick: () => void onUpdateClick: () => void onCancelClick: () => void } const InstallStateIndicator: React.FC = ({ installProgress, installState, onInstallClick, onUpdateClick, onCancelClick, }) => { if (installProgress !== -1) { const progress = installProgress * 100 return (
{progress.toFixed(0)}%
) } switch (installState) { case 'Installed': return (
Installed
) case 'Updatable': return ( ) case 'NotInstalled': return ( ) default: return
} } const marked: Marked = new Marked({ renderer: { link: (href, title, text) => { return Renderer.prototype.link ?.apply(this, [href, title, text]) .replace('