/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useCallback, useEffect, useMemo, useState } from 'react' import { DownloadEvent, EngineEvent, events, InferenceEngine, } from '@janhq/core' import { Button, ScrollArea, Badge, Select, Progress } from '@janhq/joi' import { useAtom, useAtomValue } from 'jotai' import { twMerge } from 'tailwind-merge' import { useActiveModel } from '@/hooks/useActiveModel' import { useGetDefaultEngineVariant, useGetInstalledEngines, useGetLatestReleasedEngine, setDefaultEngineVariant, installEngine, updateEngine, useGetReleasedEnginesByVersion, } from '@/hooks/useEngineManagement' import { formatDownloadPercentage } from '@/utils/converter' import ExtensionSetting from '../ExtensionSetting' import DeleteEngineVariant from './DeleteEngineVariant' import { LocalEngineDefaultVariantAtom, RecommendEngineVariantAtom, } from '@/helpers/atoms/App.atom' import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom' const os = () => { switch (PLATFORM) { case 'win32': return 'windows' case 'linux': return 'linux' default: return 'mac' } } const LocalEngineSettings = ({ engine }: { engine: InferenceEngine }) => { const { installedEngines, mutate: mutateInstalledEngines } = useGetInstalledEngines(engine) const { defaultEngineVariant, mutate: mutateDefaultEngineVariant } = useGetDefaultEngineVariant(engine) const { latestReleasedEngine } = useGetLatestReleasedEngine(engine, os()) const { releasedEnginesByVersion } = useGetReleasedEnginesByVersion( engine, defaultEngineVariant?.version as string, os() ) const showScrollBar = useAtomValue(showScrollBarAtom) const [installingEngines, setInstallingEngines] = useState< Map >(new Map()) const { stopModel } = useActiveModel() const [recommendEngineVariant, setRecommendEngineVariant] = useAtom( RecommendEngineVariantAtom ) const isEngineUpdated = latestReleasedEngine && latestReleasedEngine.some((item) => item.name.includes( defaultEngineVariant?.version.replace(/^v/, '') as string ) ) const availableVariants = useMemo( () => latestReleasedEngine?.map((e) => e.name.replace( `${defaultEngineVariant?.version.replace(/^v/, '') as string}-`, '' ) ), [latestReleasedEngine, defaultEngineVariant] ) const options = installedEngines && installedEngines .filter((x: any) => x.version === defaultEngineVariant?.version) .map((x: any) => ({ name: x.name, value: x.name, recommend: recommendEngineVariant === x.name, })) const installedEngineByVersion = installedEngines?.filter( (x: any) => x.version === defaultEngineVariant?.version ) const [selectedVariants, setSelectedVariants] = useAtom( LocalEngineDefaultVariantAtom ) const selectedVariant = useMemo( () => options?.map((e) => e.value).includes(selectedVariants) ? selectedVariants : undefined, [selectedVariants, options] ) useEffect(() => { if (defaultEngineVariant?.variant) { setSelectedVariants(defaultEngineVariant.variant || '') } if (!recommendEngineVariant.length) { setRecommendEngineVariant(defaultEngineVariant?.variant || '') } }, [defaultEngineVariant, setSelectedVariants, setRecommendEngineVariant]) const handleEngineUpdate = useCallback( async (event: { id: string; type: DownloadEvent; percent: number }) => { await stopModel().catch(console.info) mutateInstalledEngines() mutateDefaultEngineVariant() // Backward compatible support - cortex.cpp returns full variant file name const variant: string | undefined = event.id.includes('.tar.gz') ? availableVariants?.find((e) => event.id.includes(`${e}.tar.gz`)) : availableVariants?.find((e) => event.id.includes(e)) if (!variant) { console.error( 'Variant not found for event.id:', event.id, availableVariants ) return } // Clone the existing Map to ensure immutability setInstallingEngines((prev) => { const updated = new Map(prev) if ( event.type === DownloadEvent.onFileDownloadError || event.type === DownloadEvent.onFileDownloadStopped || event.type === DownloadEvent.onFileDownloadSuccess ) { // Remove the variant from the Map if download stops/errors/succeeds updated.delete(variant) } else { // Update the variant with the new percentage updated.set(variant, event.percent) } return updated }) }, [ stopModel, mutateDefaultEngineVariant, mutateInstalledEngines, setInstallingEngines, availableVariants, ] ) useEffect(() => { events.on(EngineEvent.OnEngineUpdate, handleEngineUpdate) return () => { events.off(EngineEvent.OnEngineUpdate, handleEngineUpdate) } }, [handleEngineUpdate]) const handleChangeVariant = async (e: string) => { await stopModel().catch(console.info) setSelectedVariants(e) setDefaultEngineVariant(engine, { variant: e, version: String(defaultEngineVariant?.version), }) } return (
Engine Version
{defaultEngineVariant?.version}
Check Updates
{engine} Backend

Choose the default variant that best suited for your hardware. See  our guides.