mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
feat: ollama unload model
This commit is contained in:
@@ -355,6 +355,31 @@ export const generateChatCompletion = async (token: string = '', body: object) =
|
||||
return [res, controller];
|
||||
};
|
||||
|
||||
export const unloadModel = async (token: string, tagName: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${OLLAMA_API_BASE_URL}/api/unload`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: tagName
|
||||
})
|
||||
}).catch((err) => {
|
||||
error = err;
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const createModel = async (token: string, payload: object, urlIdx: string | null = null) => {
|
||||
let error = null;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import Check from '$lib/components/icons/Check.svelte';
|
||||
import Search from '$lib/components/icons/Search.svelte';
|
||||
|
||||
import { deleteModel, getOllamaVersion, pullModel } from '$lib/apis/ollama';
|
||||
import { deleteModel, getOllamaVersion, pullModel, unloadModel } from '$lib/apis/ollama';
|
||||
|
||||
import {
|
||||
user,
|
||||
@@ -31,6 +31,7 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import dayjs from '$lib/dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import ArrowUpTray from '$lib/components/icons/ArrowUpTray.svelte';
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
@@ -312,6 +313,22 @@
|
||||
toast.success(`${model} download has been canceled`);
|
||||
}
|
||||
};
|
||||
|
||||
const unloadModelHandler = async (model: string) => {
|
||||
const res = await unloadModel(localStorage.token, model).catch((error) => {
|
||||
toast.error($i18n.t('Error unloading model: {{error}}', { error }));
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success($i18n.t('Model unloaded successfully'));
|
||||
models.set(
|
||||
await getModels(
|
||||
localStorage.token,
|
||||
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<DropdownMenu.Root
|
||||
@@ -660,11 +677,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if value === item.value}
|
||||
<div class="ml-auto pl-2 pr-2 md:pr-0">
|
||||
<Check />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="ml-auto pl-2 pr-1 flex gap-1.5 items-center">
|
||||
{#if $user?.role === 'admin' && item.model.owned_by === 'ollama' && item.model.ollama?.expires_at && new Date(item.model.ollama?.expires_at * 1000) > new Date()}
|
||||
<Tooltip content={`${$i18n.t('Eject')}`} className="flex-shrink-0">
|
||||
<button
|
||||
class="flex"
|
||||
on:click={() => {
|
||||
unloadModelHandler(item.value);
|
||||
}}
|
||||
>
|
||||
<ArrowUpTray className="size-3" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
|
||||
{#if value === item.value}
|
||||
<div>
|
||||
<Check className="size-3" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
{:else}
|
||||
<div class="">
|
||||
|
||||
Reference in New Issue
Block a user