fix: user can't use a model in model hub (#1801)

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>
This commit is contained in:
NamH 2024-01-26 14:41:42 +07:00 committed by GitHub
parent bdebbca9b5
commit 9fa28d2275
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 61 additions and 60 deletions

View File

@ -36,23 +36,22 @@ import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
import {
ModelParams,
activeThreadAtom,
getActiveThreadIdAtom,
setThreadModelParamsAtom,
threadStatesAtom,
} from '@/helpers/atoms/Thread.atom'
export const selectedModelAtom = atom<Model | undefined>(undefined)
export default function DropdownListSidebar() {
const activeThreadId = useAtomValue(getActiveThreadIdAtom)
const DropdownListSidebar: React.FC = () => {
const activeThread = useAtomValue(activeThreadAtom)
const threadStates = useAtomValue(threadStatesAtom)
const [selectedModel, setSelectedModel] = useAtom(selectedModelAtom)
const setThreadModelParams = useSetAtom(setThreadModelParamsAtom)
const { activeModel, stateModel } = useActiveModel()
const { stateModel } = useActiveModel()
const [serverEnabled, setServerEnabled] = useAtom(serverEnabledAtom)
const { setMainViewState } = useMainViewState()
const [loader, setLoader] = useState(0)
const { recommendedModel, downloadedModels } = useRecommendedModel()
/**
@ -65,38 +64,41 @@ export default function DropdownListSidebar() {
}
useEffect(() => {
setSelectedModel(selectedModel || activeModel || recommendedModel)
if (!activeThread) return
if (activeThread) {
const finishInit = threadStates[activeThread.id].isFinishInit ?? true
if (finishInit) return
const modelParams: ModelParams = {
...recommendedModel?.parameters,
...recommendedModel?.settings,
/**
* This is to set default value for these settings instead of maximum value
* Should only apply when model.json has these settings
*/
...(recommendedModel?.parameters.max_tokens && {
max_tokens: defaultValue(recommendedModel?.parameters.max_tokens),
}),
...(recommendedModel?.settings.ctx_len && {
ctx_len: defaultValue(recommendedModel?.settings.ctx_len),
}),
}
setThreadModelParams(activeThread.id, modelParams)
let model = downloadedModels.find(
(model) => model.id === activeThread.assistants[0].model.id
)
if (!model) {
model = recommendedModel
}
// eslint-disable-next-line react-hooks/exhaustive-deps
setSelectedModel(model)
const finishInit = threadStates[activeThread.id].isFinishInit ?? true
if (finishInit) return
const modelParams: ModelParams = {
...model?.parameters,
...model?.settings,
/**
* This is to set default value for these settings instead of maximum value
* Should only apply when model.json has these settings
*/
...(model?.parameters.max_tokens && {
max_tokens: defaultValue(model?.parameters.max_tokens),
}),
...(model?.settings.ctx_len && {
ctx_len: defaultValue(model?.settings.ctx_len),
}),
}
setThreadModelParams(activeThread.id, modelParams)
}, [
recommendedModel,
activeThread,
setSelectedModel,
setThreadModelParams,
threadStates,
downloadedModels,
setThreadModelParams,
setSelectedModel,
])
const [loader, setLoader] = useState(0)
// This is fake loader please fix this when we have realtime percentage when load model
useEffect(() => {
if (stateModel.loading) {
@ -132,20 +134,20 @@ export default function DropdownListSidebar() {
setServerEnabled(false)
}
if (activeThreadId) {
if (activeThread) {
const modelParams = {
...model?.parameters,
...model?.settings,
}
setThreadModelParams(activeThreadId, modelParams)
setThreadModelParams(activeThread.id, modelParams)
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[
downloadedModels,
serverEnabled,
activeThreadId,
activeModel,
activeThread,
setSelectedModel,
setServerEnabled,
setThreadModelParams,
]
)
@ -236,10 +238,9 @@ export default function DropdownListSidebar() {
</Select>
</div>
<OpenAiKeyInput
selectedModel={selectedModel}
serverEnabled={serverEnabled}
/>
<OpenAiKeyInput />
</>
)
}
export default DropdownListSidebar

View File

@ -1,16 +1,19 @@
import React, { useEffect, useState } from 'react'
import { InferenceEngine, Model } from '@janhq/core'
import { InferenceEngine } from '@janhq/core'
import { Input } from '@janhq/uikit'
import { useAtomValue } from 'jotai'
import { useEngineSettings } from '@/hooks/useEngineSettings'
type Props = {
selectedModel?: Model
serverEnabled: boolean
}
import { selectedModelAtom } from '../DropdownListSidebar'
const OpenAiKeyInput: React.FC<Props> = ({ selectedModel, serverEnabled }) => {
import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
const OpenAiKeyInput: React.FC = () => {
const selectedModel = useAtomValue(selectedModelAtom)
const serverEnabled = useAtomValue(serverEnabledAtom)
const [openAISettings, setOpenAISettings] = useState<
{ api_key: string } | undefined
>(undefined)
@ -20,8 +23,7 @@ const OpenAiKeyInput: React.FC<Props> = ({ selectedModel, serverEnabled }) => {
readOpenAISettings().then((settings) => {
setOpenAISettings(settings)
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
}, [readOpenAISettings])
if (!selectedModel || selectedModel.engine !== InferenceEngine.openai) {
return null

View File

@ -1,7 +1,9 @@
import { useCallback } from 'react'
import { fs, joinPath, events, AppConfigurationEventName } from '@janhq/core'
export const useEngineSettings = () => {
const readOpenAISettings = async () => {
const readOpenAISettings = useCallback(async () => {
if (
!(await fs.existsSync(await joinPath(['file://engines', 'openai.json'])))
)
@ -14,7 +16,8 @@ export const useEngineSettings = () => {
return typeof settings === 'object' ? settings : JSON.parse(settings)
}
return {}
}
}, [])
const saveOpenAISettings = async ({
apiKey,
}: {

View File

@ -43,9 +43,7 @@ export default function useRecommendedModel() {
Model | undefined
> => {
const models = await getAndSortDownloadedModels()
if (!activeThread) {
return
}
if (!activeThread) return
const finishInit = threadStates[activeThread.id].isFinishInit ?? true
if (finishInit) {

View File

@ -140,10 +140,8 @@ const Sidebar: React.FC = () => {
</div>
</CardSidebar>
<CardSidebar title="Model">
<div className="px-2">
<div className="mt-4">
<DropdownListSidebar />
</div>
<div className="px-2 pt-4">
<DropdownListSidebar />
{componentDataRuntimeSetting.length !== 0 && (
<div className="mt-6">

View File

@ -29,6 +29,7 @@ import { ExternalLinkIcon, InfoIcon } from 'lucide-react'
import { twMerge } from 'tailwind-merge'
import CardSidebar from '@/containers/CardSidebar'
import DropdownListSidebar, {
selectedModelAtom,
} from '@/containers/DropdownListSidebar'
@ -66,7 +67,7 @@ const LocalServerScreen = () => {
const { openServerLog, clearServerLog } = useServerLog()
const { startModel, stateModel } = useActiveModel()
const [selectedModel] = useAtom(selectedModelAtom)
const selectedModel = useAtomValue(selectedModelAtom)
const [isCorsEnabled, setIsCorsEnabled] = useAtom(corsEnabledAtom)
const [isVerboseEnabled, setIsVerboseEnabled] = useAtom(verboseEnabledAtom)
@ -351,10 +352,8 @@ const LocalServerScreen = () => {
: 'w-0 translate-x-full opacity-0'
)}
>
<div className="px-4">
<div className="mt-4">
<DropdownListSidebar />
</div>
<div className="px-4 pt-4">
<DropdownListSidebar />
{componentDataEngineSetting.filter(
(x) => x.name === 'prompt_template'