chore: model import from llama.cpp provider

This commit is contained in:
Faisal Amir 2025-05-20 15:48:45 +07:00
parent c4d32c72d1
commit c54e8c80b6
2 changed files with 92 additions and 3 deletions

View File

@ -4,6 +4,8 @@ import ProvidersMenu from '@/containers/ProvidersMenu'
import { useModelProvider } from '@/hooks/useModelProvider'
import { cn, getProviderTitle } from '@/lib/utils'
import { Switch } from '@/components/ui/switch'
import { open } from '@tauri-apps/plugin-dialog'
import { importModel } from '@/services/models'
import {
createFileRoute,
Link,
@ -24,6 +26,10 @@ import { CustomTooltipJoyRide } from '@/containers/CustomeTooltipJoyRide'
import { route } from '@/constants/routes'
import DeleteProvider from '@/containers/dialogs/DeleteProvider'
import { updateSettings } from '@/services/providers'
import { Button } from '@/components/ui/button'
import { IconFolderPlus } from '@tabler/icons-react'
import { getProviders } from '@/services/providers'
import { toast } from 'sonner'
// as route.threadsDetail
export const Route = createFileRoute('/settings/providers/$providerName')({
@ -62,7 +68,7 @@ const steps = [
function ProviderDetail() {
const { step } = useSearch({ from: Route.id })
const { providerName } = useParams({ from: Route.id })
const { getProviderByName, updateProvider } = useModelProvider()
const { getProviderByName, setProviders, updateProvider } = useModelProvider()
const provider = getProviderByName(providerName)
const isSetup = step === 'setup_remote_provider'
const navigate = useNavigate()
@ -167,7 +173,10 @@ function ProviderDetail() {
) {
updateObj.base_url = newValue
}
updateSettings(providerName, updateObj.settings ?? [])
updateSettings(
providerName,
updateObj.settings ?? []
)
updateProvider(providerName, {
...provider,
...updateObj,
@ -229,7 +238,51 @@ function ProviderDetail() {
Models
</h1>
<div className="flex items-center gap-2">
{provider && <DialogAddModel provider={provider} />}
{provider && provider.provider !== 'llama.cpp' && (
<DialogAddModel provider={provider} />
)}
{provider && provider.provider === 'llama.cpp' && (
<Button
variant="link"
size="sm"
className="hover:no-underline"
onClick={async () => {
const selectedFile = await open({
multiple: false,
directory: false,
filters: [
{
name: 'GGUF',
extensions: ['gguf'],
},
],
})
if (selectedFile) {
try {
await importModel(selectedFile)
} catch (error) {
console.error('Failed to import model:', error)
} finally {
// Refresh the provider to update the models list
getProviders().then(setProviders)
toast.success('Import Model', {
id: `import-model-${provider.provider}`,
description: `Model ${provider.provider} has been imported successfully.`,
})
}
}
}}
>
<div className="cursor-pointer flex items-center justify-center rounded hover:bg-main-view-fg/15 bg-main-view-fg/10 transition-all duration-200 ease-in-out px-1.5 py-1 gap-1">
<IconFolderPlus
size={18}
className="text-main-view-fg/50"
/>
<span className="text-main-view-fg/70">Import</span>
</div>
</Button>
)}
</div>
</div>
}

View File

@ -168,6 +168,42 @@ export const deleteModel = async (id: string) => {
}
}
/**
* Imports a model from a file path.
* @param filePath The path to the model file or an array of file paths.
* @param modelId Optional model ID. If not provided, it will be derived from the file name.
* @param provider The provider for the model (default: 'llama.cpp').
* @returns A promise that resolves when the model is imported.
*/
export const importModel = async (
filePath: string | string[],
modelId?: string,
provider: string = 'llama.cpp'
) => {
const extension = ExtensionManager.getInstance().get<ModelExtension>(
ExtensionTypeEnum.Model
)
if (!extension) throw new Error('Model extension not found')
try {
// If filePath is an array, use the first element
const path = Array.isArray(filePath) ? filePath[0] : filePath
// If no path was selected, throw an error
if (!path) throw new Error('No file selected')
// Extract filename from path to use as model ID if not provided
const defaultModelId = path.split('/').pop()?.split('.')[0] || path
const modelIdToUse = modelId || defaultModelId
return await extension.importModel(modelIdToUse, path, provider)
} catch (error) {
console.error('Failed to import model:', error)
throw error
}
}
/**
* Configures the proxy options for model downloads.
* @param param0