Преглед на файлове

feat: multiple models chat user permissions

Timothy Jaeryang Baek преди 4 месеца
родител
ревизия
79dff685ea

+ 6 - 0
backend/open_webui/config.py

@@ -1062,6 +1062,10 @@ USER_PERMISSIONS_CHAT_EDIT = (
     os.environ.get("USER_PERMISSIONS_CHAT_EDIT", "True").lower() == "true"
 )
 
+USER_PERMISSIONS_CHAT_MULTIPLE_MODELS = (
+    os.environ.get("USER_PERMISSIONS_CHAT_MULTIPLE_MODELS", "True").lower() == "true"
+)
+
 USER_PERMISSIONS_CHAT_TEMPORARY = (
     os.environ.get("USER_PERMISSIONS_CHAT_TEMPORARY", "True").lower() == "true"
 )
@@ -1071,6 +1075,7 @@ USER_PERMISSIONS_CHAT_TEMPORARY_ENFORCED = (
     == "true"
 )
 
+
 USER_PERMISSIONS_FEATURES_DIRECT_TOOL_SERVERS = (
     os.environ.get("USER_PERMISSIONS_FEATURES_DIRECT_TOOL_SERVERS", "False").lower()
     == "true"
@@ -1109,6 +1114,7 @@ DEFAULT_USER_PERMISSIONS = {
         "file_upload": USER_PERMISSIONS_CHAT_FILE_UPLOAD,
         "delete": USER_PERMISSIONS_CHAT_DELETE,
         "edit": USER_PERMISSIONS_CHAT_EDIT,
+        "multiple_models": USER_PERMISSIONS_CHAT_MULTIPLE_MODELS,
         "temporary": USER_PERMISSIONS_CHAT_TEMPORARY,
         "temporary_enforced": USER_PERMISSIONS_CHAT_TEMPORARY_ENFORCED,
     },

+ 1 - 0
backend/open_webui/routers/users.py

@@ -88,6 +88,7 @@ class ChatPermissions(BaseModel):
     file_upload: bool = True
     delete: bool = True
     edit: bool = True
+    multiple_models: bool = True
     temporary: bool = True
     temporary_enforced: bool = False
 

+ 1 - 0
src/lib/components/admin/Users/Groups.svelte

@@ -63,6 +63,7 @@
 			file_upload: true,
 			delete: true,
 			edit: true,
+			multiple_models: true,
 			temporary: true,
 			temporary_enforced: false
 		},

+ 9 - 0
src/lib/components/admin/Users/Groups/Permissions.svelte

@@ -24,6 +24,7 @@
 			delete: true,
 			edit: true,
 			file_upload: true,
+			multiple_models: true,
 			temporary: true,
 			temporary_enforced: false
 		},
@@ -272,6 +273,14 @@
 			<Switch bind:state={permissions.chat.edit} />
 		</div>
 
+		<div class="  flex w-full justify-between my-2 pr-2">
+			<div class=" self-center text-xs font-medium">
+				{$i18n.t('Allow Multiple Models in Chat')}
+			</div>
+
+			<Switch bind:state={permissions.chat.multiple_models} />
+		</div>
+
 		<div class="  flex w-full justify-between my-2 pr-2">
 			<div class=" self-center text-xs font-medium">
 				{$i18n.t('Allow Temporary Chat')}

+ 52 - 50
src/lib/components/chat/ModelSelector.svelte

@@ -54,58 +54,60 @@
 				</div>
 			</div>
 
-			{#if selectedModelIdx === 0}
-				<div
-					class="  self-center mx-1 disabled:text-gray-600 disabled:hover:text-gray-600 -translate-y-[0.5px]"
-				>
-					<Tooltip content={$i18n.t('Add Model')}>
-						<button
-							class=" "
-							{disabled}
-							on:click={() => {
-								selectedModels = [...selectedModels, ''];
-							}}
-							aria-label="Add Model"
-						>
-							<svg
-								xmlns="http://www.w3.org/2000/svg"
-								fill="none"
-								viewBox="0 0 24 24"
-								stroke-width="2"
-								stroke="currentColor"
-								class="size-3.5"
+			{#if $user?.role === 'admin' || ($user?.permissions?.chat?.multiple_models ?? true)}
+				{#if selectedModelIdx === 0}
+					<div
+						class="  self-center mx-1 disabled:text-gray-600 disabled:hover:text-gray-600 -translate-y-[0.5px]"
+					>
+						<Tooltip content={$i18n.t('Add Model')}>
+							<button
+								class=" "
+								{disabled}
+								on:click={() => {
+									selectedModels = [...selectedModels, ''];
+								}}
+								aria-label="Add Model"
 							>
-								<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m6-6H6" />
-							</svg>
-						</button>
-					</Tooltip>
-				</div>
-			{:else}
-				<div
-					class="  self-center mx-1 disabled:text-gray-600 disabled:hover:text-gray-600 -translate-y-[0.5px]"
-				>
-					<Tooltip content={$i18n.t('Remove Model')}>
-						<button
-							{disabled}
-							on:click={() => {
-								selectedModels.splice(selectedModelIdx, 1);
-								selectedModels = selectedModels;
-							}}
-							aria-label="Remove Model"
-						>
-							<svg
-								xmlns="http://www.w3.org/2000/svg"
-								fill="none"
-								viewBox="0 0 24 24"
-								stroke-width="2"
-								stroke="currentColor"
-								class="size-3"
+								<svg
+									xmlns="http://www.w3.org/2000/svg"
+									fill="none"
+									viewBox="0 0 24 24"
+									stroke-width="2"
+									stroke="currentColor"
+									class="size-3.5"
+								>
+									<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m6-6H6" />
+								</svg>
+							</button>
+						</Tooltip>
+					</div>
+				{:else}
+					<div
+						class="  self-center mx-1 disabled:text-gray-600 disabled:hover:text-gray-600 -translate-y-[0.5px]"
+					>
+						<Tooltip content={$i18n.t('Remove Model')}>
+							<button
+								{disabled}
+								on:click={() => {
+									selectedModels.splice(selectedModelIdx, 1);
+									selectedModels = selectedModels;
+								}}
+								aria-label="Remove Model"
 							>
-								<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12h-15" />
-							</svg>
-						</button>
-					</Tooltip>
-				</div>
+								<svg
+									xmlns="http://www.w3.org/2000/svg"
+									fill="none"
+									viewBox="0 0 24 24"
+									stroke-width="2"
+									stroke="currentColor"
+									class="size-3"
+								>
+									<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12h-15" />
+								</svg>
+							</button>
+						</Tooltip>
+					</div>
+				{/if}
 			{/if}
 		</div>
 	{/each}