import React, { useCallback, useEffect, useState } from 'react' import Image from 'next/image' import { EngineStatus, LlmEngine, LocalEngine, Model, RemoteEngine, RemoteEngines, } from '@janhq/core' import { Button } from '@janhq/joi' import { useAtom, useSetAtom } from 'jotai' import { SettingsIcon, ChevronDownIcon, ChevronUpIcon, PlusIcon, } from 'lucide-react' import { twMerge } from 'tailwind-merge' import useEngineQuery from '@/hooks/useEngineQuery' import useGetModelsByEngine from '@/hooks/useGetModelsByEngine' import { getLogoByLocalEngine, getLogoByRemoteEngine, getTitleByCategory, } from '@/utils/model-engine' import ModelLabel from '../ModelLabel' import { showEngineListModelAtom } from '@/helpers/atoms/Model.atom' import { setUpRemoteModelStageAtom } from '@/helpers/atoms/SetupRemoteModel.atom' type Props = { engine: LlmEngine searchText: string onModelSelected: (model: Model) => void } const ModelSection: React.FC = ({ engine, searchText, onModelSelected, }) => { const [models, setModels] = useState([]) const { getModelsByEngine } = useGetModelsByEngine() const setUpRemoteModelStage = useSetAtom(setUpRemoteModelStageAtom) const { data: engineData } = useEngineQuery() const [showEngineListModel, setShowEngineListModel] = useAtom( showEngineListModelAtom ) const engineLogo: string | undefined = models.find( (entry) => entry?.metadata?.logo != null )?.metadata?.logo const apiKeyUrl: string | undefined = models.find( (entry) => entry?.metadata?.api_key_url != null )?.metadata?.api_key_url const onSettingClick = useCallback(() => { setUpRemoteModelStage('SETUP_API_KEY', engine as unknown as RemoteEngine, { logo: engineLogo, api_key_url: apiKeyUrl, }) }, [apiKeyUrl, engine, engineLogo, setUpRemoteModelStage]) const isEngineReady = engineData?.find((e) => e.name === engine)?.status === EngineStatus.Ready const getEngineStatusReady: LlmEngine[] | undefined = engineData ?.filter((e) => e.status === EngineStatus.Ready) .map((x) => x.name as LlmEngine) const showModel = showEngineListModel.includes(engine) const onClickChevron = useCallback(() => { if (showModel) { setShowEngineListModel((prev) => prev.filter((item) => item !== engine)) } else { setShowEngineListModel((prev) => [...prev, engine]) } }, [engine, setShowEngineListModel, showModel]) useEffect(() => { const matchedModels = getModelsByEngine(engine, searchText) setModels(matchedModels) setShowEngineListModel((prev) => [ ...prev, ...(getEngineStatusReady as LlmEngine[]), ]) // eslint-disable-next-line react-hooks/exhaustive-deps }, [getModelsByEngine, engine, searchText, setShowEngineListModel]) const engineName = getTitleByCategory(engine) const localEngineLogo = getLogoByLocalEngine(engine as LocalEngine) const remoteEngineLogo = getLogoByRemoteEngine(engine as RemoteEngine) const isRemoteEngine = RemoteEngines.includes(engine as RemoteEngine) if (models.length === 0) return null return (
{!isRemoteEngine && localEngineLogo && ( logo )} {remoteEngineLogo && ( {`logo )}
{engineName}
{isRemoteEngine && ( )} {!showModel ? ( ) : ( )}
    {models.map((model) => { if (!showModel) return null return (
  • { onModelSelected(model) }} >

    {model.name ?? model.model}

  • ) })}
) } export default ModelSection