Parcourir la source

feat: local/external connections

Timothy Jaeryang Baek il y a 4 mois
Parent
commit
08e4c163ea

+ 8 - 4
backend/open_webui/routers/ollama.py

@@ -340,6 +340,8 @@ async def get_all_models(request: Request, user: UserModel = None):
                     ),  # Legacy support
                 )
 
+                connection_type = api_config.get("connection_type", "local")
+
                 prefix_id = api_config.get("prefix_id", None)
                 tags = api_config.get("tags", [])
                 model_ids = api_config.get("model_ids", [])
@@ -352,14 +354,16 @@ async def get_all_models(request: Request, user: UserModel = None):
                         )
                     )
 
-                if prefix_id:
-                    for model in response.get("models", []):
+                for model in response.get("models", []):
+                    if prefix_id:
                         model["model"] = f"{prefix_id}.{model['model']}"
 
-                if tags:
-                    for model in response.get("models", []):
+                    if tags:
                         model["tags"] = tags
 
+                    if connection_type:
+                        model["connection_type"] = connection_type
+
         def merge_models_lists(model_lists):
             merged_models = {}
 

+ 10 - 8
backend/open_webui/routers/openai.py

@@ -353,21 +353,22 @@ async def get_all_models_responses(request: Request, user: UserModel) -> list:
                 ),  # Legacy support
             )
 
+            connection_type = api_config.get("connection_type", "external")
             prefix_id = api_config.get("prefix_id", None)
             tags = api_config.get("tags", [])
 
-            if prefix_id:
-                for model in (
-                    response if isinstance(response, list) else response.get("data", [])
-                ):
+            for model in (
+                response if isinstance(response, list) else response.get("data", [])
+            ):
+                if prefix_id:
                     model["id"] = f"{prefix_id}.{model['id']}"
 
-            if tags:
-                for model in (
-                    response if isinstance(response, list) else response.get("data", [])
-                ):
+                if tags:
                     model["tags"] = tags
 
+                if connection_type:
+                    model["connection_type"] = connection_type
+
     log.debug(f"get_all_models:responses() {responses}")
     return responses
 
@@ -415,6 +416,7 @@ async def get_all_models(request: Request, user: UserModel) -> dict[str, list]:
                             "name": model.get("name", model["id"]),
                             "owned_by": "openai",
                             "openai": model,
+                            "connection_type": model.get("connection_type", "external"),
                             "urlIdx": idx,
                         }
                         for model in models

+ 1 - 0
backend/open_webui/utils/models.py

@@ -49,6 +49,7 @@ async def get_all_base_models(request: Request, user: UserModel = None):
                 "created": int(time.time()),
                 "owned_by": "ollama",
                 "ollama": model,
+                "connection_type": model.get("connection_type", "local"),
                 "tags": model.get("tags", []),
             }
             for model in ollama_models["models"]

+ 36 - 2
src/lib/components/AddConnectionModal.svelte

@@ -30,6 +30,9 @@
 	let url = '';
 	let key = '';
 
+	let connectionType = 'external';
+	let azure = false;
+
 	let prefixId = '';
 	let enable = true;
 	let tags = [];
@@ -95,7 +98,9 @@
 				enable: enable,
 				tags: tags,
 				prefix_id: prefixId,
-				model_ids: modelIds
+				model_ids: modelIds,
+				connection_type: connectionType,
+				...(!ollama && azure ? { azure: true } : {})
 			}
 		};
 
@@ -120,6 +125,13 @@
 			tags = connection.config?.tags ?? [];
 			prefixId = connection.config?.prefix_id ?? '';
 			modelIds = connection.config?.model_ids ?? [];
+
+			if (ollama) {
+				connectionType = connection.config?.connection_type ?? 'local';
+			} else {
+				connectionType = connection.config?.connection_type ?? 'external';
+				azure = connection.config?.azure ?? false;
+			}
 		}
 	};
 
@@ -134,7 +146,7 @@
 
 <Modal size="sm" bind:show>
 	<div>
-		<div class=" flex justify-between dark:text-gray-100 px-5 pt-4 pb-2">
+		<div class=" flex justify-between dark:text-gray-100 px-5 pt-4 pb-1.5">
 			<div class=" text-lg font-medium self-center font-primary">
 				{#if edit}
 					{$i18n.t('Edit Connection')}
@@ -172,6 +184,28 @@
 				>
 					<div class="px-1">
 						<div class="flex gap-2">
+							<div class="flex w-full justify-between items-center">
+								<div class=" text-xs text-gray-500">{$i18n.t('Connection Type')}</div>
+
+								<div class="">
+									<button
+										on:click={() => {
+											connectionType = connectionType === 'local' ? 'external' : 'local';
+										}}
+										type="button"
+										class=" text-xs text-gray-700 dark:text-gray-300"
+									>
+										{#if connectionType === 'local'}
+											{$i18n.t('Local')}
+										{:else}
+											{$i18n.t('External')}
+										{/if}
+									</button>
+								</div>
+							</div>
+						</div>
+
+						<div class="flex gap-2 mt-1.5">
 							<div class="flex flex-col w-full">
 								<div class=" mb-0.5 text-xs text-gray-500">{$i18n.t('URL')}</div>
 

+ 5 - 5
src/lib/components/admin/Settings/Interface.svelte

@@ -108,8 +108,8 @@
 
 				<hr class=" border-gray-100 dark:border-gray-850 my-2" />
 
-				<div class=" mb-1 font-medium flex items-center">
-					<div class=" text-xs mr-1">{$i18n.t('Set Task Model')}</div>
+				<div class=" mb-2 font-medium flex items-center">
+					<div class=" text-xs mr-1">{$i18n.t('Task Model')}</div>
 					<Tooltip
 						content={$i18n.t(
 							'A task model is used when performing tasks such as generating titles for chats and web search queries'
@@ -134,7 +134,7 @@
 
 				<div class=" mb-2.5 flex w-full gap-2">
 					<div class="flex-1">
-						<div class=" text-xs mb-1">{$i18n.t('Local Models')}</div>
+						<div class=" text-xs mb-1">{$i18n.t('Local Task Model')}</div>
 						<select
 							class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
 							bind:value={taskConfig.TASK_MODEL}
@@ -159,7 +159,7 @@
 							}}
 						>
 							<option value="" selected>{$i18n.t('Current Model')}</option>
-							{#each models.filter((m) => m.owned_by === 'ollama') as model}
+							{#each models.filter((m) => m.connection_type === 'local') as model}
 								<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
 									{model.name}
 								</option>
@@ -168,7 +168,7 @@
 					</div>
 
 					<div class="flex-1">
-						<div class=" text-xs mb-1">{$i18n.t('External Models')}</div>
+						<div class=" text-xs mb-1">{$i18n.t('External Task Model')}</div>
 						<select
 							class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
 							bind:value={taskConfig.TASK_MODEL_EXTERNAL}

+ 14 - 14
src/lib/components/chat/ModelSelector/Selector.svelte

@@ -100,10 +100,10 @@
 					.filter((item) => {
 						if (selectedConnectionType === '') {
 							return true;
-						} else if (selectedConnectionType === 'ollama') {
-							return item.model?.owned_by === 'ollama';
-						} else if (selectedConnectionType === 'openai') {
-							return item.model?.owned_by === 'openai';
+						} else if (selectedConnectionType === 'local') {
+							return item.model?.connection_type === 'local';
+						} else if (selectedConnectionType === 'external') {
+							return item.model?.connection_type === 'external';
 						} else if (selectedConnectionType === 'direct') {
 							return item.model?.direct;
 						}
@@ -118,10 +118,10 @@
 					.filter((item) => {
 						if (selectedConnectionType === '') {
 							return true;
-						} else if (selectedConnectionType === 'ollama') {
-							return item.model?.owned_by === 'ollama';
-						} else if (selectedConnectionType === 'openai') {
-							return item.model?.owned_by === 'openai';
+						} else if (selectedConnectionType === 'local') {
+							return item.model?.connection_type === 'local';
+						} else if (selectedConnectionType === 'external') {
+							return item.model?.connection_type === 'external';
 						} else if (selectedConnectionType === 'direct') {
 							return item.model?.direct;
 						}
@@ -393,7 +393,7 @@
 							class="flex gap-1 w-fit text-center text-sm font-medium rounded-full bg-transparent px-1.5 pb-0.5"
 							bind:this={tagsContainerElement}
 						>
-							{#if (items.find((item) => item.model?.owned_by === 'ollama') && items.find((item) => item.model?.owned_by === 'openai')) || items.find((item) => item.model?.direct) || tags.length > 0}
+							{#if (items.find((item) => item.model?.connection_type === 'local') && items.find((item) => item.model?.connection_type === 'external')) || items.find((item) => item.model?.direct) || tags.length > 0}
 								<button
 									class="min-w-fit outline-none p-1.5 {selectedTag === '' &&
 									selectedConnectionType === ''
@@ -408,25 +408,25 @@
 								</button>
 							{/if}
 
-							{#if items.find((item) => item.model?.owned_by === 'ollama') && items.find((item) => item.model?.owned_by === 'openai')}
+							{#if items.find((item) => item.model?.connection_type === 'local') && items.find((item) => item.model?.connection_type === 'external')}
 								<button
-									class="min-w-fit outline-none p-1.5 {selectedConnectionType === 'ollama'
+									class="min-w-fit outline-none p-1.5 {selectedConnectionType === 'local'
 										? ''
 										: 'text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition capitalize"
 									on:click={() => {
 										selectedTag = '';
-										selectedConnectionType = 'ollama';
+										selectedConnectionType = 'local';
 									}}
 								>
 									{$i18n.t('Local')}
 								</button>
 								<button
-									class="min-w-fit outline-none p-1.5 {selectedConnectionType === 'openai'
+									class="min-w-fit outline-none p-1.5 {selectedConnectionType === 'external'
 										? ''
 										: 'text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition capitalize"
 									on:click={() => {
 										selectedTag = '';
-										selectedConnectionType = 'openai';
+										selectedConnectionType = 'external';
 									}}
 								>
 									{$i18n.t('External')}