Timothy Jaeryang Baek 5 months ago
parent
commit
a1ce8422fd

+ 2 - 0
backend/open_webui/apps/webui/models/prompts.py

@@ -61,6 +61,7 @@ class PromptForm(BaseModel):
     command: str
     command: str
     title: str
     title: str
     content: str
     content: str
+    access_control: Optional[dict] = None
 
 
 
 
 class PromptsTable:
 class PromptsTable:
@@ -124,6 +125,7 @@ class PromptsTable:
                 prompt = db.query(Prompt).filter_by(command=command).first()
                 prompt = db.query(Prompt).filter_by(command=command).first()
                 prompt.title = form_data.title
                 prompt.title = form_data.title
                 prompt.content = form_data.content
                 prompt.content = form_data.content
+                prompt.access_control = form_data.access_control
                 prompt.timestamp = int(time.time())
                 prompt.timestamp = int(time.time())
                 db.commit()
                 db.commit()
                 return PromptModel.model_validate(prompt)
                 return PromptModel.model_validate(prompt)

+ 19 - 13
src/lib/apis/prompts/index.ts

@@ -1,10 +1,18 @@
 import { WEBUI_API_BASE_URL } from '$lib/constants';
 import { WEBUI_API_BASE_URL } from '$lib/constants';
 
 
+
+type PromptItem = {
+	command: string;
+	title: string;
+	content: string;
+	access_control: null|object;
+}
+
+
+
 export const createNewPrompt = async (
 export const createNewPrompt = async (
 	token: string,
 	token: string,
-	command: string,
-	title: string,
-	content: string
+	prompt: PromptItem
 ) => {
 ) => {
 	let error = null;
 	let error = null;
 
 
@@ -16,9 +24,8 @@ export const createNewPrompt = async (
 			authorization: `Bearer ${token}`
 			authorization: `Bearer ${token}`
 		},
 		},
 		body: JSON.stringify({
 		body: JSON.stringify({
-			command: `/${command}`,
-			title: title,
-			content: content
+			...prompt,
+			command: `/${prompt.command}`,
 		})
 		})
 	})
 	})
 		.then(async (res) => {
 		.then(async (res) => {
@@ -134,15 +141,15 @@ export const getPromptByCommand = async (token: string, command: string) => {
 	return res;
 	return res;
 };
 };
 
 
+
+
 export const updatePromptByCommand = async (
 export const updatePromptByCommand = async (
 	token: string,
 	token: string,
-	command: string,
-	title: string,
-	content: string
+	prompt: PromptItem
 ) => {
 ) => {
 	let error = null;
 	let error = null;
 
 
-	const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/command/${command}/update`, {
+	const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/command/${prompt.command}/update`, {
 		method: 'POST',
 		method: 'POST',
 		headers: {
 		headers: {
 			Accept: 'application/json',
 			Accept: 'application/json',
@@ -150,9 +157,8 @@ export const updatePromptByCommand = async (
 			authorization: `Bearer ${token}`
 			authorization: `Bearer ${token}`
 		},
 		},
 		body: JSON.stringify({
 		body: JSON.stringify({
-			command: `/${command}`,
-			title: title,
-			content: content
+			...prompt,
+			command: `/${prompt.command}`,
 		})
 		})
 	})
 	})
 		.then(async (res) => {
 		.then(async (res) => {

+ 4 - 18
src/lib/components/chat/Chat.svelte

@@ -153,15 +153,17 @@
 		console.log('saveSessionSelectedModels', selectedModels, sessionStorage.selectedModels);
 		console.log('saveSessionSelectedModels', selectedModels, sessionStorage.selectedModels);
 	};
 	};
 
 
-	$: if (selectedModelIds) {
+	$: if (selectedModels) {
 		setToolIds();
 		setToolIds();
 	}
 	}
 
 
-	const setToolIds = () => {
+	const setToolIds = async () => {
 		if (selectedModels.length !== 1) {
 		if (selectedModels.length !== 1) {
 			return;
 			return;
 		}
 		}
 
 
+		console.log('setToolIds', selectedModels);
+
 		const model = $models.find((m) => m.id === selectedModels[0]);
 		const model = $models.find((m) => m.id === selectedModels[0]);
 		if (model) {
 		if (model) {
 			selectedToolIds = model?.info?.meta?.toolIds ?? [];
 			selectedToolIds = model?.info?.meta?.toolIds ?? [];
@@ -495,8 +497,6 @@
 			}
 			}
 		}
 		}
 
 
-		console.log(selectedModels);
-
 		await showControls.set(false);
 		await showControls.set(false);
 		await showCallOverlay.set(false);
 		await showCallOverlay.set(false);
 		await showOverview.set(false);
 		await showOverview.set(false);
@@ -2282,13 +2282,6 @@
 								bind:selectedToolIds
 								bind:selectedToolIds
 								bind:webSearchEnabled
 								bind:webSearchEnabled
 								bind:atSelectedModel
 								bind:atSelectedModel
-								availableToolIds={selectedModelIds.reduce((a, e, i, arr) => {
-									const model = $models.find((m) => m.id === e);
-									if (model?.info?.meta?.toolIds ?? false) {
-										return [...new Set([...a, ...model.info.meta.toolIds])];
-									}
-									return a;
-								}, [])}
 								transparentBackground={$settings?.backgroundImageUrl ?? false}
 								transparentBackground={$settings?.backgroundImageUrl ?? false}
 								{stopResponse}
 								{stopResponse}
 								{createMessagePair}
 								{createMessagePair}
@@ -2326,13 +2319,6 @@
 								bind:selectedToolIds
 								bind:selectedToolIds
 								bind:webSearchEnabled
 								bind:webSearchEnabled
 								bind:atSelectedModel
 								bind:atSelectedModel
-								availableToolIds={selectedModelIds.reduce((a, e, i, arr) => {
-									const model = $models.find((m) => m.id === e);
-									if (model?.info?.meta?.toolIds ?? false) {
-										return [...new Set([...a, ...model.info.meta.toolIds])];
-									}
-									return a;
-								}, [])}
 								transparentBackground={$settings?.backgroundImageUrl ?? false}
 								transparentBackground={$settings?.backgroundImageUrl ?? false}
 								{stopResponse}
 								{stopResponse}
 								{createMessagePair}
 								{createMessagePair}

+ 1 - 1
src/lib/components/chat/MessageInput.svelte

@@ -51,7 +51,7 @@
 
 
 	export let prompt = '';
 	export let prompt = '';
 	export let files = [];
 	export let files = [];
-	export let availableToolIds = [];
+
 	export let selectedToolIds = [];
 	export let selectedToolIds = [];
 	export let webSearchEnabled = false;
 	export let webSearchEnabled = false;
 
 

+ 13 - 11
src/lib/components/chat/MessageInput/InputMenu.svelte

@@ -1,9 +1,10 @@
 <script lang="ts">
 <script lang="ts">
 	import { DropdownMenu } from 'bits-ui';
 	import { DropdownMenu } from 'bits-ui';
 	import { flyAndScale } from '$lib/utils/transitions';
 	import { flyAndScale } from '$lib/utils/transitions';
-	import { getContext, onMount } from 'svelte';
+	import { getContext, onMount, tick } from 'svelte';
 
 
 	import { config, user, tools as _tools } from '$lib/stores';
 	import { config, user, tools as _tools } from '$lib/stores';
+	import { getTools } from '$lib/apis/tools';
 
 
 	import Dropdown from '$lib/components/common/Dropdown.svelte';
 	import Dropdown from '$lib/components/common/Dropdown.svelte';
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
@@ -11,17 +12,13 @@
 	import Switch from '$lib/components/common/Switch.svelte';
 	import Switch from '$lib/components/common/Switch.svelte';
 	import GlobeAltSolid from '$lib/components/icons/GlobeAltSolid.svelte';
 	import GlobeAltSolid from '$lib/components/icons/GlobeAltSolid.svelte';
 	import WrenchSolid from '$lib/components/icons/WrenchSolid.svelte';
 	import WrenchSolid from '$lib/components/icons/WrenchSolid.svelte';
-	import { getTools } from '$lib/apis/tools';
 
 
 	const i18n = getContext('i18n');
 	const i18n = getContext('i18n');
 
 
 	export let uploadFilesHandler: Function;
 	export let uploadFilesHandler: Function;
-
-	export let availableToolIds: string[] = [];
 	export let selectedToolIds: string[] = [];
 	export let selectedToolIds: string[] = [];
 
 
 	export let webSearchEnabled: boolean;
 	export let webSearchEnabled: boolean;
-
 	export let onClose: Function;
 	export let onClose: Function;
 
 
 	let tools = {};
 	let tools = {};
@@ -31,12 +28,7 @@
 		init();
 		init();
 	}
 	}
 
 
-	$: if (tools) {
-		selectedToolIds = Object.keys(tools).filter((toolId) => tools[toolId]?.enabled ?? false);
-	}
-
 	const init = async () => {
 	const init = async () => {
-		console.log('init');
 		if ($_tools === null) {
 		if ($_tools === null) {
 			await _tools.set(await getTools(localStorage.token));
 			await _tools.set(await getTools(localStorage.token));
 		}
 		}
@@ -95,7 +87,17 @@
 							</div>
 							</div>
 
 
 							<div class=" flex-shrink-0">
 							<div class=" flex-shrink-0">
-								<Switch state={tools[toolId].enabled} />
+								<Switch
+									state={tools[toolId].enabled}
+									on:change={async () => {
+										await tick();
+										if (tools[toolId].enabled) {
+											selectedToolIds = [...selectedToolIds, toolId];
+										} else {
+											selectedToolIds = selectedToolIds.filter((id) => id !== toolId);
+										}
+									}}
+								/>
 							</div>
 							</div>
 						</button>
 						</button>
 					{/each}
 					{/each}

+ 1 - 2
src/lib/components/chat/Placeholder.svelte

@@ -32,7 +32,7 @@
 
 
 	export let prompt = '';
 	export let prompt = '';
 	export let files = [];
 	export let files = [];
-	export let availableToolIds = [];
+
 	export let selectedToolIds = [];
 	export let selectedToolIds = [];
 	export let webSearchEnabled = false;
 	export let webSearchEnabled = false;
 
 
@@ -200,7 +200,6 @@
 						bind:selectedToolIds
 						bind:selectedToolIds
 						bind:webSearchEnabled
 						bind:webSearchEnabled
 						bind:atSelectedModel
 						bind:atSelectedModel
-						{availableToolIds}
 						{transparentBackground}
 						{transparentBackground}
 						{stopResponse}
 						{stopResponse}
 						{createMessagePair}
 						{createMessagePair}

+ 2 - 4
src/lib/components/common/Switch.svelte

@@ -4,14 +4,12 @@
 	export let state = true;
 	export let state = true;
 
 
 	const dispatch = createEventDispatcher();
 	const dispatch = createEventDispatcher();
+
+	$: dispatch('change', state);
 </script>
 </script>
 
 
 <Switch.Root
 <Switch.Root
 	bind:checked={state}
 	bind:checked={state}
-	onCheckedChange={async (e) => {
-		await tick();
-		dispatch('change', e);
-	}}
 	class="flex h-5 min-h-5 w-9 shrink-0 cursor-pointer items-center rounded-full px-[3px] mx-[1px] transition  {state
 	class="flex h-5 min-h-5 w-9 shrink-0 cursor-pointer items-center rounded-full px-[3px] mx-[1px] transition  {state
 		? ' bg-emerald-600'
 		? ' bg-emerald-600'
 		: 'bg-gray-200 dark:bg-transparent'} outline outline-1 outline-gray-100 dark:outline-gray-800"
 		: 'bg-gray-200 dark:bg-transparent'} outline outline-1 outline-gray-100 dark:outline-gray-800"

+ 9 - 10
src/routes/(app)/workspace/prompts/create/+page.svelte

@@ -8,14 +8,11 @@
 	import PromptEditor from '$lib/components/workspace/Prompts/PromptEditor.svelte';
 	import PromptEditor from '$lib/components/workspace/Prompts/PromptEditor.svelte';
 
 
 	let prompt = null;
 	let prompt = null;
-	const onSubmit = async ({ title, command, content }) => {
-		const prompt = await createNewPrompt(localStorage.token, command, title, content).catch(
-			(error) => {
-				toast.error(error);
-
-				return null;
-			}
-		);
+	const onSubmit = async (_prompt) => {
+		const prompt = await createNewPrompt(localStorage.token, _prompt).catch((error) => {
+			toast.error(error);
+			return null;
+		});
 
 
 		if (prompt) {
 		if (prompt) {
 			await prompts.set(await getPrompts(localStorage.token));
 			await prompts.set(await getPrompts(localStorage.token));
@@ -37,7 +34,8 @@
 			prompt = {
 			prompt = {
 				title: _prompt.title,
 				title: _prompt.title,
 				command: _prompt.command,
 				command: _prompt.command,
-				content: _prompt.content
+				content: _prompt.content,
+				access_control: null
 			};
 			};
 		});
 		});
 
 
@@ -51,7 +49,8 @@
 			prompt = {
 			prompt = {
 				title: _prompt.title,
 				title: _prompt.title,
 				command: _prompt.command,
 				command: _prompt.command,
-				content: _prompt.content
+				content: _prompt.content,
+				access_control: null
 			};
 			};
 			sessionStorage.removeItem('prompt');
 			sessionStorage.removeItem('prompt');
 		}
 		}

+ 16 - 10
src/routes/(app)/workspace/prompts/edit/+page.svelte

@@ -4,19 +4,18 @@
 	import { prompts } from '$lib/stores';
 	import { prompts } from '$lib/stores';
 	import { onMount, tick, getContext } from 'svelte';
 	import { onMount, tick, getContext } from 'svelte';
 
 
-	import { getPrompts, updatePromptByCommand } from '$lib/apis/prompts';
+	import { getPromptByCommand, getPrompts, updatePromptByCommand } from '$lib/apis/prompts';
 	import { page } from '$app/stores';
 	import { page } from '$app/stores';
 
 
 	import PromptEditor from '$lib/components/workspace/Prompts/PromptEditor.svelte';
 	import PromptEditor from '$lib/components/workspace/Prompts/PromptEditor.svelte';
 
 
 	let prompt = null;
 	let prompt = null;
-	const onSubmit = async ({ title, command, content }) => {
-		const prompt = await updatePromptByCommand(localStorage.token, command, title, content).catch(
-			(error) => {
-				toast.error(error);
-				return null;
-			}
-		);
+	const onSubmit = async (_prompt) => {
+		console.log(_prompt);
+		const prompt = await updatePromptByCommand(localStorage.token, _prompt).catch((error) => {
+			toast.error(error);
+			return null;
+		});
 
 
 		if (prompt) {
 		if (prompt) {
 			await prompts.set(await getPrompts(localStorage.token));
 			await prompts.set(await getPrompts(localStorage.token));
@@ -27,13 +26,20 @@
 	onMount(async () => {
 	onMount(async () => {
 		const command = $page.url.searchParams.get('command');
 		const command = $page.url.searchParams.get('command');
 		if (command) {
 		if (command) {
-			const _prompt = $prompts.filter((prompt) => prompt.command === command).at(0);
+			const _prompt = await getPromptByCommand(
+				localStorage.token,
+				command.replace(/\//g, '')
+			).catch((error) => {
+				toast.error(error);
+				return null;
+			});
 
 
 			if (_prompt) {
 			if (_prompt) {
 				prompt = {
 				prompt = {
 					title: _prompt.title,
 					title: _prompt.title,
 					command: _prompt.command,
 					command: _prompt.command,
-					content: _prompt.content
+					content: _prompt.content,
+					access_control: _prompt?.access_control ?? null
 				};
 				};
 			} else {
 			} else {
 				goto('/workspace/prompts');
 				goto('/workspace/prompts');