fix: models load

This commit is contained in:
Louis 2024-11-18 18:22:09 +07:00
parent b8e521164b
commit e9fd7f4554
No known key found for this signature in database
GPG Key ID: 44FA9F4D33C37DE2
7 changed files with 53 additions and 43 deletions

View File

@ -113,7 +113,6 @@ export abstract class BaseExtension implements ExtensionType {
for (const model of models) { for (const model of models) {
ModelManager.instance().register(model) ModelManager.instance().register(model)
} }
events.emit(ModelEvent.OnModelsUpdate, {})
} }
/** /**

View File

@ -215,7 +215,9 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
// Delay for the state update from cortex.cpp // Delay for the state update from cortex.cpp
// Just to be sure // Just to be sure
setTimeout(() => { setTimeout(() => {
events.emit(ModelEvent.OnModelsUpdate, {}) events.emit(ModelEvent.OnModelsUpdate, {
fetch: true,
})
}, 500) }, 500)
} }
}) })

View File

@ -40,11 +40,6 @@ export default class JanModelExtension extends ModelExtension {
async onLoad() { async onLoad() {
this.registerSettings(SETTINGS) this.registerSettings(SETTINGS)
// Try get models from cortex.cpp
this.getModels().then((models) => {
this.registerModels(models)
})
// Listen to app download events // Listen to app download events
this.handleDesktopEvents() this.handleDesktopEvents()
} }
@ -163,19 +158,27 @@ export default class JanModelExtension extends ModelExtension {
(e) => e.engine === InferenceEngine.nitro (e) => e.engine === InferenceEngine.nitro
) )
await this.cortexAPI.getModels().then((models) => { /**
const existingIds = models.map((e) => e.id) * Fetch models from cortex.cpp
toImportModels = toImportModels.filter( */
(e: Model) => !existingIds.includes(e.id) && !e.settings?.vision_model var fetchedModels = await this.cortexAPI.getModels().catch(() => [])
)
}) // Checking if there are models to import
const existingIds = fetchedModels.map((e) => e.id)
toImportModels = toImportModels.filter(
(e: Model) => !existingIds.includes(e.id) && !e.settings?.vision_model
)
/**
* There is no model to import
* just return fetched models
*/
if (!toImportModels.length) return fetchedModels
console.log('To import models:', toImportModels.length) console.log('To import models:', toImportModels.length)
/** /**
* There are models to import * There are models to import
* do not return models from cortex.cpp yet */
* otherwise it will reset the app cache
* */
if (toImportModels.length > 0) { if (toImportModels.length > 0) {
// Import models // Import models
await Promise.all( await Promise.all(
@ -202,8 +205,6 @@ export default class JanModelExtension extends ModelExtension {
}) })
}) })
) )
return currentModels
} }
/** /**

View File

@ -29,17 +29,18 @@ const DataLoader: React.FC<Props> = ({ children }) => {
const setQuickAskEnabled = useSetAtom(quickAskEnabledAtom) const setQuickAskEnabled = useSetAtom(quickAskEnabledAtom)
const setJanDefaultDataFolder = useSetAtom(defaultJanDataFolderAtom) const setJanDefaultDataFolder = useSetAtom(defaultJanDataFolderAtom)
const setJanSettingScreen = useSetAtom(janSettingScreenAtom) const setJanSettingScreen = useSetAtom(janSettingScreenAtom)
const { loadDataModel } = useModels()
useThreads() useThreads()
useAssistants() useAssistants()
useGetSystemResources() useGetSystemResources()
useLoadTheme() useLoadTheme()
const { loadDataModel, isUpdated } = useModels()
useEffect(() => { useEffect(() => {
// Listen for model updates // Load data once
loadDataModel() loadDataModel()
}, [isUpdated, loadDataModel]) // eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useEffect(() => { useEffect(() => {
window.core?.api window.core?.api

View File

@ -112,8 +112,8 @@ const EventListenerWrapper = ({ children }: PropsWithChildren) => {
state.downloadState = 'end' state.downloadState = 'end'
setDownloadState(state) setDownloadState(state)
removeDownloadingModel(state.modelId) removeDownloadingModel(state.modelId)
events.emit(ModelEvent.OnModelsUpdate, { fetch: true })
} }
events.emit(ModelEvent.OnModelsUpdate, {})
}, },
[removeDownloadingModel, setDownloadState] [removeDownloadingModel, setDownloadState]
) )

View File

@ -43,7 +43,7 @@ const ModelImportListener = ({ children }: PropsWithChildren) => {
const onImportModelSuccess = useCallback( const onImportModelSuccess = useCallback(
(state: ImportingModel) => { (state: ImportingModel) => {
if (!state.modelId) return if (!state.modelId) return
events.emit(ModelEvent.OnModelsUpdate, {}) events.emit(ModelEvent.OnModelsUpdate, { fetch: true })
setImportingModelSuccess(state.importId, state.modelId) setImportingModelSuccess(state.importId, state.modelId)
}, },
[setImportingModelSuccess] [setImportingModelSuccess]

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef } from 'react' import { useCallback, useEffect } from 'react'
import { import {
ExtensionTypeEnum, ExtensionTypeEnum,
@ -9,7 +9,7 @@ import {
ModelManager, ModelManager,
} from '@janhq/core' } from '@janhq/core'
import { useSetAtom } from 'jotai' import { useSetAtom, useAtom } from 'jotai'
import { useDebouncedCallback } from 'use-debounce' import { useDebouncedCallback } from 'use-debounce'
@ -27,17 +27,11 @@ import {
* and updates the atoms accordingly. * and updates the atoms accordingly.
*/ */
const useModels = () => { const useModels = () => {
const setDownloadedModels = useSetAtom(downloadedModelsAtom) const [downloadedModels, setDownloadedModels] = useAtom(downloadedModelsAtom)
const setExtensionModels = useSetAtom(configuredModelsAtom) const setExtensionModels = useSetAtom(configuredModelsAtom)
const hasFetchedDownloadedModels = useRef(false) // Track whether the function has been executed
let isUpdated = false
const getData = useCallback(() => { const getData = useCallback(() => {
if (hasFetchedDownloadedModels.current) return
const getDownloadedModels = async () => { const getDownloadedModels = async () => {
hasFetchedDownloadedModels.current = true
const localModels = (await getModels()).map((e) => ({ const localModels = (await getModels()).map((e) => ({
...e, ...e,
name: ModelManager.instance().models.get(e.id)?.name ?? e.id, name: ModelManager.instance().models.get(e.id)?.name ?? e.id,
@ -58,6 +52,8 @@ const useModels = () => {
setDownloadedModels(toUpdate) setDownloadedModels(toUpdate)
let isUpdated = false
toUpdate.forEach((model) => { toUpdate.forEach((model) => {
if (!ModelManager.instance().models.has(model.id)) { if (!ModelManager.instance().models.has(model.id)) {
ModelManager.instance().models.set(model.id, model) ModelManager.instance().models.set(model.id, model)
@ -77,30 +73,41 @@ const useModels = () => {
// Fetch all data // Fetch all data
getExtensionModels() getExtensionModels()
getDownloadedModels() getDownloadedModels()
}, []) }, [setDownloadedModels, setExtensionModels])
const reloadData = useDebouncedCallback(() => getData(), 300) const reloadData = useDebouncedCallback(() => getData(), 300)
const updateStates = useCallback(() => {
const cachedModels = ModelManager.instance().models.values().toArray()
const toUpdate = [
...downloadedModels,
...cachedModels.filter(
(e: Model) => !downloadedModels.some((g: Model) => g.id === e.id)
),
]
setDownloadedModels(toUpdate)
}, [downloadedModels, setDownloadedModels])
const getModels = async (): Promise<Model[]> => const getModels = async (): Promise<Model[]> =>
extensionManager extensionManager
.get<ModelExtension>(ExtensionTypeEnum.Model) .get<ModelExtension>(ExtensionTypeEnum.Model)
?.getModels() ?? [] ?.getModels() ?? []
useEffect(() => { useEffect(() => {
// Try get data on mount // Listen for model updates
if (isUpdated) { events.on(ModelEvent.OnModelsUpdate, async (data: { fetch?: boolean }) => {
// Listen for model updates if (data.fetch) reloadData()
events.on(ModelEvent.OnModelsUpdate, async () => reloadData()) else updateStates()
return () => { })
// Remove listener on unmount return () => {
events.off(ModelEvent.OnModelsUpdate, async () => {}) // Remove listener on unmount
} events.off(ModelEvent.OnModelsUpdate, async () => {})
} }
}, [isUpdated, reloadData]) }, [reloadData, updateStates])
return { return {
loadDataModel: getData, loadDataModel: getData,
isUpdated: isUpdated,
} }
} }