forked from open-webui/open-webui
		
	refac: image generation
This commit is contained in:
		
							parent
							
								
									f1c8e7f5d1
								
							
						
					
					
						commit
						dd3a4b3889
					
				
					 2 changed files with 125 additions and 81 deletions
				
			
		|  | @ -1,9 +1,9 @@ | ||||||
| import { IMAGES_API_BASE_URL } from '$lib/constants'; | import { IMAGES_API_BASE_URL } from '$lib/constants'; | ||||||
| 
 | 
 | ||||||
| export const getImageGenerationEnabledStatus = async (token: string = '') => { | export const getImageGenerationConfig = async (token: string = '') => { | ||||||
| 	let error = null; | 	let error = null; | ||||||
| 
 | 
 | ||||||
| 	const res = await fetch(`${IMAGES_API_BASE_URL}/enabled`, { | 	const res = await fetch(`${IMAGES_API_BASE_URL}/config`, { | ||||||
| 		method: 'GET', | 		method: 'GET', | ||||||
| 		headers: { | 		headers: { | ||||||
| 			Accept: 'application/json', | 			Accept: 'application/json', | ||||||
|  | @ -32,16 +32,24 @@ export const getImageGenerationEnabledStatus = async (token: string = '') => { | ||||||
| 	return res; | 	return res; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const toggleImageGenerationEnabledStatus = async (token: string = '') => { | export const updateImageGenerationConfig = async ( | ||||||
|  | 	token: string = '', | ||||||
|  | 	engine: string, | ||||||
|  | 	enabled: boolean | ||||||
|  | ) => { | ||||||
| 	let error = null; | 	let error = null; | ||||||
| 
 | 
 | ||||||
| 	const res = await fetch(`${IMAGES_API_BASE_URL}/enabled/toggle`, { | 	const res = await fetch(`${IMAGES_API_BASE_URL}/config/update`, { | ||||||
| 		method: 'GET', | 		method: 'POST', | ||||||
| 		headers: { | 		headers: { | ||||||
| 			Accept: 'application/json', | 			Accept: 'application/json', | ||||||
| 			'Content-Type': 'application/json', | 			'Content-Type': 'application/json', | ||||||
| 			...(token && { authorization: `Bearer ${token}` }) | 			...(token && { authorization: `Bearer ${token}` }) | ||||||
| 		} | 		}, | ||||||
|  | 		body: JSON.stringify({ | ||||||
|  | 			engine, | ||||||
|  | 			enabled | ||||||
|  | 		}) | ||||||
| 	}) | 	}) | ||||||
| 		.then(async (res) => { | 		.then(async (res) => { | ||||||
| 			if (!res.ok) throw await res.json(); | 			if (!res.ok) throw await res.json(); | ||||||
|  | @ -263,7 +271,7 @@ export const updateImageSteps = async (token: string = '', steps: number) => { | ||||||
| 	return res.IMAGE_STEPS; | 	return res.IMAGE_STEPS; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const getDiffusionModels = async (token: string = '') => { | export const getImageGenerationModels = async (token: string = '') => { | ||||||
| 	let error = null; | 	let error = null; | ||||||
| 
 | 
 | ||||||
| 	const res = await fetch(`${IMAGES_API_BASE_URL}/models`, { | 	const res = await fetch(`${IMAGES_API_BASE_URL}/models`, { | ||||||
|  | @ -295,7 +303,7 @@ export const getDiffusionModels = async (token: string = '') => { | ||||||
| 	return res; | 	return res; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const getDefaultDiffusionModel = async (token: string = '') => { | export const getDefaultImageGenerationModel = async (token: string = '') => { | ||||||
| 	let error = null; | 	let error = null; | ||||||
| 
 | 
 | ||||||
| 	const res = await fetch(`${IMAGES_API_BASE_URL}/models/default`, { | 	const res = await fetch(`${IMAGES_API_BASE_URL}/models/default`, { | ||||||
|  | @ -327,7 +335,7 @@ export const getDefaultDiffusionModel = async (token: string = '') => { | ||||||
| 	return res.model; | 	return res.model; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const updateDefaultDiffusionModel = async (token: string = '', model: string) => { | export const updateDefaultImageGenerationModel = async (token: string = '', model: string) => { | ||||||
| 	let error = null; | 	let error = null; | ||||||
| 
 | 
 | ||||||
| 	const res = await fetch(`${IMAGES_API_BASE_URL}/models/default/update`, { | 	const res = await fetch(`${IMAGES_API_BASE_URL}/models/default/update`, { | ||||||
|  |  | ||||||
|  | @ -5,13 +5,13 @@ | ||||||
| 	import { config, user } from '$lib/stores'; | 	import { config, user } from '$lib/stores'; | ||||||
| 	import { | 	import { | ||||||
| 		getAUTOMATIC1111Url, | 		getAUTOMATIC1111Url, | ||||||
| 		getDefaultDiffusionModel, | 		getImageGenerationModels, | ||||||
| 		getDiffusionModels, | 		getDefaultImageGenerationModel, | ||||||
| 		getImageGenerationEnabledStatus, | 		updateDefaultImageGenerationModel, | ||||||
| 		getImageSize, | 		getImageSize, | ||||||
| 		toggleImageGenerationEnabledStatus, | 		getImageGenerationConfig, | ||||||
|  | 		updateImageGenerationConfig, | ||||||
| 		updateAUTOMATIC1111Url, | 		updateAUTOMATIC1111Url, | ||||||
| 		updateDefaultDiffusionModel, |  | ||||||
| 		updateImageSize, | 		updateImageSize, | ||||||
| 		getImageSteps, | 		getImageSteps, | ||||||
| 		updateImageSteps | 		updateImageSteps | ||||||
|  | @ -23,7 +23,9 @@ | ||||||
| 
 | 
 | ||||||
| 	let loading = false; | 	let loading = false; | ||||||
| 
 | 
 | ||||||
|  | 	let imageGenerationEngine = ''; | ||||||
| 	let enableImageGeneration = false; | 	let enableImageGeneration = false; | ||||||
|  | 
 | ||||||
| 	let AUTOMATIC1111_BASE_URL = ''; | 	let AUTOMATIC1111_BASE_URL = ''; | ||||||
| 
 | 
 | ||||||
| 	let selectedModel = ''; | 	let selectedModel = ''; | ||||||
|  | @ -33,11 +35,11 @@ | ||||||
| 	let steps = 50; | 	let steps = 50; | ||||||
| 
 | 
 | ||||||
| 	const getModels = async () => { | 	const getModels = async () => { | ||||||
| 		models = await getDiffusionModels(localStorage.token).catch((error) => { | 		models = await getImageGenerationModels(localStorage.token).catch((error) => { | ||||||
| 			toast.error(error); | 			toast.error(error); | ||||||
| 			return null; | 			return null; | ||||||
| 		}); | 		}); | ||||||
| 		selectedModel = await getDefaultDiffusionModel(localStorage.token).catch((error) => { | 		selectedModel = await getDefaultImageGenerationModel(localStorage.token).catch((error) => { | ||||||
| 			return ''; | 			return ''; | ||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
|  | @ -62,33 +64,44 @@ | ||||||
| 			AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token); | 			AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token); | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| 	const toggleImageGeneration = async () => { | 	const updateImageGeneration = async () => { | ||||||
| 		if (AUTOMATIC1111_BASE_URL) { | 		const res = await updateImageGenerationConfig( | ||||||
| 			enableImageGeneration = await toggleImageGenerationEnabledStatus(localStorage.token).catch( | 			localStorage.token, | ||||||
| 				(error) => { | 			imageGenerationEngine, | ||||||
| 					toast.error(error); | 			enableImageGeneration | ||||||
| 					return false; | 		).catch((error) => { | ||||||
| 				} | 			toast.error(error); | ||||||
| 			); | 			return null; | ||||||
|  | 		}); | ||||||
| 
 | 
 | ||||||
| 			if (enableImageGeneration) { | 		if (res) { | ||||||
| 				config.set(await getBackendConfig(localStorage.token)); | 			imageGenerationEngine = res.engine; | ||||||
| 				getModels(); | 			enableImageGeneration = res.enabled; | ||||||
| 			} | 		} | ||||||
| 		} else { | 
 | ||||||
| 			enableImageGeneration = false; | 		if (enableImageGeneration) { | ||||||
| 			toast.error('AUTOMATIC1111_BASE_URL not provided'); | 			config.set(await getBackendConfig(localStorage.token)); | ||||||
|  | 			getModels(); | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	onMount(async () => { | 	onMount(async () => { | ||||||
| 		if ($user.role === 'admin') { | 		if ($user.role === 'admin') { | ||||||
| 			enableImageGeneration = await getImageGenerationEnabledStatus(localStorage.token); | 			const res = await getImageGenerationConfig(localStorage.token).catch((error) => { | ||||||
|  | 				toast.error(error); | ||||||
|  | 				return null; | ||||||
|  | 			}); | ||||||
|  | 
 | ||||||
|  | 			if (res) { | ||||||
|  | 				imageGenerationEngine = res.engine; | ||||||
|  | 				enableImageGeneration = res.enabled; | ||||||
|  | 			} | ||||||
| 			AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token); | 			AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token); | ||||||
| 
 | 
 | ||||||
| 			if (enableImageGeneration && AUTOMATIC1111_BASE_URL) { | 			imageSize = await getImageSize(localStorage.token); | ||||||
| 				imageSize = await getImageSize(localStorage.token); | 			steps = await getImageSteps(localStorage.token); | ||||||
| 				steps = await getImageSteps(localStorage.token); | 
 | ||||||
|  | 			if (enableImageGeneration) { | ||||||
| 				getModels(); | 				getModels(); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -99,7 +112,7 @@ | ||||||
| 	class="flex flex-col h-full justify-between space-y-3 text-sm" | 	class="flex flex-col h-full justify-between space-y-3 text-sm" | ||||||
| 	on:submit|preventDefault={async () => { | 	on:submit|preventDefault={async () => { | ||||||
| 		loading = true; | 		loading = true; | ||||||
| 		await updateDefaultDiffusionModel(localStorage.token, selectedModel); | 		await updateDefaultImageGenerationModel(localStorage.token, selectedModel); | ||||||
| 		await updateImageSize(localStorage.token, imageSize).catch((error) => { | 		await updateImageSize(localStorage.token, imageSize).catch((error) => { | ||||||
| 			toast.error(error); | 			toast.error(error); | ||||||
| 			return null; | 			return null; | ||||||
|  | @ -117,6 +130,23 @@ | ||||||
| 		<div> | 		<div> | ||||||
| 			<div class=" mb-1 text-sm font-medium">Image Settings</div> | 			<div class=" mb-1 text-sm font-medium">Image Settings</div> | ||||||
| 
 | 
 | ||||||
|  | 			<div class=" py-0.5 flex w-full justify-between"> | ||||||
|  | 				<div class=" self-center text-xs font-medium">Image Generation Engine</div> | ||||||
|  | 				<div class="flex items-center relative"> | ||||||
|  | 					<select | ||||||
|  | 						class="w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right" | ||||||
|  | 						bind:value={imageGenerationEngine} | ||||||
|  | 						placeholder="Select a mode" | ||||||
|  | 						on:change={async () => { | ||||||
|  | 							await updateImageGeneration(); | ||||||
|  | 						}} | ||||||
|  | 					> | ||||||
|  | 						<option value="">Default (Automatic1111)</option> | ||||||
|  | 						<option value="openai">Open AI (Dall-E)</option> | ||||||
|  | 					</select> | ||||||
|  | 				</div> | ||||||
|  | 			</div> | ||||||
|  | 
 | ||||||
| 			<div> | 			<div> | ||||||
| 				<div class=" py-0.5 flex w-full justify-between"> | 				<div class=" py-0.5 flex w-full justify-between"> | ||||||
| 					<div class=" self-center text-xs font-medium">Image Generation (Experimental)</div> | 					<div class=" self-center text-xs font-medium">Image Generation (Experimental)</div> | ||||||
|  | @ -124,7 +154,12 @@ | ||||||
| 					<button | 					<button | ||||||
| 						class="p-1 px-3 text-xs flex rounded transition" | 						class="p-1 px-3 text-xs flex rounded transition" | ||||||
| 						on:click={() => { | 						on:click={() => { | ||||||
| 							toggleImageGeneration(); | 							if (imageGenerationEngine === '' && AUTOMATIC1111_BASE_URL === '') { | ||||||
|  | 								toast.error('AUTOMATIC1111 Base URL is required.'); | ||||||
|  | 							} else { | ||||||
|  | 								enableImageGeneration = !enableImageGeneration; | ||||||
|  | 								updateImageGeneration(); | ||||||
|  | 							} | ||||||
| 						}} | 						}} | ||||||
| 						type="button" | 						type="button" | ||||||
| 					> | 					> | ||||||
|  | @ -137,51 +172,54 @@ | ||||||
| 				</div> | 				</div> | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 		<hr class=" dark:border-gray-700" /> |  | ||||||
| 
 | 
 | ||||||
| 		<div class=" mb-2.5 text-sm font-medium">AUTOMATIC1111 Base URL</div> | 		{#if imageGenerationEngine === ''} | ||||||
| 		<div class="flex w-full"> | 			<hr class=" dark:border-gray-700" /> | ||||||
| 			<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://127.0.0.1:7860/)" |  | ||||||
| 					bind:value={AUTOMATIC1111_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" |  | ||||||
| 				type="button" |  | ||||||
| 				on:click={() => { |  | ||||||
| 					// updateOllamaAPIUrlHandler(); |  | ||||||
| 
 | 
 | ||||||
| 					updateAUTOMATIC1111UrlHandler(); | 			<div class=" mb-2.5 text-sm font-medium">AUTOMATIC1111 Base URL</div> | ||||||
| 				}} | 			<div class="flex w-full"> | ||||||
| 			> | 				<div class="flex-1 mr-2"> | ||||||
| 				<svg | 					<input | ||||||
| 					xmlns="http://www.w3.org/2000/svg" | 						class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none" | ||||||
| 					viewBox="0 0 20 20" | 						placeholder="Enter URL (e.g. http://127.0.0.1:7860/)" | ||||||
| 					fill="currentColor" | 						bind:value={AUTOMATIC1111_BASE_URL} | ||||||
| 					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> | 				</div> | ||||||
| 			</button> | 				<button | ||||||
| 		</div> | 					class="px-3 bg-gray-200 hover:bg-gray-300 dark:bg-gray-600 dark:hover:bg-gray-700 rounded transition" | ||||||
|  | 					type="button" | ||||||
|  | 					on:click={() => { | ||||||
|  | 						// updateOllamaAPIUrlHandler(); | ||||||
| 
 | 
 | ||||||
| 		<div class="mt-2 text-xs text-gray-400 dark:text-gray-500"> | 						updateAUTOMATIC1111UrlHandler(); | ||||||
| 			Include `--api` flag when running stable-diffusion-webui | 					}} | ||||||
| 			<a | 				> | ||||||
| 				class=" text-gray-300 font-medium" | 					<svg | ||||||
| 				href="https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/3734" | 						xmlns="http://www.w3.org/2000/svg" | ||||||
| 				target="_blank" | 						viewBox="0 0 20 20" | ||||||
| 			> | 						fill="currentColor" | ||||||
| 				(e.g. `sh webui.sh --api`) | 						class="w-4 h-4" | ||||||
| 			</a> | 					> | ||||||
| 		</div> | 						<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="mt-2 text-xs text-gray-400 dark:text-gray-500"> | ||||||
|  | 				Include `--api` flag when running stable-diffusion-webui | ||||||
|  | 				<a | ||||||
|  | 					class=" text-gray-300 font-medium" | ||||||
|  | 					href="https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/3734" | ||||||
|  | 					target="_blank" | ||||||
|  | 				> | ||||||
|  | 					(e.g. `sh webui.sh --api`) | ||||||
|  | 				</a> | ||||||
|  | 			</div> | ||||||
|  | 		{/if} | ||||||
| 
 | 
 | ||||||
| 		{#if enableImageGeneration} | 		{#if enableImageGeneration} | ||||||
| 			<hr class=" dark:border-gray-700" /> | 			<hr class=" dark:border-gray-700" /> | ||||||
|  | @ -199,9 +237,7 @@ | ||||||
| 								<option value="" disabled selected>Select a model</option> | 								<option value="" disabled selected>Select a model</option> | ||||||
| 							{/if} | 							{/if} | ||||||
| 							{#each models ?? [] as model} | 							{#each models ?? [] as model} | ||||||
| 								<option value={model.title} class="bg-gray-100 dark:bg-gray-700" | 								<option value={model.id} class="bg-gray-100 dark:bg-gray-700">{model.name}</option> | ||||||
| 									>{model.model_name}</option |  | ||||||
| 								> |  | ||||||
| 							{/each} | 							{/each} | ||||||
| 						</select> | 						</select> | ||||||
| 					</div> | 					</div> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek