mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
feat: Add Replicate image generation integration with 14+ models, hybrid loading, and robust error handling
This commit is contained in:
parent
661625f362
commit
761746f1cb
@ -2966,3 +2966,13 @@ LDAP_VALIDATE_CERT = PersistentConfig(
|
|||||||
LDAP_CIPHERS = PersistentConfig(
|
LDAP_CIPHERS = PersistentConfig(
|
||||||
"LDAP_CIPHERS", "ldap.server.ciphers", os.environ.get("LDAP_CIPHERS", "ALL")
|
"LDAP_CIPHERS", "ldap.server.ciphers", os.environ.get("LDAP_CIPHERS", "ALL")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
####################################
|
||||||
|
# REPLICATE
|
||||||
|
####################################
|
||||||
|
|
||||||
|
REPLICATE_API_TOKEN = PersistentConfig(
|
||||||
|
"REPLICATE_API_TOKEN",
|
||||||
|
"image_generation.replicate.api_token",
|
||||||
|
os.getenv("REPLICATE_API_TOKEN", ""),
|
||||||
|
)
|
||||||
|
|||||||
@ -338,6 +338,8 @@ from open_webui.config import (
|
|||||||
LDAP_CA_CERT_FILE,
|
LDAP_CA_CERT_FILE,
|
||||||
LDAP_VALIDATE_CERT,
|
LDAP_VALIDATE_CERT,
|
||||||
LDAP_CIPHERS,
|
LDAP_CIPHERS,
|
||||||
|
# Replicate
|
||||||
|
REPLICATE_API_TOKEN,
|
||||||
# Misc
|
# Misc
|
||||||
ENV,
|
ENV,
|
||||||
CACHE_DIR,
|
CACHE_DIR,
|
||||||
@ -639,6 +641,7 @@ app.state.config.LDAP_CA_CERT_FILE = LDAP_CA_CERT_FILE
|
|||||||
app.state.config.LDAP_VALIDATE_CERT = LDAP_VALIDATE_CERT
|
app.state.config.LDAP_VALIDATE_CERT = LDAP_VALIDATE_CERT
|
||||||
app.state.config.LDAP_CIPHERS = LDAP_CIPHERS
|
app.state.config.LDAP_CIPHERS = LDAP_CIPHERS
|
||||||
|
|
||||||
|
app.state.config.REPLICATE_API_TOKEN = REPLICATE_API_TOKEN
|
||||||
|
|
||||||
app.state.AUTH_TRUSTED_EMAIL_HEADER = WEBUI_AUTH_TRUSTED_EMAIL_HEADER
|
app.state.AUTH_TRUSTED_EMAIL_HEADER = WEBUI_AUTH_TRUSTED_EMAIL_HEADER
|
||||||
app.state.AUTH_TRUSTED_NAME_HEADER = WEBUI_AUTH_TRUSTED_NAME_HEADER
|
app.state.AUTH_TRUSTED_NAME_HEADER = WEBUI_AUTH_TRUSTED_NAME_HEADER
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -134,6 +134,7 @@ dependencies = [
|
|||||||
|
|
||||||
"moto[s3]>=5.0.26",
|
"moto[s3]>=5.0.26",
|
||||||
|
|
||||||
|
"replicate",
|
||||||
]
|
]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">= 3.11, < 3.13.0a1"
|
requires-python = ">= 3.11, < 3.13.0a1"
|
||||||
|
|||||||
@ -121,7 +121,7 @@
|
|||||||
|
|
||||||
if (config.enabled) {
|
if (config.enabled) {
|
||||||
backendConfig.set(await getBackendConfig());
|
backendConfig.set(await getBackendConfig());
|
||||||
getModels();
|
await getModels();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -184,10 +184,21 @@
|
|||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
config = res;
|
config = res;
|
||||||
|
if (!config.replicate) {
|
||||||
|
config.replicate = {
|
||||||
|
REPLICATE_API_TOKEN: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageGenerationConfig = await getImageGenerationConfig(localStorage.token).catch((error) => {
|
||||||
|
toast.error(`${error}`);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load models first, then they'll be available when the UI renders
|
||||||
if (config.enabled) {
|
if (config.enabled) {
|
||||||
getModels();
|
await getModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.comfyui.COMFYUI_WORKFLOW) {
|
if (config.comfyui.COMFYUI_WORKFLOW) {
|
||||||
@ -213,15 +224,6 @@
|
|||||||
node_ids: typeof n.node_ids === 'string' ? n.node_ids : n.node_ids.join(',')
|
node_ids: typeof n.node_ids === 'string' ? n.node_ids : n.node_ids.join(',')
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const imageConfigRes = await getImageGenerationConfig(localStorage.token).catch((error) => {
|
|
||||||
toast.error(`${error}`);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (imageConfigRes) {
|
|
||||||
imageGenerationConfig = imageConfigRes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -291,17 +293,21 @@
|
|||||||
<div class=" self-center text-xs font-medium">{$i18n.t('Image Generation Engine')}</div>
|
<div class=" self-center text-xs font-medium">{$i18n.t('Image Generation Engine')}</div>
|
||||||
<div class="flex items-center relative">
|
<div class="flex items-center relative">
|
||||||
<select
|
<select
|
||||||
class=" dark:bg-gray-900 w-fit pr-8 cursor-pointer rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right"
|
class=" w-full bg-transparent text-sm transition-all !border-none !outline-none"
|
||||||
bind:value={config.engine}
|
bind:value={config.engine}
|
||||||
placeholder={$i18n.t('Select Engine')}
|
|
||||||
on:change={async () => {
|
on:change={async () => {
|
||||||
updateConfigHandler();
|
await updateConfigHandler();
|
||||||
|
// Fetch models when switching to any engine
|
||||||
|
if (config.enabled) {
|
||||||
|
await getModels();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value="openai">{$i18n.t('Default (Open AI)')}</option>
|
<option value="openai">OpenAI</option>
|
||||||
<option value="comfyui">{$i18n.t('ComfyUI')}</option>
|
<option value="automatic1111">AUTOMATIC1111</option>
|
||||||
<option value="automatic1111">{$i18n.t('Automatic1111')}</option>
|
<option value="comfyui">ComfyUI</option>
|
||||||
<option value="gemini">{$i18n.t('Gemini')}</option>
|
<option value="gemini">Gemini</option>
|
||||||
|
<option value="replicate">Replicate</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -631,6 +637,30 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{:else if config.engine === 'replicate'}
|
||||||
|
<div class="mb-2.5">
|
||||||
|
<div class=" mb-2 font-medium">{$i18n.t('Replicate Settings')}</div>
|
||||||
|
<div class="flex w-full flex-col space-y-2">
|
||||||
|
<div class="flex w-full flex-col lg:flex-row items-start lg:items-center">
|
||||||
|
<div class="lg:w-4/12 w-full text-sm font-medium">
|
||||||
|
{$i18n.t('Replicate API Token')}
|
||||||
|
</div>
|
||||||
|
<div class="flex-1">
|
||||||
|
<SensitiveInput
|
||||||
|
placeholder="r8_..."
|
||||||
|
bind:value={config.replicate.REPLICATE_API_TOKEN}
|
||||||
|
on:change={async () => {
|
||||||
|
await updateConfigHandler();
|
||||||
|
// Refresh models after API token change
|
||||||
|
if (config.enabled && config.replicate.REPLICATE_API_TOKEN) {
|
||||||
|
await getModels();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -643,20 +673,17 @@
|
|||||||
<div class="flex-1 mr-2">
|
<div class="flex-1 mr-2">
|
||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<Tooltip content={$i18n.t('Enter Model ID')} placement="top-start">
|
<Tooltip content={$i18n.t('Select Model')} placement="top-start">
|
||||||
<input
|
<select
|
||||||
list="model-list"
|
|
||||||
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
|
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={imageGenerationConfig.MODEL}
|
bind:value={imageGenerationConfig.MODEL}
|
||||||
placeholder="Select a model"
|
|
||||||
required
|
required
|
||||||
/>
|
>
|
||||||
|
<option value="" disabled>Select a model</option>
|
||||||
<datalist id="model-list">
|
|
||||||
{#each models ?? [] as model}
|
{#each models ?? [] as model}
|
||||||
<option value={model.id}>{model.name}</option>
|
<option value={model.id}>{model.name || model.id}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</datalist>
|
</select>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
export let onDismiss = () => {};
|
export let onDismiss = () => {};
|
||||||
|
|
||||||
let _src = '';
|
let _src = '';
|
||||||
$: _src = src.startsWith('/') ? `${WEBUI_BASE_URL}${src}` : src;
|
$: _src = src && src.startsWith('/') ? `${WEBUI_BASE_URL}${src}` : src;
|
||||||
|
|
||||||
let showImagePreview = false;
|
let showImagePreview = false;
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user