瀏覽代碼

feat: export litellm config.yaml

Timothy J. Baek 11 月之前
父節點
當前提交
c6a57b1f6f
共有 3 個文件被更改,包括 82 次插入4 次删除
  1. 9 0
      backend/apps/webui/routers/utils.py
  2. 36 0
      src/lib/apis/utils/index.ts
  3. 37 4
      src/lib/components/admin/Settings/Database.svelte

+ 9 - 0
backend/apps/webui/routers/utils.py

@@ -107,3 +107,12 @@ async def download_db(user=Depends(get_admin_user)):
         media_type="application/octet-stream",
         filename="webui.db",
     )
+
+
+@router.get("/litellm/config")
+async def download_litellm_config_yaml(user=Depends(get_admin_user)):
+    return FileResponse(
+        f"{DATA_DIR}/litellm/config.yaml",
+        media_type="application/octet-stream",
+        filename="config.yaml",
+    )

+ 36 - 0
src/lib/apis/utils/index.ts

@@ -108,3 +108,39 @@ export const downloadDatabase = async (token: string) => {
 		throw error;
 	}
 };
+
+export const downloadLiteLLMConfig = async (token: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/utils/litellm/config`, {
+		method: 'GET',
+		headers: {
+			'Content-Type': 'application/json',
+			Authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (response) => {
+			if (!response.ok) {
+				throw await response.json();
+			}
+			return response.blob();
+		})
+		.then((blob) => {
+			const url = window.URL.createObjectURL(blob);
+			const a = document.createElement('a');
+			a.href = url;
+			a.download = 'config.yaml';
+			document.body.appendChild(a);
+			a.click();
+			window.URL.revokeObjectURL(url);
+		})
+		.catch((err) => {
+			console.log(err);
+			error = err.detail;
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+};

+ 37 - 4
src/lib/components/admin/Settings/Database.svelte

@@ -2,7 +2,7 @@
 	import fileSaver from 'file-saver';
 	const { saveAs } = fileSaver;
 
-	import { downloadDatabase } from '$lib/apis/utils';
+	import { downloadDatabase, downloadLiteLLMConfig } from '$lib/apis/utils';
 	import { onMount, getContext } from 'svelte';
 	import { config, user } from '$lib/stores';
 	import { toast } from 'svelte-sonner';
@@ -68,10 +68,8 @@
 					</button>
 				</div>
 
-				<hr class=" dark:border-gray-700 my-1" />
-
 				<button
-					class=" flex rounded-md py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
+					class=" flex rounded-md py-2 px-3 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
 					on:click={() => {
 						exportAllUserChats();
 					}}
@@ -96,6 +94,41 @@
 					</div>
 				</button>
 			{/if}
+
+			<hr class=" dark:border-gray-850 my-1" />
+
+			<div class="  flex w-full justify-between">
+				<!-- <div class=" self-center text-xs font-medium">{$i18n.t('Allow Chat Deletion')}</div> -->
+
+				<button
+					class=" flex rounded-md py-1.5 px-3 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
+					type="button"
+					on:click={() => {
+						downloadLiteLLMConfig(localStorage.token).catch((error) => {
+							toast.error(error);
+						});
+					}}
+				>
+					<div class=" self-center mr-3">
+						<svg
+							xmlns="http://www.w3.org/2000/svg"
+							viewBox="0 0 24 24"
+							fill="currentColor"
+							class="size-4"
+						>
+							<path
+								fill-rule="evenodd"
+								d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm5.845 17.03a.75.75 0 0 0 1.06 0l3-3a.75.75 0 1 0-1.06-1.06l-1.72 1.72V12a.75.75 0 0 0-1.5 0v4.19l-1.72-1.72a.75.75 0 0 0-1.06 1.06l3 3Z"
+								clip-rule="evenodd"
+							/>
+							<path
+								d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z"
+							/>
+						</svg>
+					</div>
+					<div class=" self-center text-sm font-medium">Export LiteLLM config.yaml</div>
+				</button>
+			</div>
 		</div>
 	</div>