mirror of
https://github.com/open-webui/desktop.git
synced 2026-07-19 22:53:37 -04:00
refac
This commit is contained in:
+24
-1
@@ -65,7 +65,8 @@ import {
|
||||
getLlamaCppPty,
|
||||
validateLlamaCppProcess,
|
||||
checkLlamaCppUpdate,
|
||||
updateLlamaCpp
|
||||
updateLlamaCpp,
|
||||
uninstallLlamaCpp
|
||||
} from './utils/llamacpp'
|
||||
|
||||
import {
|
||||
@@ -907,6 +908,28 @@ if (!gotTheLock) {
|
||||
ipcMain.handle('llamacpp:logs', () => getLlamaCppLog())
|
||||
ipcMain.handle('llamacpp:pty:connect', () => connectLlamaCppPtyPort())
|
||||
|
||||
ipcMain.handle('llamacpp:uninstall', async () => {
|
||||
try {
|
||||
const info = getLlamaCppInfo()
|
||||
await uninstallLlamaCpp()
|
||||
sendToRenderer('status:llamacpp', null)
|
||||
// Unregister OpenAI endpoint if it was running
|
||||
if (info.url) {
|
||||
sendToRenderer('connections:openai', {
|
||||
action: 'remove',
|
||||
url: `${info.url}/v1`
|
||||
})
|
||||
setTimeout(() => sendToRenderer('models:refresh'), 500)
|
||||
}
|
||||
await setConfig({ llamaCpp: { ...CONFIG?.llamaCpp, enabled: false } })
|
||||
CONFIG = await getConfig()
|
||||
return true
|
||||
} catch (error) {
|
||||
log.error('Failed to uninstall llamacpp:', error)
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
// Hugging Face models
|
||||
ipcMain.handle('huggingface:models:list', () => listModels())
|
||||
ipcMain.handle('huggingface:models:dir', () => getModelsDir())
|
||||
|
||||
@@ -505,3 +505,18 @@ export const validateLlamaCppProcess = (): boolean => {
|
||||
lock.release()
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall llama.cpp — stop the server and remove all downloaded binaries.
|
||||
*/
|
||||
export const uninstallLlamaCpp = async (): Promise<void> => {
|
||||
await stopLlamaCpp()
|
||||
|
||||
const cacheBase = path.join(getUserDataPath(), 'llama.cpp')
|
||||
if (fs.existsSync(cacheBase)) {
|
||||
fs.rmSync(cacheBase, { recursive: true, force: true })
|
||||
log.info('Removed llama.cpp directory:', cacheBase)
|
||||
}
|
||||
|
||||
binaryPath = null
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@ const api = {
|
||||
},
|
||||
checkLlamaCppUpdate: () => ipcRenderer.invoke('llamacpp:check-update'),
|
||||
updateLlamaCpp: () => ipcRenderer.invoke('llamacpp:update'),
|
||||
uninstallLlamaCpp: () => ipcRenderer.invoke('llamacpp:uninstall'),
|
||||
|
||||
// Hugging Face models
|
||||
listHfModels: () => ipcRenderer.invoke('huggingface:models:list'),
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<div>
|
||||
<div class="text-[13px] font-medium text-gray-700 dark:text-gray-300 flex items-center gap-1.5">
|
||||
{$i18n.t('main.getStarted.llamaCpp')}
|
||||
<span class="text-[9px] px-1.5 py-0.5 rounded-full bg-amber-500/10 text-amber-600 dark:text-amber-400 uppercase tracking-wide font-medium">{$i18n.t('common.experimental')}</span>
|
||||
<span class="text-[9px] opacity-30 uppercase tracking-wide">{$i18n.t('common.experimental')}</span>
|
||||
</div>
|
||||
<div class="text-[11px] text-gray-400 dark:text-gray-500 mt-0.5">{$i18n.t('main.getStarted.llamaCppDesc')}</div>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
let settingUp = $state(false)
|
||||
let loaded = $state(false)
|
||||
let setupStatus = $state('')
|
||||
let uninstalling = $state(false)
|
||||
let installing = $state(false)
|
||||
|
||||
type UpdateStatus = 'idle' | 'checking' | 'available' | 'updating' | 'up-to-date' | 'error'
|
||||
let updateStatus = $state<UpdateStatus>('idle')
|
||||
@@ -166,6 +168,8 @@
|
||||
deleting = null
|
||||
}
|
||||
|
||||
const installed = $derived(!!lsInfo?.binaryPath)
|
||||
|
||||
const formatSize = (bytes: number): string => {
|
||||
if (bytes < 1024) return `${bytes} B`
|
||||
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
|
||||
@@ -176,6 +180,37 @@
|
||||
|
||||
{#if !loaded}
|
||||
<div class="py-6 text-[12px] opacity-20 text-center">{$i18n.t('common.loading')}</div>
|
||||
{:else if !installed}
|
||||
<div class="py-4 flex items-center justify-between">
|
||||
<div>
|
||||
<div class="text-[13px] opacity-40 flex items-center gap-1.5">
|
||||
{$i18n.t('settings.inference.notInstalled')}
|
||||
<span class="text-[9px] opacity-30 uppercase tracking-wide">{$i18n.t('common.experimental')}</span>
|
||||
</div>
|
||||
<div class="text-[11px] opacity-20 mt-0.5">{$i18n.t('settings.inference.notInstalledDesc')}</div>
|
||||
</div>
|
||||
<button
|
||||
class="text-[12px] opacity-40 hover:opacity-70 px-3 py-1.5 bg-black/[0.04] dark:bg-white/[0.06] transition border-none text-[#1d1d1f] dark:text-[#fafafa] rounded-xl flex items-center gap-1.5 {installing ? 'pointer-events-none opacity-20' : ''}"
|
||||
disabled={installing}
|
||||
onclick={async () => {
|
||||
installing = true
|
||||
try {
|
||||
await window.electronAPI.startLlamaCpp()
|
||||
lsInfo = await window.electronAPI.getLlamaCppInfo()
|
||||
} catch (e) {
|
||||
console.error('Failed to install:', e)
|
||||
}
|
||||
installing = false
|
||||
}}
|
||||
>
|
||||
{#if installing}
|
||||
<div class="w-2.5 h-2.5 rounded-full border-[1.5px] border-black/20 dark:border-white/30 border-t-transparent animate-spin"></div>
|
||||
{$i18n.t('common.installing')}
|
||||
{:else}
|
||||
{$i18n.t('common.install')}
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-col divide-y divide-white/[0.04]">
|
||||
<!-- Server status & controls -->
|
||||
@@ -184,7 +219,7 @@
|
||||
<div>
|
||||
<div class="text-[13px] opacity-70 flex items-center gap-1.5">
|
||||
{$i18n.t('settings.inference.llamaServer')}
|
||||
<span class="text-[9px] px-1.5 py-0.5 rounded-full bg-amber-500/10 text-amber-600 dark:text-amber-400 uppercase tracking-wide font-medium">{$i18n.t('common.experimental')}</span>
|
||||
<span class="text-[9px] opacity-30 uppercase tracking-wide">{$i18n.t('common.experimental')}</span>
|
||||
</div>
|
||||
<div class="text-[11px] opacity-25 mt-0.5">
|
||||
{$i18n.t('settings.inference.llamaServerDesc')}
|
||||
@@ -430,5 +465,38 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Uninstall -->
|
||||
{#if lsInfo?.binaryPath}
|
||||
<div class="py-4 flex items-center justify-between">
|
||||
<div>
|
||||
<div class="text-[13px] opacity-70">{$i18n.t('settings.inference.uninstall')}</div>
|
||||
<div class="text-[11px] opacity-25 mt-0.5">{$i18n.t('settings.inference.uninstallDesc')}</div>
|
||||
</div>
|
||||
<button
|
||||
class="text-[12px] opacity-40 hover:opacity-70 px-3 py-1.5 bg-black/[0.04] dark:bg-white/[0.06] transition border-none text-[#1d1d1f] dark:text-[#fafafa] rounded-xl flex items-center gap-1.5 {uninstalling ? 'pointer-events-none opacity-20' : ''}"
|
||||
disabled={uninstalling}
|
||||
onclick={async () => {
|
||||
if (confirm($i18n.t('settings.inference.uninstallConfirm'))) {
|
||||
uninstalling = true
|
||||
try {
|
||||
await window.electronAPI.uninstallLlamaCpp()
|
||||
lsInfo = await window.electronAPI.getLlamaCppInfo()
|
||||
} catch (e) {
|
||||
console.error('Failed to uninstall llama.cpp:', e)
|
||||
}
|
||||
uninstalling = false
|
||||
}
|
||||
}}
|
||||
>
|
||||
{#if uninstalling}
|
||||
<div class="w-2.5 h-2.5 rounded-full border-[1.5px] border-black/20 dark:border-white/30 border-t-transparent animate-spin"></div>
|
||||
{$i18n.t('common.uninstalling')}
|
||||
{:else}
|
||||
{$i18n.t('common.uninstall')}
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -235,6 +235,11 @@
|
||||
"settings.inference.updateAvailable": "Update available: {{version}}",
|
||||
"settings.inference.upToDate": "Up to date",
|
||||
"settings.inference.updating": "Updating…",
|
||||
"settings.inference.uninstall": "Uninstall",
|
||||
"settings.inference.uninstallDesc": "Remove llama.cpp binaries",
|
||||
"settings.inference.uninstallConfirm": "This will stop llama-server and remove all downloaded binaries. Continue?",
|
||||
"settings.inference.notInstalled": "llama.cpp is not installed",
|
||||
"settings.inference.notInstalledDesc": "Download and set up llama.cpp for local model inference",
|
||||
|
||||
"settings.models.downloadedModels": "Downloaded Models",
|
||||
"settings.models.noModels": "No models downloaded yet",
|
||||
|
||||
Reference in New Issue
Block a user