diff --git a/backend/apps/ollama/main.py b/backend/apps/ollama/main.py index 988d4bf49..05fcb6ddf 100644 --- a/backend/apps/ollama/main.py +++ b/backend/apps/ollama/main.py @@ -207,9 +207,12 @@ async def pull_model( form_data: ModelNameForm, url_idx: int = 0, user=Depends(get_admin_user) ): url = app.state.OLLAMA_BASE_URLS[url_idx] + print(url) + r = None - def get_request(url): + def get_request(): + nonlocal url nonlocal r try: @@ -235,7 +238,7 @@ async def pull_model( raise e try: - return await run_in_threadpool(get_request(url)) + return await run_in_threadpool(get_request) except Exception as e: print(e) error_detail = "Open WebUI: Server Connection Error" @@ -454,6 +457,7 @@ async def delete_model( ) url = app.state.OLLAMA_BASE_URLS[url_idx] + print(url) try: r = requests.request( diff --git a/src/lib/apis/ollama/index.ts b/src/lib/apis/ollama/index.ts index 5887b11f6..2047fedef 100644 --- a/src/lib/apis/ollama/index.ts +++ b/src/lib/apis/ollama/index.ts @@ -318,20 +318,23 @@ export const createModel = async (token: string, tagName: string, content: strin return res; }; -export const deleteModel = async (token: string, tagName: string) => { +export const deleteModel = async (token: string, tagName: string, urlIdx: string | null = null) => { let error = null; - const res = await fetch(`${OLLAMA_API_BASE_URL}/api/delete`, { - method: 'DELETE', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}` - }, - body: JSON.stringify({ - name: tagName - }) - }) + const res = await fetch( + `${OLLAMA_API_BASE_URL}/api/delete${urlIdx !== null ? `/${urlIdx}` : ''}`, + { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + name: tagName + }) + } + ) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); @@ -358,10 +361,10 @@ export const deleteModel = async (token: string, tagName: string) => { return res; }; -export const pullModel = async (token: string, tagName: string) => { +export const pullModel = async (token: string, tagName: string, urlIdx: string | null = null) => { let error = null; - const res = await fetch(`${OLLAMA_API_BASE_URL}/api/pull`, { + const res = await fetch(`${OLLAMA_API_BASE_URL}/api/pull${urlIdx !== null ? `/${urlIdx}` : ''}`, { method: 'POST', headers: { Accept: 'application/json', diff --git a/src/lib/components/chat/Settings/Models.svelte b/src/lib/components/chat/Settings/Models.svelte index 3225f6995..f6b70892c 100644 --- a/src/lib/components/chat/Settings/Models.svelte +++ b/src/lib/components/chat/Settings/Models.svelte @@ -2,7 +2,13 @@ import queue from 'async/queue'; import { toast } from 'svelte-sonner'; - import { createModel, deleteModel, getOllamaVersion, pullModel } from '$lib/apis/ollama'; + import { + createModel, + deleteModel, + getOllamaUrls, + getOllamaVersion, + pullModel + } from '$lib/apis/ollama'; import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; import { WEBUI_NAME, models, user } from '$lib/stores'; import { splitStream } from '$lib/utils'; @@ -27,6 +33,9 @@ $: liteLLMModelName = liteLLMModel; // Models + + let OLLAMA_URLS = []; + let selectedOllamaUrlIdx: string | null = null; let showExperimentalOllama = false; let ollamaVersion = ''; const MAX_PARALLEL_DOWNLOADS = 3; @@ -236,9 +245,11 @@ }; const deleteModelHandler = async () => { - const res = await deleteModel(localStorage.token, deleteModelTag).catch((error) => { - toast.error(error); - }); + const res = await deleteModel(localStorage.token, deleteModelTag, selectedOllamaUrlIdx).catch( + (error) => { + toast.error(error); + } + ); if (res) { toast.success(`Deleted ${deleteModelTag}`); @@ -249,10 +260,12 @@ }; const pullModelHandlerProcessor = async (opts: { modelName: string; callback: Function }) => { - const res = await pullModel(localStorage.token, opts.modelName).catch((error) => { - opts.callback({ success: false, error, modelName: opts.modelName }); - return null; - }); + const res = await pullModel(localStorage.token, opts.modelName, selectedOllamaUrlIdx).catch( + (error) => { + opts.callback({ success: false, error, modelName: opts.modelName }); + return null; + } + ); if (res) { const reader = res.body @@ -358,6 +371,15 @@ }; onMount(async () => { + OLLAMA_URLS = await getOllamaUrls(localStorage.token).catch((error) => { + toast.error(error); + return []; + }); + + if (OLLAMA_URLS.length > 1) { + selectedOllamaUrlIdx = 0; + } + ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false); liteLLMModelInfo = await getLiteLLMModelInfo(localStorage.token); }); @@ -367,52 +389,137 @@