fix: models load
This commit is contained in:
parent
b8e521164b
commit
e9fd7f4554
@ -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, {})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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]
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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]
|
||||||
|
|||||||
@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user