* chore: add react developer tools to electron * feat: add small convert modal * feat: separate modals and add hugging face extension * feat: fully implement hugging face converter * fix: forgot to uncomment this... * fix: typo * feat: try hf-to-gguf script first and then use convert.py HF-to-GGUF has support for some unusual models maybe using convert.py first would be better but we can change the usage order later * fix: pre-install directory changed * fix: sometimes exit code is undefined * chore: download additional files for qwen * fix: event handling changed * chore: add one more necessary package * feat: download gguf-py from llama.cpp * fix: cannot interpret wildcards on GNU tar Co-authored-by: hiento09 <136591877+hiento09@users.noreply.github.com> --------- Co-authored-by: hiento09 <136591877+hiento09@users.noreply.github.com>
82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
import { useContext } from 'react'
|
|
|
|
import {
|
|
ExtensionTypeEnum,
|
|
HuggingFaceExtension,
|
|
HuggingFaceRepoData,
|
|
Quantization,
|
|
} from '@janhq/core'
|
|
|
|
import { useSetAtom } from 'jotai'
|
|
|
|
import { FeatureToggleContext } from '@/context/FeatureToggle'
|
|
|
|
import { extensionManager } from '@/extension/ExtensionManager'
|
|
import {
|
|
conversionStatusAtom,
|
|
conversionErrorAtom,
|
|
} from '@/helpers/atoms/HFConverter.atom'
|
|
|
|
export const useConvertHuggingFaceModel = () => {
|
|
const { ignoreSSL, proxy } = useContext(FeatureToggleContext)
|
|
const setConversionStatus = useSetAtom(conversionStatusAtom)
|
|
const setConversionError = useSetAtom(conversionErrorAtom)
|
|
|
|
const convertHuggingFaceModel = async (
|
|
repoID: string,
|
|
repoData: HuggingFaceRepoData,
|
|
quantization: Quantization
|
|
) => {
|
|
const extension = await extensionManager.get<HuggingFaceExtension>(
|
|
ExtensionTypeEnum.HuggingFace
|
|
)
|
|
try {
|
|
if (extension) {
|
|
extension.interrupted = false
|
|
}
|
|
setConversionStatus('downloading')
|
|
await extension?.downloadModelFiles(repoID, repoData, {
|
|
ignoreSSL,
|
|
proxy,
|
|
})
|
|
if (extension?.interrupted) return
|
|
setConversionStatus('converting')
|
|
await extension?.convert(repoID)
|
|
if (extension?.interrupted) return
|
|
setConversionStatus('quantizing')
|
|
await extension?.quantize(repoID, quantization)
|
|
if (extension?.interrupted) return
|
|
setConversionStatus('generating')
|
|
await extension?.generateMetadata(repoID, repoData, quantization)
|
|
setConversionStatus('done')
|
|
} catch (err) {
|
|
if (extension?.interrupted) return
|
|
extension?.cancelConvert(repoID, repoData)
|
|
if (typeof err === 'number') {
|
|
setConversionError(new Error(`exit code: ${err}`))
|
|
} else {
|
|
setConversionError(err as Error)
|
|
}
|
|
console.error(err)
|
|
}
|
|
}
|
|
|
|
const cancelConvertHuggingFaceModel = async (
|
|
repoID: string,
|
|
repoData: HuggingFaceRepoData
|
|
) => {
|
|
const extension = await extensionManager.get<HuggingFaceExtension>(
|
|
ExtensionTypeEnum.HuggingFace
|
|
)
|
|
|
|
setConversionStatus('stopping')
|
|
await extension?.cancelConvert(repoID, repoData)
|
|
setConversionStatus(null)
|
|
}
|
|
|
|
return {
|
|
convertHuggingFaceModel,
|
|
cancelConvertHuggingFaceModel,
|
|
}
|
|
}
|