refac: image generation

This commit is contained in:
Timothy J. Baek 2024-03-08 16:22:19 -08:00
parent f1c8e7f5d1
commit dd3a4b3889
2 changed files with 125 additions and 81 deletions

View file

@ -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`, {

View file

@ -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>