Bladeren bron

feat: litellm proxy frontend integration

Timothy J. Baek 1 jaar geleden
bovenliggende
commit
ec6f53e298

+ 2 - 0
backend/apps/images/main.py

@@ -109,6 +109,7 @@ def get_models(user=Depends(get_current_user)):
         models = r.json()
         return models
     except Exception as e:
+        app.state.ENABLED = False
         raise HTTPException(status_code=400, detail=ERROR_MESSAGES.DEFAULT(e))
 
 
@@ -120,6 +121,7 @@ async def get_default_model(user=Depends(get_admin_user)):
 
         return {"model": options["sd_model_checkpoint"]}
     except Exception as e:
+        app.state.ENABLED = False
         raise HTTPException(status_code=400, detail=ERROR_MESSAGES.DEFAULT(e))
 
 

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 	"name": "open-webui",
-	"version": "0.1.102",
+	"version": "0.1.103",
 	"private": true,
 	"scripts": {
 		"dev": "vite dev --host",

+ 107 - 1
src/lib/apis/litellm/index.ts

@@ -17,7 +17,7 @@ export const getLiteLLMModels = async (token: string = '') => {
 		})
 		.catch((err) => {
 			console.log(err);
-			error = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`;
+			error = `LiteLLM: ${err?.error?.message ?? 'Network Problem'}`;
 			return [];
 		});
 
@@ -40,3 +40,109 @@ export const getLiteLLMModels = async (token: string = '') => {
 				})
 		: models;
 };
+
+export const getLiteLLMModelInfo = async (token: string = '') => {
+	let error = null;
+
+	const res = await fetch(`${LITELLM_API_BASE_URL}/model/info`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			...(token && { authorization: `Bearer ${token}` })
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			error = `LiteLLM: ${err?.error?.message ?? 'Network Problem'}`;
+			return [];
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	const models = Array.isArray(res) ? res : res?.data ?? null;
+
+	return models;
+};
+
+type AddLiteLLMModelForm = {
+	name: string;
+	model: string;
+	api_base: string;
+	api_key: string;
+	rpm: string;
+};
+
+export const addLiteLLMModel = async (token: string = '', payload: AddLiteLLMModelForm) => {
+	let error = null;
+
+	const res = await fetch(`${LITELLM_API_BASE_URL}/model/new`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			...(token && { authorization: `Bearer ${token}` })
+		},
+		body: JSON.stringify({
+			model_name: payload.name,
+			litellm_params: {
+				model: payload.model,
+				...(payload.api_base === '' ? {} : { api_base: payload.api_base }),
+				...(payload.api_key === '' ? {} : { api_key: payload.api_key }),
+				...(isNaN(parseInt(payload.rpm)) ? {} : { rpm: parseInt(payload.rpm) })
+			}
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			error = `LiteLLM: ${err?.error?.message ?? 'Network Problem'}`;
+			return [];
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const deleteLiteLLMModel = async (token: string = '', id: string) => {
+	let error = null;
+
+	const res = await fetch(`${LITELLM_API_BASE_URL}/model/delete`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			...(token && { authorization: `Bearer ${token}` })
+		},
+		body: JSON.stringify({
+			id: id
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			error = `LiteLLM: ${err?.error?.message ?? 'Network Problem'}`;
+			return [];
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};

+ 9 - 7
src/lib/components/chat/Settings/About.svelte

@@ -38,16 +38,18 @@
 			</div>
 		</div>
 
-		<hr class=" dark:border-gray-700" />
+		{#if ollamaVersion}
+			<hr class=" dark:border-gray-700" />
 
-		<div>
-			<div class=" mb-2.5 text-sm font-medium">Ollama Version</div>
-			<div class="flex w-full">
-				<div class="flex-1 text-xs text-gray-700 dark:text-gray-200">
-					{ollamaVersion ?? 'N/A'}
+			<div>
+				<div class=" mb-2.5 text-sm font-medium">Ollama Version</div>
+				<div class="flex w-full">
+					<div class="flex-1 text-xs text-gray-700 dark:text-gray-200">
+						{ollamaVersion ?? 'N/A'}
+					</div>
 				</div>
 			</div>
-		</div>
+		{/if}
 
 		<hr class=" dark:border-gray-700" />
 

+ 85 - 63
src/lib/components/chat/Settings/Connections.svelte

@@ -15,6 +15,9 @@
 	let OPENAI_API_KEY = '';
 	let OPENAI_API_BASE_URL = '';
 
+	let showOpenAI = false;
+	let showLiteLLM = false;
+
 	const updateOpenAIHandler = async () => {
 		OPENAI_API_BASE_URL = await updateOpenAIUrl(localStorage.token, OPENAI_API_BASE_URL);
 		OPENAI_API_KEY = await updateOpenAIKey(localStorage.token, OPENAI_API_KEY);
@@ -45,7 +48,7 @@
 </script>
 
 <form
-	class="flex flex-col h-full space-y-3 text-sm"
+	class="flex flex-col h-full justify-between text-sm"
 	on:submit|preventDefault={() => {
 		updateOpenAIHandler();
 		dispatch('save');
@@ -56,81 +59,100 @@
 		// });
 	}}
 >
-	<div>
-		<div class=" mb-2.5 text-sm font-medium">Ollama API URL</div>
-		<div class="flex w-full">
-			<div class="flex-1 mr-2">
-				<input
-					class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
-					placeholder="Enter URL (e.g. http://localhost:11434/api)"
-					bind:value={API_BASE_URL}
-				/>
-			</div>
-			<button
-				class="px-3 bg-gray-200 hover:bg-gray-300 dark:bg-gray-600 dark:hover:bg-gray-700 rounded transition"
-				on:click={() => {
-					updateOllamaAPIUrlHandler();
-				}}
-				type="button"
-			>
-				<svg
-					xmlns="http://www.w3.org/2000/svg"
-					viewBox="0 0 20 20"
-					fill="currentColor"
-					class="w-4 h-4"
-				>
-					<path
-						fill-rule="evenodd"
-						d="M15.312 11.424a5.5 5.5 0 01-9.201 2.466l-.312-.311h2.433a.75.75 0 000-1.5H3.989a.75.75 0 00-.75.75v4.242a.75.75 0 001.5 0v-2.43l.31.31a7 7 0 0011.712-3.138.75.75 0 00-1.449-.39zm1.23-3.723a.75.75 0 00.219-.53V2.929a.75.75 0 00-1.5 0V5.36l-.31-.31A7 7 0 003.239 8.188a.75.75 0 101.448.389A5.5 5.5 0 0113.89 6.11l.311.31h-2.432a.75.75 0 000 1.5h4.243a.75.75 0 00.53-.219z"
-						clip-rule="evenodd"
-					/>
-				</svg>
-			</button>
-		</div>
+	<div class="  pr-1.5 overflow-y-scroll max-h-[21rem] space-y-3">
+		<div class=" space-y-3">
+			<div class="mt-2 space-y-2 pr-1.5">
+				<div class="flex justify-between items-center text-sm">
+					<div class="  font-medium">OpenAI API</div>
+					<button
+						class=" text-xs font-medium text-gray-500"
+						type="button"
+						on:click={() => {
+							showOpenAI = !showOpenAI;
+						}}>{showOpenAI ? 'Hide' : 'Show'}</button
+					>
+				</div>
 
-		<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
-			Trouble accessing Ollama?
-			<a
-				class=" text-gray-300 font-medium"
-				href="https://github.com/open-webui/open-webui#troubleshooting"
-				target="_blank"
-			>
-				Click here for help.
-			</a>
+				{#if showOpenAI}
+					<div>
+						<div class=" mb-2.5 text-sm font-medium">API Key</div>
+						<div class="flex w-full">
+							<div class="flex-1">
+								<input
+									class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
+									placeholder="Enter OpenAI API Key"
+									bind:value={OPENAI_API_KEY}
+									autocomplete="off"
+								/>
+							</div>
+						</div>
+					</div>
+
+					<div>
+						<div class=" mb-2.5 text-sm font-medium">API Base URL</div>
+						<div class="flex w-full">
+							<div class="flex-1">
+								<input
+									class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
+									placeholder="Enter OpenAI API Base URL"
+									bind:value={OPENAI_API_BASE_URL}
+									autocomplete="off"
+								/>
+							</div>
+						</div>
+						<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
+							WebUI will make requests to <span class=" text-gray-200"
+								>'{OPENAI_API_BASE_URL}/chat'</span
+							>
+						</div>
+					</div>
+				{/if}
+			</div>
 		</div>
-	</div>
 
-	<hr class=" dark:border-gray-700" />
+		<hr class=" dark:border-gray-700" />
 
-	<div class=" space-y-3">
 		<div>
-			<div class=" mb-2.5 text-sm font-medium">OpenAI API Key</div>
+			<div class=" mb-2.5 text-sm font-medium">Ollama API URL</div>
 			<div class="flex w-full">
-				<div class="flex-1">
+				<div class="flex-1 mr-2">
 					<input
 						class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
-						placeholder="Enter OpenAI API Key"
-						bind:value={OPENAI_API_KEY}
-						autocomplete="off"
+						placeholder="Enter URL (e.g. http://localhost:11434/api)"
+						bind:value={API_BASE_URL}
 					/>
 				</div>
+				<button
+					class="px-3 bg-gray-200 hover:bg-gray-300 dark:bg-gray-600 dark:hover:bg-gray-700 rounded transition"
+					on:click={() => {
+						updateOllamaAPIUrlHandler();
+					}}
+					type="button"
+				>
+					<svg
+						xmlns="http://www.w3.org/2000/svg"
+						viewBox="0 0 20 20"
+						fill="currentColor"
+						class="w-4 h-4"
+					>
+						<path
+							fill-rule="evenodd"
+							d="M15.312 11.424a5.5 5.5 0 01-9.201 2.466l-.312-.311h2.433a.75.75 0 000-1.5H3.989a.75.75 0 00-.75.75v4.242a.75.75 0 001.5 0v-2.43l.31.31a7 7 0 0011.712-3.138.75.75 0 00-1.449-.39zm1.23-3.723a.75.75 0 00.219-.53V2.929a.75.75 0 00-1.5 0V5.36l-.31-.31A7 7 0 003.239 8.188a.75.75 0 101.448.389A5.5 5.5 0 0113.89 6.11l.311.31h-2.432a.75.75 0 000 1.5h4.243a.75.75 0 00.53-.219z"
+							clip-rule="evenodd"
+						/>
+					</svg>
+				</button>
 			</div>
-		</div>
 
-		<div>
-			<div class=" mb-2.5 text-sm font-medium">OpenAI API Base URL</div>
-			<div class="flex w-full">
-				<div class="flex-1">
-					<input
-						class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
-						placeholder="Enter OpenAI API Base URL"
-						bind:value={OPENAI_API_BASE_URL}
-						autocomplete="off"
-					/>
-				</div>
-			</div>
 			<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
-				WebUI will make requests to <span class=" text-gray-200">'{OPENAI_API_BASE_URL}/chat'</span>
+				Trouble accessing Ollama?
+				<a
+					class=" text-gray-300 font-medium"
+					href="https://github.com/open-webui/open-webui#troubleshooting"
+					target="_blank"
+				>
+					Click here for help.
+				</a>
 			</div>
 		</div>
 	</div>

+ 596 - 265
src/lib/components/chat/Settings/Models.svelte

@@ -2,14 +2,33 @@
 	import queue from 'async/queue';
 	import toast from 'svelte-french-toast';
 
-	import { createModel, deleteModel, pullModel } from '$lib/apis/ollama';
+	import { createModel, deleteModel, 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';
+	import { onMount } from 'svelte';
+	import { addLiteLLMModel, deleteLiteLLMModel, getLiteLLMModelInfo } from '$lib/apis/litellm';
 
 	export let getModels: Function;
 
+	let showLiteLLM = false;
+	let showLiteLLMParams = false;
+
+	let liteLLMModelInfo = [];
+
+	let liteLLMModel = '';
+	let liteLLMModelName = '';
+	let liteLLMAPIBase = '';
+	let liteLLMAPIKey = '';
+	let liteLLMRPM = '';
+
+	let deleteLiteLLMModelId = '';
+
+	$: liteLLMModelName = liteLLMModel;
+
 	// Models
+	let showExperimentalOllama = false;
+	let ollamaVersion = '';
 	const MAX_PARALLEL_DOWNLOADS = 3;
 	const modelDownloadQueue = queue(
 		(task: { modelName: string }, cb) =>
@@ -286,311 +305,623 @@
 			opts.callback({ success: true, modelName: opts.modelName });
 		}
 	};
+
+	const addLiteLLMModelHandler = async () => {
+		if (!liteLLMModelInfo.find((info) => info.model_name === liteLLMModelName)) {
+			const res = await addLiteLLMModel(localStorage.token, {
+				name: liteLLMModelName,
+				model: liteLLMModel,
+				api_base: liteLLMAPIBase,
+				api_key: liteLLMAPIKey,
+				rpm: liteLLMRPM
+			}).catch((error) => {
+				toast.error(error);
+				return null;
+			});
+
+			if (res) {
+				if (res.message) {
+					toast.success(res.message);
+				}
+			}
+		} else {
+			toast.error(`Model ${liteLLMModelName} already exists.`);
+		}
+
+		liteLLMModelName = '';
+		liteLLMModel = '';
+		liteLLMAPIBase = '';
+		liteLLMAPIKey = '';
+		liteLLMRPM = '';
+
+		liteLLMModelInfo = await getLiteLLMModelInfo(localStorage.token);
+		models.set(await getModels());
+	};
+
+	const deleteLiteLLMModelHandler = async () => {
+		const res = await deleteLiteLLMModel(localStorage.token, deleteLiteLLMModelId).catch(
+			(error) => {
+				toast.error(error);
+				return null;
+			}
+		);
+
+		if (res) {
+			if (res.message) {
+				toast.success(res.message);
+			}
+		}
+
+		deleteLiteLLMModelId = '';
+		liteLLMModelInfo = await getLiteLLMModelInfo(localStorage.token);
+		models.set(await getModels());
+	};
+
+	onMount(async () => {
+		ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false);
+		liteLLMModelInfo = await getLiteLLMModelInfo(localStorage.token);
+	});
 </script>
 
 <div class="flex flex-col h-full justify-between text-sm">
-	<div class=" space-y-3 pr-1.5 overflow-y-scroll h-80">
-		<div>
-			<div class=" mb-2.5 text-sm font-medium">Pull a model from Ollama.com</div>
-			<div class="flex w-full">
-				<div class="flex-1 mr-2">
-					<input
-						class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
-						placeholder="Enter model tag (e.g. mistral:7b)"
-						bind:value={modelTag}
-					/>
-				</div>
-				<button
-					class="px-3 text-gray-100 bg-emerald-600 hover:bg-emerald-700 disabled:bg-gray-700 disabled:cursor-not-allowed rounded transition"
-					on:click={() => {
-						pullModelHandler();
-					}}
-					disabled={modelTransferring}
-				>
-					{#if modelTransferring}
-						<div class="self-center">
-							<svg
-								class=" w-4 h-4"
-								viewBox="0 0 24 24"
-								fill="currentColor"
-								xmlns="http://www.w3.org/2000/svg"
-								><style>
-									.spinner_ajPY {
-										transform-origin: center;
-										animation: spinner_AtaB 0.75s infinite linear;
-									}
-									@keyframes spinner_AtaB {
-										100% {
-											transform: rotate(360deg);
-										}
-									}
-								</style><path
-									d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
-									opacity=".25"
-								/><path
-									d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
-									class="spinner_ajPY"
-								/></svg
-							>
-						</div>
-					{:else}
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							viewBox="0 0 16 16"
-							fill="currentColor"
-							class="w-4 h-4"
-						>
-							<path
-								d="M8.75 2.75a.75.75 0 0 0-1.5 0v5.69L5.03 6.22a.75.75 0 0 0-1.06 1.06l3.5 3.5a.75.75 0 0 0 1.06 0l3.5-3.5a.75.75 0 0 0-1.06-1.06L8.75 8.44V2.75Z"
-							/>
-							<path
-								d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
-							/>
-						</svg>
-					{/if}
-				</button>
-			</div>
-
-			<div class="mt-2 mb-1 text-xs text-gray-400 dark:text-gray-500">
-				To access the available model names for downloading, <a
-					class=" text-gray-500 dark:text-gray-300 font-medium"
-					href="https://ollama.com/library"
-					target="_blank">click here.</a
-				>
-			</div>
+	<div class=" space-y-3 pr-1.5 overflow-y-scroll h-[23rem]">
+		{#if ollamaVersion}
+			<div class="space-y-2 pr-1.5">
+				<div>
+					<div class=" mb-2 text-sm font-medium">Manage Ollama Models</div>
 
-			{#if Object.keys(modelDownloadStatus).length > 0}
-				{#each Object.keys(modelDownloadStatus) as model}
-					<div class="flex flex-col">
-						<div class="font-medium mb-1">{model}</div>
-						<div class="">
-							<div
-								class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
-								style="width: {Math.max(15, modelDownloadStatus[model].pullProgress ?? 0)}%"
-							>
-								{modelDownloadStatus[model].pullProgress ?? 0}%
-							</div>
-							<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
-								{modelDownloadStatus[model].digest}
-							</div>
+					<div class=" mb-2 text-sm font-medium">Pull a model from Ollama.com</div>
+					<div class="flex w-full">
+						<div class="flex-1 mr-2">
+							<input
+								class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								placeholder="Enter model tag (e.g. mistral:7b)"
+								bind:value={modelTag}
+							/>
 						</div>
+						<button
+							class="px-3 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded transition"
+							on:click={() => {
+								pullModelHandler();
+							}}
+							disabled={modelTransferring}
+						>
+							{#if modelTransferring}
+								<div class="self-center">
+									<svg
+										class=" w-4 h-4"
+										viewBox="0 0 24 24"
+										fill="currentColor"
+										xmlns="http://www.w3.org/2000/svg"
+										><style>
+											.spinner_ajPY {
+												transform-origin: center;
+												animation: spinner_AtaB 0.75s infinite linear;
+											}
+											@keyframes spinner_AtaB {
+												100% {
+													transform: rotate(360deg);
+												}
+											}
+										</style><path
+											d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
+											opacity=".25"
+										/><path
+											d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
+											class="spinner_ajPY"
+										/></svg
+									>
+								</div>
+							{:else}
+								<svg
+									xmlns="http://www.w3.org/2000/svg"
+									viewBox="0 0 16 16"
+									fill="currentColor"
+									class="w-4 h-4"
+								>
+									<path
+										d="M8.75 2.75a.75.75 0 0 0-1.5 0v5.69L5.03 6.22a.75.75 0 0 0-1.06 1.06l3.5 3.5a.75.75 0 0 0 1.06 0l3.5-3.5a.75.75 0 0 0-1.06-1.06L8.75 8.44V2.75Z"
+									/>
+									<path
+										d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
+									/>
+								</svg>
+							{/if}
+						</button>
 					</div>
-				{/each}
-			{/if}
-		</div>
 
-		<hr class=" dark:border-gray-700" />
+					<div class="mt-2 mb-1 text-xs text-gray-400 dark:text-gray-500">
+						To access the available model names for downloading, <a
+							class=" text-gray-500 dark:text-gray-300 font-medium"
+							href="https://ollama.com/library"
+							target="_blank">click here.</a
+						>
+					</div>
 
-		<div>
-			<div class=" mb-2.5 text-sm font-medium">Delete a model</div>
-			<div class="flex w-full">
-				<div class="flex-1 mr-2">
-					<select
-						class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
-						bind:value={deleteModelTag}
-						placeholder="Select a model"
-					>
-						{#if !deleteModelTag}
-							<option value="" disabled selected>Select a model</option>
-						{/if}
-						{#each $models.filter((m) => m.size != null) as model}
-							<option value={model.name} class="bg-gray-100 dark:bg-gray-700"
-								>{model.name + ' (' + (model.size / 1024 ** 3).toFixed(1) + ' GB)'}</option
-							>
+					{#if Object.keys(modelDownloadStatus).length > 0}
+						{#each Object.keys(modelDownloadStatus) as model}
+							<div class="flex flex-col">
+								<div class="font-medium mb-1">{model}</div>
+								<div class="">
+									<div
+										class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
+										style="width: {Math.max(15, modelDownloadStatus[model].pullProgress ?? 0)}%"
+									>
+										{modelDownloadStatus[model].pullProgress ?? 0}%
+									</div>
+									<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
+										{modelDownloadStatus[model].digest}
+									</div>
+								</div>
+							</div>
 						{/each}
-					</select>
+					{/if}
 				</div>
-				<button
-					class="px-3 bg-red-700 hover:bg-red-800 text-gray-100 rounded transition"
-					on:click={() => {
-						deleteModelHandler();
-					}}
-				>
-					<svg
-						xmlns="http://www.w3.org/2000/svg"
-						viewBox="0 0 16 16"
-						fill="currentColor"
-						class="w-4 h-4"
-					>
-						<path
-							fill-rule="evenodd"
-							d="M5 3.25V4H2.75a.75.75 0 0 0 0 1.5h.3l.815 8.15A1.5 1.5 0 0 0 5.357 15h5.285a1.5 1.5 0 0 0 1.493-1.35l.815-8.15h.3a.75.75 0 0 0 0-1.5H11v-.75A2.25 2.25 0 0 0 8.75 1h-1.5A2.25 2.25 0 0 0 5 3.25Zm2.25-.75a.75.75 0 0 0-.75.75V4h3v-.75a.75.75 0 0 0-.75-.75h-1.5ZM6.05 6a.75.75 0 0 1 .787.713l.275 5.5a.75.75 0 0 1-1.498.075l-.275-5.5A.75.75 0 0 1 6.05 6Zm3.9 0a.75.75 0 0 1 .712.787l-.275 5.5a.75.75 0 0 1-1.498-.075l.275-5.5a.75.75 0 0 1 .786-.711Z"
-							clip-rule="evenodd"
-						/>
-					</svg>
-				</button>
-			</div>
-		</div>
 
-		<hr class=" dark:border-gray-700" />
-
-		<form
-			on:submit|preventDefault={() => {
-				uploadModelHandler();
-			}}
-		>
-			<div class=" mb-2 flex w-full justify-between">
-				<div class="  text-sm font-medium">
-					Upload a GGUF model <a
-						class=" text-xs font-medium text-gray-500 underline"
-						href="https://github.com/jmorganca/ollama/blob/main/README.md#import-from-gguf"
-						target="_blank">(Experimental)</a
-					>
+				<div>
+					<div class=" mb-2 text-sm font-medium">Delete a model</div>
+					<div class="flex w-full">
+						<div class="flex-1 mr-2">
+							<select
+								class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								bind:value={deleteModelTag}
+								placeholder="Select a model"
+							>
+								{#if !deleteModelTag}
+									<option value="" disabled selected>Select a model</option>
+								{/if}
+								{#each $models.filter((m) => m.size != null) as model}
+									<option value={model.name} class="bg-gray-100 dark:bg-gray-700"
+										>{model.name + ' (' + (model.size / 1024 ** 3).toFixed(1) + ' GB)'}</option
+									>
+								{/each}
+							</select>
+						</div>
+						<button
+							class="px-3 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded transition"
+							on:click={() => {
+								deleteModelHandler();
+							}}
+						>
+							<svg
+								xmlns="http://www.w3.org/2000/svg"
+								viewBox="0 0 16 16"
+								fill="currentColor"
+								class="w-4 h-4"
+							>
+								<path
+									fill-rule="evenodd"
+									d="M5 3.25V4H2.75a.75.75 0 0 0 0 1.5h.3l.815 8.15A1.5 1.5 0 0 0 5.357 15h5.285a1.5 1.5 0 0 0 1.493-1.35l.815-8.15h.3a.75.75 0 0 0 0-1.5H11v-.75A2.25 2.25 0 0 0 8.75 1h-1.5A2.25 2.25 0 0 0 5 3.25Zm2.25-.75a.75.75 0 0 0-.75.75V4h3v-.75a.75.75 0 0 0-.75-.75h-1.5ZM6.05 6a.75.75 0 0 1 .787.713l.275 5.5a.75.75 0 0 1-1.498.075l-.275-5.5A.75.75 0 0 1 6.05 6Zm3.9 0a.75.75 0 0 1 .712.787l-.275 5.5a.75.75 0 0 1-1.498-.075l.275-5.5a.75.75 0 0 1 .786-.711Z"
+									clip-rule="evenodd"
+								/>
+							</svg>
+						</button>
+					</div>
 				</div>
 
-				<button
-					class="p-1 px-3 text-xs flex rounded transition"
-					on:click={() => {
-						if (modelUploadMode === 'file') {
-							modelUploadMode = 'url';
-						} else {
-							modelUploadMode = 'file';
-						}
-					}}
-					type="button"
-				>
-					{#if modelUploadMode === 'file'}
-						<span class="ml-2 self-center">File Mode</span>
-					{:else}
-						<span class="ml-2 self-center">URL Mode</span>
-					{/if}
-				</button>
-			</div>
+				<div>
+					<div class="flex justify-between items-center text-xs">
+						<div class=" text-sm font-medium">Experimental</div>
+						<button
+							class=" text-xs font-medium text-gray-500"
+							type="button"
+							on:click={() => {
+								showExperimentalOllama = !showExperimentalOllama;
+							}}>{showExperimentalOllama ? 'Show' : 'Hide'}</button
+						>
+					</div>
+				</div>
 
-			<div class="flex w-full mb-1.5">
-				<div class="flex flex-col w-full">
-					{#if modelUploadMode === 'file'}
-						<div class="flex-1 {modelInputFile && modelInputFile.length > 0 ? 'mr-2' : ''}">
-							<input
-								id="model-upload-input"
-								type="file"
-								bind:files={modelInputFile}
-								on:change={() => {
-									console.log(modelInputFile);
-								}}
-								accept=".gguf"
-								required
-								hidden
-							/>
+				{#if showExperimentalOllama}
+					<form
+						on:submit|preventDefault={() => {
+							uploadModelHandler();
+						}}
+					>
+						<div class=" mb-2 flex w-full justify-between">
+							<div class="  text-sm font-medium">Upload a GGUF model</div>
 
 							<button
-								type="button"
-								class="w-full rounded text-left py-2 px-4 dark:text-gray-300 dark:bg-gray-800"
+								class="p-1 px-3 text-xs flex rounded transition"
 								on:click={() => {
-									document.getElementById('model-upload-input').click();
+									if (modelUploadMode === 'file') {
+										modelUploadMode = 'url';
+									} else {
+										modelUploadMode = 'file';
+									}
 								}}
+								type="button"
 							>
-								{#if modelInputFile && modelInputFile.length > 0}
-									{modelInputFile[0].name}
+								{#if modelUploadMode === 'file'}
+									<span class="ml-2 self-center">File Mode</span>
 								{:else}
-									Click here to select
+									<span class="ml-2 self-center">URL Mode</span>
 								{/if}
 							</button>
 						</div>
-					{:else}
-						<div class="flex-1 {modelFileUrl !== '' ? 'mr-2' : ''}">
-							<input
-								class="w-full rounded text-left py-2 px-4 dark:text-gray-300 dark:bg-gray-800 outline-none {modelFileUrl !==
-								''
-									? 'mr-2'
-									: ''}"
-								type="url"
-								required
-								bind:value={modelFileUrl}
-								placeholder="Type HuggingFace Resolve (Download) URL"
-							/>
-						</div>
-					{/if}
-				</div>
 
-				{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
-					<button
-						class="px-3 text-gray-100 bg-emerald-600 hover:bg-emerald-700 disabled:bg-gray-700 disabled:cursor-not-allowed rounded transition"
-						type="submit"
-						disabled={modelTransferring}
-					>
-						{#if modelTransferring}
-							<div class="self-center">
-								<svg
-									class=" w-4 h-4"
-									viewBox="0 0 24 24"
-									fill="currentColor"
-									xmlns="http://www.w3.org/2000/svg"
-									><style>
-										.spinner_ajPY {
-											transform-origin: center;
-											animation: spinner_AtaB 0.75s infinite linear;
-										}
-										@keyframes spinner_AtaB {
-											100% {
-												transform: rotate(360deg);
-											}
-										}
-									</style><path
-										d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
-										opacity=".25"
-									/><path
-										d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
-										class="spinner_ajPY"
-									/></svg
+						<div class="flex w-full mb-1.5">
+							<div class="flex flex-col w-full">
+								{#if modelUploadMode === 'file'}
+									<div class="flex-1 {modelInputFile && modelInputFile.length > 0 ? 'mr-2' : ''}">
+										<input
+											id="model-upload-input"
+											type="file"
+											bind:files={modelInputFile}
+											on:change={() => {
+												console.log(modelInputFile);
+											}}
+											accept=".gguf"
+											required
+											hidden
+										/>
+
+										<button
+											type="button"
+											class="w-full rounded text-left py-2 px-4 dark:text-gray-300 dark:bg-gray-850"
+											on:click={() => {
+												document.getElementById('model-upload-input').click();
+											}}
+										>
+											{#if modelInputFile && modelInputFile.length > 0}
+												{modelInputFile[0].name}
+											{:else}
+												Click here to select
+											{/if}
+										</button>
+									</div>
+								{:else}
+									<div class="flex-1 {modelFileUrl !== '' ? 'mr-2' : ''}">
+										<input
+											class="w-full rounded text-left py-2 px-4 dark:text-gray-300 dark:bg-gray-850 outline-none {modelFileUrl !==
+											''
+												? 'mr-2'
+												: ''}"
+											type="url"
+											required
+											bind:value={modelFileUrl}
+											placeholder="Type HuggingFace Resolve (Download) URL"
+										/>
+									</div>
+								{/if}
+							</div>
+
+							{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
+								<button
+									class="px-3 text-gray-100 bg-emerald-600 hover:bg-emerald-700 disabled:bg-gray-700 disabled:cursor-not-allowed rounded transition"
+									type="submit"
+									disabled={modelTransferring}
 								>
+									{#if modelTransferring}
+										<div class="self-center">
+											<svg
+												class=" w-4 h-4"
+												viewBox="0 0 24 24"
+												fill="currentColor"
+												xmlns="http://www.w3.org/2000/svg"
+												><style>
+													.spinner_ajPY {
+														transform-origin: center;
+														animation: spinner_AtaB 0.75s infinite linear;
+													}
+													@keyframes spinner_AtaB {
+														100% {
+															transform: rotate(360deg);
+														}
+													}
+												</style><path
+													d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
+													opacity=".25"
+												/><path
+													d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
+													class="spinner_ajPY"
+												/></svg
+											>
+										</div>
+									{:else}
+										<svg
+											xmlns="http://www.w3.org/2000/svg"
+											viewBox="0 0 16 16"
+											fill="currentColor"
+											class="w-4 h-4"
+										>
+											<path
+												d="M7.25 10.25a.75.75 0 0 0 1.5 0V4.56l2.22 2.22a.75.75 0 1 0 1.06-1.06l-3.5-3.5a.75.75 0 0 0-1.06 0l-3.5 3.5a.75.75 0 0 0 1.06 1.06l2.22-2.22v5.69Z"
+											/>
+											<path
+												d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
+											/>
+										</svg>
+									{/if}
+								</button>
+							{/if}
+						</div>
+
+						{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
+							<div>
+								<div>
+									<div class=" my-2.5 text-sm font-medium">Modelfile Content</div>
+									<textarea
+										bind:value={modelFileContent}
+										class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none resize-none"
+										rows="6"
+									/>
+								</div>
 							</div>
-						{:else}
-							<svg
-								xmlns="http://www.w3.org/2000/svg"
-								viewBox="0 0 16 16"
-								fill="currentColor"
-								class="w-4 h-4"
+						{/if}
+						<div class=" mt-1 text-xs text-gray-400 dark:text-gray-500">
+							To access the GGUF models available for downloading, <a
+								class=" text-gray-500 dark:text-gray-300 font-medium"
+								href="https://huggingface.co/models?search=gguf"
+								target="_blank">click here.</a
 							>
-								<path
-									d="M7.25 10.25a.75.75 0 0 0 1.5 0V4.56l2.22 2.22a.75.75 0 1 0 1.06-1.06l-3.5-3.5a.75.75 0 0 0-1.06 0l-3.5 3.5a.75.75 0 0 0 1.06 1.06l2.22-2.22v5.69Z"
-								/>
-								<path
-									d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
-								/>
-							</svg>
+						</div>
+
+						{#if uploadProgress !== null}
+							<div class="mt-2">
+								<div class=" mb-2 text-xs">Upload Progress</div>
+
+								<div class="w-full rounded-full dark:bg-gray-800">
+									<div
+										class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
+										style="width: {Math.max(15, uploadProgress ?? 0)}%"
+									>
+										{uploadProgress ?? 0}%
+									</div>
+								</div>
+								<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
+									{modelFileDigest}
+								</div>
+							</div>
 						{/if}
-					</button>
+					</form>
 				{/if}
 			</div>
+			<hr class=" dark:border-gray-700 my-2" />
+		{/if}
 
-			{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
+		<div class=" space-y-3">
+			<div class="mt-2 space-y-3 pr-1.5">
 				<div>
+					<div class=" mb-2 text-sm font-medium">Manage LiteLLM Models</div>
+
+					<div>
+						<div class="flex justify-between items-center text-xs">
+							<div class=" text-sm font-medium">Add a model</div>
+							<button
+								class=" text-xs font-medium text-gray-500"
+								type="button"
+								on:click={() => {
+									showLiteLLMParams = !showLiteLLMParams;
+								}}>{showLiteLLMParams ? 'Advanced' : 'Default'}</button
+							>
+						</div>
+					</div>
+
+					<div class="my-2 space-y-2">
+						<div class="flex w-full mb-1.5">
+							<div class="flex-1 mr-2">
+								<input
+									class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+									placeholder="Enter LiteLLM Model (litellm_params.model)"
+									bind:value={liteLLMModel}
+									autocomplete="off"
+								/>
+							</div>
+
+							<button
+								class="px-3 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded transition"
+								on:click={() => {
+									addLiteLLMModelHandler();
+								}}
+							>
+								<svg
+									xmlns="http://www.w3.org/2000/svg"
+									viewBox="0 0 16 16"
+									fill="currentColor"
+									class="w-4 h-4"
+								>
+									<path
+										d="M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z"
+									/>
+								</svg>
+							</button>
+						</div>
+
+						{#if showLiteLLMParams}
+							<div>
+								<div class=" mb-1.5 text-sm font-medium">Model Name</div>
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											placeholder="Enter Model Name (model_name)"
+											bind:value={liteLLMModelName}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+
+							<div>
+								<div class=" mb-1.5 text-sm font-medium">API Base URL</div>
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											placeholder="Enter LiteLLM API Base URL (litellm_params.api_base)"
+											bind:value={liteLLMAPIBase}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+
+							<div>
+								<div class=" mb-1.5 text-sm font-medium">API Key</div>
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											placeholder="Enter LiteLLM API Key (litellm_params.api_key)"
+											bind:value={liteLLMAPIKey}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+
+							<div>
+								<div class="mb-1.5 text-sm font-medium">API RPM</div>
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											placeholder="Enter LiteLLM API RPM (litellm_params.rpm)"
+											bind:value={liteLLMRPM}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+						{/if}
+					</div>
+
+					<div class="mb-2 text-xs text-gray-400 dark:text-gray-500">
+						Not sure what to add?
+						<a
+							class=" text-gray-300 font-medium"
+							href="https://litellm.vercel.app/docs/proxy/configs#quick-start"
+							target="_blank"
+						>
+							Click here for help.
+						</a>
+					</div>
+
 					<div>
-						<div class=" my-2.5 text-sm font-medium">Modelfile Content</div>
-						<textarea
-							bind:value={modelFileContent}
-							class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none resize-none"
-							rows="6"
-						/>
+						<div class=" mb-2.5 text-sm font-medium">Delete a model</div>
+						<div class="flex w-full">
+							<div class="flex-1 mr-2">
+								<select
+									class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+									bind:value={deleteLiteLLMModelId}
+									placeholder="Select a model"
+								>
+									{#if !deleteLiteLLMModelId}
+										<option value="" disabled selected>Select a model</option>
+									{/if}
+									{#each liteLLMModelInfo as model}
+										<option value={model.model_info.id} class="bg-gray-100 dark:bg-gray-700"
+											>{model.model_name}</option
+										>
+									{/each}
+								</select>
+							</div>
+							<button
+								class="px-3 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded transition"
+								on:click={() => {
+									deleteLiteLLMModelHandler();
+								}}
+							>
+								<svg
+									xmlns="http://www.w3.org/2000/svg"
+									viewBox="0 0 16 16"
+									fill="currentColor"
+									class="w-4 h-4"
+								>
+									<path
+										fill-rule="evenodd"
+										d="M5 3.25V4H2.75a.75.75 0 0 0 0 1.5h.3l.815 8.15A1.5 1.5 0 0 0 5.357 15h5.285a1.5 1.5 0 0 0 1.493-1.35l.815-8.15h.3a.75.75 0 0 0 0-1.5H11v-.75A2.25 2.25 0 0 0 8.75 1h-1.5A2.25 2.25 0 0 0 5 3.25Zm2.25-.75a.75.75 0 0 0-.75.75V4h3v-.75a.75.75 0 0 0-.75-.75h-1.5ZM6.05 6a.75.75 0 0 1 .787.713l.275 5.5a.75.75 0 0 1-1.498.075l-.275-5.5A.75.75 0 0 1 6.05 6Zm3.9 0a.75.75 0 0 1 .712.787l-.275 5.5a.75.75 0 0 1-1.498-.075l.275-5.5a.75.75 0 0 1 .786-.711Z"
+										clip-rule="evenodd"
+									/>
+								</svg>
+							</button>
+						</div>
 					</div>
 				</div>
-			{/if}
-			<div class=" mt-1 text-xs text-gray-400 dark:text-gray-500">
-				To access the GGUF models available for downloading, <a
-					class=" text-gray-500 dark:text-gray-300 font-medium"
-					href="https://huggingface.co/models?search=gguf"
-					target="_blank">click here.</a
-				>
 			</div>
 
-			{#if uploadProgress !== null}
-				<div class="mt-2">
-					<div class=" mb-2 text-xs">Upload Progress</div>
+			<!-- <div class="mt-2 space-y-3 pr-1.5">
+				<div>
+					<div class=" mb-2.5 text-sm font-medium">Add LiteLLM Model</div>
+					<div class="flex w-full mb-2">
+						<div class="flex-1">
+							<input
+								class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
+								placeholder="Enter LiteLLM Model (e.g. ollama/mistral)"
+								bind:value={liteLLMModel}
+								autocomplete="off"
+							/>
+						</div>
+					</div>
 
-					<div class="w-full rounded-full dark:bg-gray-800">
-						<div
-							class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
-							style="width: {Math.max(15, uploadProgress ?? 0)}%"
+					<div class="flex justify-between items-center text-sm">
+						<div class="  font-medium">Advanced Model Params</div>
+						<button
+							class=" text-xs font-medium text-gray-500"
+							type="button"
+							on:click={() => {
+								showLiteLLMParams = !showLiteLLMParams;
+							}}>{showLiteLLMParams ? 'Hide' : 'Show'}</button
 						>
-							{uploadProgress ?? 0}%
-						</div>
 					</div>
-					<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
-						{modelFileDigest}
+
+					{#if showLiteLLMParams}
+						<div>
+							<div class=" mb-2.5 text-sm font-medium">LiteLLM API Key</div>
+							<div class="flex w-full">
+								<div class="flex-1">
+									<input
+										class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
+										placeholder="Enter LiteLLM API Key (e.g. os.environ/AZURE_API_KEY_CA)"
+										bind:value={liteLLMAPIKey}
+										autocomplete="off"
+									/>
+								</div>
+							</div>
+						</div>
+
+						<div>
+							<div class=" mb-2.5 text-sm font-medium">LiteLLM API Base URL</div>
+							<div class="flex w-full">
+								<div class="flex-1">
+									<input
+										class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
+										placeholder="Enter LiteLLM API Base URL"
+										bind:value={liteLLMAPIBase}
+										autocomplete="off"
+									/>
+								</div>
+							</div>
+						</div>
+
+						<div>
+							<div class=" mb-2.5 text-sm font-medium">LiteLLM API RPM</div>
+							<div class="flex w-full">
+								<div class="flex-1">
+									<input
+										class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
+										placeholder="Enter LiteLLM API RPM"
+										bind:value={liteLLMRPM}
+										autocomplete="off"
+									/>
+								</div>
+							</div>
+						</div>
+					{/if}
+
+					<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
+						Not sure what to add?
+						<a
+							class=" text-gray-300 font-medium"
+							href="https://litellm.vercel.app/docs/proxy/configs#quick-start"
+							target="_blank"
+						>
+							Click here for help.
+						</a>
 					</div>
 				</div>
-			{/if}
-		</form>
+			</div> -->
+		</div>
 	</div>
 </div>