Compare commits

..

20 Commits

Author SHA1 Message Date
psychedelicious
9353298b4f chore: bump version to v5.6.2 2025-02-14 13:13:33 +11:00
Eugene Brodsky
cf22e09b28 chore(ui): upgrade vite, vitest, and related plugins to latest versions 2025-02-14 11:09:51 +11:00
Linos
6e5ca7ece8 translationBot(ui): update translation (Vietnamese)
Currently translated at 99.8% (1753 of 1755 strings)

translationBot(ui): update translation (Vietnamese)

Currently translated at 99.8% (1751 of 1753 strings)

Co-authored-by: Linos <linos.coding@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/vi/
Translation: InvokeAI/Web UI
2025-02-13 19:26:55 +11:00
Thomas Bolteau
b81209e751 translationBot(ui): update translation (French)
Currently translated at 91.7% (1609 of 1753 strings)

Co-authored-by: Thomas Bolteau <thomas.bolteau50@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/fr/
Translation: InvokeAI/Web UI
2025-02-13 19:26:55 +11:00
Riccardo Giovanetti
c4040eb2f0 translationBot(ui): update translation (Italian)
Currently translated at 98.9% (1735 of 1753 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.9% (1731 of 1749 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.9% (1731 of 1749 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.6% (1726 of 1749 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2025-02-13 19:26:55 +11:00
Billy Lisner
046ea611f9 Remove files 2025-02-13 19:24:01 +11:00
Billy Lisner
1439da5e88 Make ruff gods happy 2025-02-13 19:24:01 +11:00
Billy Lisner
69a504710f More detailed error messages 2025-02-13 19:24:01 +11:00
Billy Lisner
842b770938 Update OpenAI Schema 2025-02-13 19:24:01 +11:00
Billy Lisner
ba39331594 Make ruff happy 2025-02-13 19:24:01 +11:00
Billy Lisner
8ee9509eec Add Metadata Field Extractor 2025-02-13 19:24:01 +11:00
psychedelicious
7b5dcffb3f fix(ui): prevent overflow on document root 2025-02-13 09:10:38 +11:00
Mary Hipp
6927e95444 update defaults 2025-02-12 15:49:15 -05:00
Mary Hipp
76618fee9c feat(ui): separate upscaling settings so that tab does not inherit from main generation settings 2025-02-12 15:49:15 -05:00
Maxim Evtush
b51312f1ba Update model_images_common.py 2025-02-11 20:03:11 +11:00
Maxim Evtush
c2b71854be Update useGalleryNavigation.ts 2025-02-11 20:03:11 +11:00
Maxim Evtush
df793c898f Update denoise_latents.py 2025-02-11 20:03:11 +11:00
Maxim Evtush
d6181e4d64 Update useImageViewer.ts 2025-02-11 20:03:11 +11:00
Maxim Evtush
0a4ea9ac6f Update validateWorkflow.ts 2025-02-11 20:03:11 +11:00
dunkeroni
9e6f3e9338 image channel multiply node loads as RGBA now 2025-02-11 18:32:56 +11:00
20 changed files with 1292 additions and 412 deletions

View File

@@ -898,7 +898,7 @@ class DenoiseLatentsInvocation(BaseInvocation):
### inpaint
mask, masked_latents, is_gradient_mask = self.prep_inpaint_mask(context, latents)
# NOTE: We used to identify inpainting models by inpecting the shape of the loaded UNet model weights. Now we
# NOTE: We used to identify inpainting models by inspecting the shape of the loaded UNet model weights. Now we
# use the ModelVariantType config. During testing, there was a report of a user with models that had an
# incorrect ModelVariantType value. Re-installing the model fixed the issue. If this issue turns out to be
# prevalent, we will have to revisit how we initialize the inpainting extensions.

View File

@@ -918,7 +918,7 @@ class ImageChannelMultiplyInvocation(BaseInvocation, WithMetadata, WithBoard):
invert_channel: bool = InputField(default=False, description="Invert the channel after scaling")
def invoke(self, context: InvocationContext) -> ImageOutput:
image = context.images.get_pil(self.image.image_name)
image = context.images.get_pil(self.image.image_name, "RGBA")
# extract the channel and mode from the input and reference tuple
mode = CHANNEL_FORMATS[self.channel][0]

View File

@@ -18,6 +18,7 @@ from invokeai.app.invocations.fields import (
UIType,
)
from invokeai.app.invocations.model import ModelIdentifierField
from invokeai.app.invocations.primitives import StringOutput
from invokeai.app.services.shared.invocation_context import InvocationContext
from invokeai.app.util.controlnet_utils import CONTROLNET_MODE_VALUES, CONTROLNET_RESIZE_VALUES
from invokeai.version.invokeai_version import __version__
@@ -275,3 +276,33 @@ class CoreMetadataInvocation(BaseInvocation):
return MetadataOutput(metadata=MetadataField.model_validate(as_dict))
model_config = ConfigDict(extra="allow")
@invocation(
"metadata_field_extractor",
title="Metadata Field Extractor",
tags=["metadata"],
category="metadata",
version="1.0.0",
)
class MetadataFieldExtractorInvocation(BaseInvocation):
"""Extracts the text value from an image's metadata given a key.
Raises an error if the image has no metadata or if the value is not a string (nesting not permitted)."""
image: ImageField = InputField(description="The image to extract metadata from")
key: str = InputField(description="The key in the image's metadata to extract the value from")
def invoke(self, context: InvocationContext) -> StringOutput:
image_name = self.image.image_name
metadata = context.images.get_metadata(image_name=image_name)
if not metadata:
raise ValueError(f"No metadata found on image {image_name}")
try:
val = metadata.root[self.key]
if not isinstance(val, str):
raise ValueError(f"Metadata at key '{self.key}' must be a string")
return StringOutput(value=val)
except KeyError as e:
raise ValueError(f"No key '{self.key}' found in the metadata for {image_name}") from e

View File

@@ -1,4 +1,4 @@
# TODO: Should these excpetions subclass existing python exceptions?
# TODO: Should these exceptions subclass existing python exceptions?
class ModelImageFileNotFoundException(Exception):
"""Raised when an image file is not found in storage."""

View File

@@ -11,9 +11,11 @@
<link id="invoke-favicon" rel="icon" type="icon" href="assets/images/invoke-favicon.svg" />
<style>
html,
body {
body,
#root {
padding: 0;
margin: 0;
overflow: hidden;
}
</style>
</head>
@@ -23,4 +25,4 @@
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
</html>

View File

@@ -126,7 +126,7 @@
"@storybook/addon-storysource": "^8.3.4",
"@storybook/manager-api": "^8.3.4",
"@storybook/react": "^8.3.4",
"@storybook/react-vite": "^8.3.4",
"@storybook/react-vite": "^8.5.5",
"@storybook/theming": "^8.3.4",
"@types/dateformat": "^5.0.2",
"@types/lodash-es": "^4.17.12",
@@ -134,9 +134,9 @@
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@types/uuid": "^10.0.0",
"@vitejs/plugin-react-swc": "^3.7.1",
"@vitest/coverage-v8": "^1.6.0",
"@vitest/ui": "^1.6.0",
"@vitejs/plugin-react-swc": "^3.8.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.5",
"concurrently": "^8.2.2",
"csstype": "^3.1.3",
"dpdm": "^3.14.0",
@@ -152,11 +152,11 @@
"tsafe": "^1.7.5",
"type-fest": "^4.26.1",
"typescript": "^5.6.2",
"vite": "^5.4.8",
"vite": "^6.1.0",
"vite-plugin-css-injected-by-js": "^3.5.2",
"vite-plugin-dts": "^3.9.1",
"vite-plugin-dts": "^4.5.0",
"vite-plugin-eslint": "^1.8.1",
"vite-tsconfig-paths": "^4.3.2",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^1.6.0"
},
"engines": {

File diff suppressed because it is too large Load Diff

View File

@@ -301,7 +301,9 @@
"hfTokenHelperText": "Un token HF est requis pour utiliser certains modèles. Cliquez ici pour créer ou obtenir votre token.",
"hfTokenInvalid": "Token HF invalide ou manquant",
"hfForbidden": "Vous n'avez pas accès à ce modèle HF.",
"hfTokenInvalidErrorMessage2": "Mettre à jour dans le "
"hfTokenInvalidErrorMessage2": "Mettre à jour dans le ",
"controlLora": "Controle LoRA",
"urlUnauthorizedErrorMessage2": "Découvrir comment ici."
},
"parameters": {
"images": "Images",
@@ -332,7 +334,7 @@
"showOptionsPanel": "Afficher le panneau latéral (O ou T)",
"invoke": {
"noPrompts": "Aucun prompts généré",
"missingInputForField": "{{nodeLabel}} -> {{fieldLabel}} entrée manquante",
"missingInputForField": "entrée manquante",
"missingFieldTemplate": "Modèle de champ manquant",
"invoke": "Invoke",
"addingImagesTo": "Ajouter des images à",
@@ -353,7 +355,9 @@
"canvasIsCompositing": "La toile est en train de composer",
"collectionTooFewItems": "{{nodeLabel}} -> {{fieldLabel}} : trop peu d'éléments, minimum {{minItems}}",
"collectionTooManyItems": "{{nodeLabel}} -> {{fieldLabel}} : trop d'éléments, maximum {{maxItems}}",
"canvasIsSelectingObject": "La toile est occupée (sélection d'objet)"
"canvasIsSelectingObject": "La toile est occupée (sélection d'objet)",
"emptyBatches": "lots vides",
"batchNodeNotConnected": "Noeud de lots non connecté : {{label}}"
},
"negativePromptPlaceholder": "Prompt Négatif",
"positivePromptPlaceholder": "Prompt Positif",
@@ -1630,7 +1634,26 @@
"boardAccessError": "Impossible de trouver la planche {{board_id}}, réinitialisation à la valeur par défaut",
"workflowHelpText": "Besoin d'aide? Consultez notre guide sur <LinkComponent>Comment commencer avec les Workflows</LinkComponent>.",
"noWorkflows": "Aucun Workflows",
"noMatchingWorkflows": "Aucun Workflows correspondant"
"noMatchingWorkflows": "Aucun Workflows correspondant",
"arithmeticSequence": "Séquence Arithmétique",
"uniformRandomDistribution": "Distribution Aléatoire Uniforme",
"noBatchGroup": "aucun groupe",
"generatorLoading": "chargement",
"generatorLoadFromFile": "Charger depuis un Fichier",
"dynamicPromptsRandom": "Prompts Dynamiques (Aléatoire)",
"integerRangeGenerator": "Générateur d'interval d'entiers",
"generateValues": "Générer Valeurs",
"linearDistribution": "Distribution Linéaire",
"floatRangeGenerator": "Générateur d'interval de nombres décimaux",
"generatorNRandomValues_one": "{{count}} valeur aléatoire",
"generatorNRandomValues_many": "{{count}} valeurs aléatoires",
"generatorNRandomValues_other": "{{count}} valeurs aléatoires",
"dynamicPromptsCombinatorial": "Prompts Dynamiques (Combinatoire)",
"parseString": "Analyser la chaine de charactères",
"internalDesc": "Cette invocation est utilisée internalement par Invoke. En fonction des mises à jours il est possible que des changements y soit effectués ou qu'elle soit supprimé sans prévention.",
"splitOn": "Diviser sur",
"generatorNoValues": "vide",
"addItem": "Ajouter un élément"
},
"models": {
"noMatchingModels": "Aucun modèle correspondant",

View File

@@ -172,7 +172,8 @@
"imagesTab": "Immagini create e salvate in Invoke.",
"assetsTab": "File che hai caricato per usarli nei tuoi progetti.",
"boardsSettings": "Impostazioni Bacheche",
"imagesSettings": "Impostazioni Immagini Galleria"
"imagesSettings": "Impostazioni Immagini Galleria",
"assets": "Risorse"
},
"hotkeys": {
"searchHotkeys": "Cerca tasti di scelta rapida",
@@ -832,7 +833,12 @@
"uploadFailedInvalidUploadDesc_withCount_one": "Devi caricare al massimo 1 immagine PNG o JPEG.",
"uploadFailedInvalidUploadDesc_withCount_many": "Devi caricare al massimo {{count}} immagini PNG o JPEG.",
"uploadFailedInvalidUploadDesc_withCount_other": "Devi caricare al massimo {{count}} immagini PNG o JPEG.",
"outOfMemoryErrorDescLocal": "Segui la nostra <LinkComponent>guida per bassa VRAM</LinkComponent> per ridurre gli OOM."
"outOfMemoryErrorDescLocal": "Segui la nostra <LinkComponent>guida per bassa VRAM</LinkComponent> per ridurre gli OOM.",
"pasteFailed": "Incolla non riuscita",
"pasteSuccess": "Incollato su {{destination}}",
"unableToCopy": "Impossibile copiare",
"unableToCopyDesc": "Il tuo browser non supporta l'accesso agli appunti. Gli utenti di Firefox potrebbero risolvere il problema seguendo ",
"unableToCopyDesc_theseSteps": "questi passaggi"
},
"accessibility": {
"invokeProgressBar": "Barra di avanzamento generazione",
@@ -2092,7 +2098,10 @@
"saveCanvasToGallery": "Salva la Tela nella Galleria",
"saveToGalleryGroup": "Salva nella Galleria",
"newInpaintMask": "Nuova maschera Inpaint",
"newRegionalGuidance": "Nuova Guida Regionale"
"newRegionalGuidance": "Nuova Guida Regionale",
"copyToClipboard": "Copia negli appunti",
"copyCanvasToClipboard": "Copia la tela negli appunti",
"copyBboxToClipboard": "Copia il riquadro di delimitazione negli appunti"
},
"newImg2ImgCanvasFromImage": "Nuova Immagine da immagine",
"copyRasterLayerTo": "Copia $t(controlLayers.rasterLayer) in",
@@ -2155,7 +2164,17 @@
"ipAdapterIncompatibleBaseModel": "modello base dell'immagine di riferimento incompatibile",
"ipAdapterNoImageSelected": "nessuna immagine di riferimento selezionata",
"rgAutoNegativeNotSupported": "Auto-Negativo non supportato per il modello base selezionato"
}
},
"pasteTo": "Incolla su",
"pasteToBboxDesc": "Nuovo livello (nel riquadro di delimitazione)",
"pasteToAssets": "Risorse",
"copyRegionError": "Errore durante la copia di {{region}}",
"pasteToAssetsDesc": "Incolla in Risorse",
"pasteToBbox": "Riquadro di delimitazione",
"pasteToCanvas": "Tela",
"pasteToCanvasDesc": "Nuovo livello (nella Tela)",
"pastedTo": "Incollato su {{destination}}",
"regionCopiedToClipboard": "{{region}} Copiato negli appunti"
},
"ui": {
"tabs": {
@@ -2254,11 +2273,12 @@
"watchRecentReleaseVideos": "Guarda i video su questa versione",
"watchUiUpdatesOverview": "Guarda le novità dell'interfaccia",
"items": [
"Modalità Bassa-VRAM",
"Gestione dinamica della memoria",
"Tempi di caricamento del modello più rapidi",
"Meno errori di memoria",
"Funzionalità lotto del flusso di lavoro ampliate"
"Impostazioni predefinite VRAM migliorate",
"Cancellazione della cache del modello su richiesta",
"Compatibilità estesa FLUX LoRA",
"Filtro Regola Immagine su Tela",
"Annulla tutto tranne l'elemento della coda corrente",
"Copia da e incolla sulla Tela"
]
},
"system": {

View File

@@ -117,7 +117,8 @@
"unstarImage": "Ngừng Gắn Sao Cho Ảnh",
"compareHelp2": "Nhấn <Kbd>M</Kbd> để tuần hoàn trong chế độ so sánh.",
"boardsSettings": "Thiết Lập Bảng",
"imagesSettings": "Cài Đặt Thư Viện Ảnh"
"imagesSettings": "Cài Đặt Thư Viện Ảnh",
"assets": "Tài Nguyên"
},
"common": {
"ipAdapter": "IP Adapter",
@@ -303,7 +304,11 @@
"completedIn": "Hoàn tất trong",
"graphQueued": "Đồ Thị Đã Vào Hàng",
"batchQueuedDesc_other": "Thêm {{count}} phiên vào {{direction}} của hàng",
"batchSize": "Kích Thước Lô"
"batchSize": "Kích Thước Lô",
"cancelAllExceptCurrentQueueItemAlertDialog": "Huỷ tất cả mục đang xếp hàng ngoại trừ mục hiện tại, sẽ dừng các mục đang chờ nhưng cho phép các mục đang chạy được hoàn tất.",
"cancelAllExceptCurrentQueueItemAlertDialog2": "Bạn có chắc muốn huỷ tất cả mục đang chờ?",
"cancelAllExceptCurrentTooltip": "Huỷ Bỏ Tất Cả Ngoại Trừ Mục Hiện Tại",
"confirm": "Đồng Ý"
},
"hotkeys": {
"canvas": {
@@ -1797,7 +1802,10 @@
"newControlLayer": "Layer Điều Khiển Được Mới",
"newRasterLayer": "Layer Dạng Raster Mới",
"bboxGroup": "Được Tạo Từ Hộp Giới Hạn",
"canvasGroup": "Canvas"
"canvasGroup": "Canvas",
"copyCanvasToClipboard": "Sao Chép Canvas Vào Clipboard",
"copyToClipboard": "Sao Chép Vào Clipboard",
"copyBboxToClipboard": "Sao Chép Hộp Giới Hạn Vào Clipboard"
},
"stagingArea": {
"saveToGallery": "Lưu Vào Thư Viện",
@@ -1914,6 +1922,30 @@
"gaussian_type": "Gaussian",
"noise_color": "Màu Nhiễu",
"size": "Cỡ Nhiễu"
},
"adjust_image": {
"channel": "Kênh Màu",
"cyan": "Lục Lam (Cmyk)",
"value_setting": "Giá Trị",
"scale_values": "Giá Trị Theo Tỉ Lệ",
"red": "Đỏ (Rgba)",
"green": "Lục (rGba)",
"blue": "Lam (rgBa)",
"alpha": "Độ Trong Suốt (rgbA)",
"luminosity": "Độ Sáng (Lab)",
"magenta": "Hồng Đỏ (cMyk)",
"yellow": "Vàng (cmYk)",
"description": "Điều chỉnh kênh màu được chọn của ảnh.",
"black": "Đen (cmyK)",
"cr": "Cr (ycC)",
"label": "Điều Chỉnh Ảnh",
"value": "Độ Sáng (hsV)",
"saturation": "Độ Bão Hoà (hSv)",
"hue": "Vùng Màu (Hsv)",
"a": "A (lAb)",
"b": "B (laB)",
"y": "Y (Ycc)",
"cb": "Cb (yCc)"
}
},
"transform": {
@@ -1992,6 +2024,20 @@
"rgReferenceImagesNotSupported": "Ảnh Mẫu Khu Vực không được hỗ trợ cho model cơ sở được chọn",
"rgAutoNegativeNotSupported": "Tự Động Đảo Chiều không được hỗ trợ cho model cơ sở được chọn",
"rgNoRegion": "không có khu vực được vẽ"
},
"pasteTo": "Dán Vào",
"pasteToAssets": "Tài Nguyên",
"pasteToAssetsDesc": "Dán Vào Tài Nguyên",
"pasteToBbox": "Hộp Giới Hạn",
"pasteToBboxDesc": "Layer Mới (Trong Hộp Giới Hạn)",
"pasteToCanvas": "Canvas",
"pasteToCanvasDesc": "Layer Mới (Trong Canvas)",
"pastedTo": "Dán Vào {{destination}}",
"regionCopiedToClipboard": "Sao Chép {{region}} Vào Clipboard",
"copyRegionError": "Lỗi khi sao chép {{region}}",
"errors": {
"unableToLoadImage": "Không Thể Tải Hình Ảnh",
"unableToFindImage": "Không Thể Tìm Hình Ảnh"
}
},
"stylePresets": {
@@ -2123,7 +2169,12 @@
"problemDownloadingImage": "Không Thể Tải Xuống Ảnh",
"problemCopyingLayer": "Không Thể Sao Chép Layer",
"problemSavingLayer": "Không Thể Lưu Layer",
"outOfMemoryErrorDescLocal": "Làm theo <LinkComponent>hướng dẫn VRAM Thấp</LinkComponent> của chúng tôi để hạn chế OOM (Tràn bộ nhớ)."
"outOfMemoryErrorDescLocal": "Làm theo <LinkComponent>hướng dẫn VRAM Thấp</LinkComponent> của chúng tôi để hạn chế OOM (Tràn bộ nhớ).",
"unableToCopy": "Không Thể Sao Chép",
"unableToCopyDesc_theseSteps": "các bước sau",
"unableToCopyDesc": "Trình duyệt của bạn không hỗ trợ tính năng clipboard. Người dùng Firefox có thể khắc phục theo ",
"pasteSuccess": "Dán Vào {{destination}}",
"pasteFailed": "Dán Thất Bại"
},
"ui": {
"tabs": {
@@ -2218,11 +2269,12 @@
"watchRecentReleaseVideos": "Xem Video Phát Hành Mới Nhất",
"watchUiUpdatesOverview": "Xem Tổng Quan Về Những Cập Nhật Cho Giao Diện Người Dùng",
"items": [
"Chế độ VRAM thấp",
"Trình quản lý bộ nhớ động",
"Tải model nhanh hơn",
"Ít lỗi bộ nhớ hơn",
"Mở rộng khả năng xử lý hàng loạt workflow"
"Cải thiện các thiết lập mặc định của VRAM",
"Xoá bộ nhớ đệm của model theo yêu cầu",
"Mở rộng khả năng tương thích LoRA trên FLUX",
"Bộ lọc điều chỉnh ảnh trên Canvas",
"Huỷ tất cả trừ mục đang xếp hàng hiện tại",
"Sao chép và dán trên Canvas"
]
},
"upsell": {

View File

@@ -49,6 +49,8 @@ export type ParamsState = {
optimizedDenoisingEnabled: boolean;
iterations: number;
scheduler: ParameterScheduler;
upscaleScheduler: ParameterScheduler;
upscaleCfgScale: ParameterCFGScale;
seed: ParameterSeed;
shouldRandomizeSeed: boolean;
steps: ParameterSteps;
@@ -96,6 +98,8 @@ const initialState: ParamsState = {
optimizedDenoisingEnabled: true,
iterations: 1,
scheduler: 'dpmpp_3m_k',
upscaleScheduler: 'kdpm_2',
upscaleCfgScale: 2,
seed: 0,
shouldRandomizeSeed: true,
steps: 30,
@@ -139,6 +143,9 @@ export const paramsSlice = createSlice({
setCfgScale: (state, action: PayloadAction<ParameterCFGScale>) => {
state.cfgScale = action.payload;
},
setUpscaleCfgScale: (state, action: PayloadAction<ParameterCFGScale>) => {
state.upscaleCfgScale = action.payload;
},
setGuidance: (state, action: PayloadAction<ParameterGuidance>) => {
state.guidance = action.payload;
},
@@ -148,6 +155,10 @@ export const paramsSlice = createSlice({
setScheduler: (state, action: PayloadAction<ParameterScheduler>) => {
state.scheduler = action.payload;
},
setUpscaleScheduler: (state, action: PayloadAction<ParameterScheduler>) => {
state.upscaleScheduler = action.payload;
},
setSeed: (state, action: PayloadAction<number>) => {
state.seed = action.payload;
state.shouldRandomizeSeed = false;
@@ -315,6 +326,8 @@ export const {
setCfgRescaleMultiplier,
setGuidance,
setScheduler,
setUpscaleScheduler,
setUpscaleCfgScale,
setSeed,
setImg2imgStrength,
setOptimizedDenoisingEnabled,
@@ -409,6 +422,9 @@ export const selectVAEPrecision = createParamsSelector((params) => params.vaePre
export const selectIterations = createParamsSelector((params) => params.iterations);
export const selectShouldUseCPUNoise = createParamsSelector((params) => params.shouldUseCpuNoise);
export const selectUpscaleScheduler = createParamsSelector((params) => params.upscaleScheduler);
export const selectUpscaleCfgScale = createParamsSelector((params) => params.upscaleCfgScale);
export const selectRefinerCFGScale = createParamsSelector((params) => params.refinerCFGScale);
export const selectRefinerModel = createParamsSelector((params) => params.refinerModel);
export const selectIsRefinerModelSelected = createParamsSelector((params) => Boolean(params.refinerModel));

View File

@@ -21,7 +21,7 @@ import type { ImageDTO } from 'services/api/types';
*
* We can hack around this, thanks to the fact that the image viewer is always opened on the first app startup. By the
* time the user closes it, the resizable panels library has already done its one extra resize and the DOM layout has
* stablized. So we can track the first time the image viewer is closed and fit the layers to the stage at that time,
* stabilized. So we can track the first time the image viewer is closed and fit the layers to the stage at that time,
* ensuring that the bbox is centered in the canvas stage on that first app startup.
*
* TODO(psyche): Figure out a better way to do handle this...

View File

@@ -152,7 +152,7 @@ type UseGalleryNavigationReturn = {
/**
* Provides access to the gallery navigation via arrow keys.
* Also provides information about the current image's position in the gallery,
* useful for determining whether to load more images or display navigatin
* useful for determining whether to load more images or display navigation
* buttons.
*/
export const useGalleryNavigation = (): UseGalleryNavigationReturn => {

View File

@@ -13,7 +13,15 @@ import { getBoardField, getPresetModifiedPrompts } from './graphBuilderUtils';
export const buildMultidiffusionUpscaleGraph = async (
state: RootState
): Promise<{ g: Graph; noise: Invocation<'noise'>; posCond: Invocation<'compel' | 'sdxl_compel_prompt'> }> => {
const { model, cfgScale: cfg_scale, scheduler, steps, vaePrecision, seed, vae } = state.params;
const {
model,
upscaleCfgScale: cfg_scale,
upscaleScheduler: scheduler,
steps,
vaePrecision,
seed,
vae,
} = state.params;
const { upscaleModel, upscaleInitialImage, structure, creativity, tileControlnetModel, scale } = state.upscale;
assert(model, 'No model found in state');

View File

@@ -46,7 +46,7 @@ const MODEL_FIELD_TYPES = [
* - Validates the workflow against the node templates, warning if the template is not known.
* - Attempts to update nodes which have a mismatched version.
* - Removes edges which are invalid.
* @param workflow The raw workflow object (e.g. JSON.parse(stringifiedWorklow))
* @param workflow The raw workflow object (e.g. JSON.parse(stringifiedWorkflow))
* @param templates The node templates to validate against.
* @throws {WorkflowVersionError} If the workflow version is not recognized.
* @throws {z.ZodError} If there is a validation error.

View File

@@ -0,0 +1,48 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
import { selectUpscaleCfgScale, setUpscaleCfgScale } from 'features/controlLayers/store/paramsSlice';
import { selectCFGScaleConfig } from 'features/system/store/configSlice';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const ParamUpscaleCFGScale = () => {
const cfgScale = useAppSelector(selectUpscaleCfgScale);
const config = useAppSelector(selectCFGScaleConfig);
const dispatch = useAppDispatch();
const { t } = useTranslation();
const marks = useMemo(
() => [config.sliderMin, Math.floor(config.sliderMax / 2), config.sliderMax],
[config.sliderMax, config.sliderMin]
);
const onChange = useCallback((v: number) => dispatch(setUpscaleCfgScale(v)), [dispatch]);
return (
<FormControl>
<InformationalPopover feature="paramCFGScale">
<FormLabel>{t('parameters.cfgScale')}</FormLabel>
</InformationalPopover>
<CompositeSlider
value={cfgScale}
defaultValue={config.initial}
min={config.sliderMin}
max={config.sliderMax}
step={config.coarseStep}
fineStep={config.fineStep}
onChange={onChange}
marks={marks}
/>
<CompositeNumberInput
value={cfgScale}
defaultValue={config.initial}
min={config.numberInputMin}
max={config.numberInputMax}
step={config.coarseStep}
fineStep={config.fineStep}
onChange={onChange}
/>
</FormControl>
);
};
export default memo(ParamUpscaleCFGScale);

View File

@@ -0,0 +1,38 @@
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
import { selectUpscaleScheduler, setUpscaleScheduler } from 'features/controlLayers/store/paramsSlice';
import { SCHEDULER_OPTIONS } from 'features/parameters/types/constants';
import { isParameterScheduler } from 'features/parameters/types/parameterSchemas';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const ParamUpscaleScheduler = () => {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const scheduler = useAppSelector(selectUpscaleScheduler);
const onChange = useCallback<ComboboxOnChange>(
(v) => {
if (!isParameterScheduler(v?.value)) {
return;
}
dispatch(setUpscaleScheduler(v.value));
},
[dispatch]
);
const value = useMemo(() => SCHEDULER_OPTIONS.find((o) => o.value === scheduler), [scheduler]);
return (
<FormControl>
<InformationalPopover feature="paramScheduler">
<FormLabel>{t('parameters.scheduler')}</FormLabel>
</InformationalPopover>
<Combobox value={value} options={SCHEDULER_OPTIONS} onChange={onChange} />
</FormControl>
);
};
export default memo(ParamUpscaleScheduler);

View File

@@ -14,6 +14,8 @@ import ParamSteps from 'features/parameters/components/Core/ParamSteps';
import { NavigateToModelManagerButton } from 'features/parameters/components/MainModel/NavigateToModelManagerButton';
import ParamMainModelSelect from 'features/parameters/components/MainModel/ParamMainModelSelect';
import { UseDefaultSettingsButton } from 'features/parameters/components/MainModel/UseDefaultSettingsButton';
import ParamUpscaleCFGScale from 'features/parameters/components/Upscale/ParamUpscaleCFGScale';
import ParamUpscaleScheduler from 'features/parameters/components/Upscale/ParamUpscaleScheduler';
import { useExpanderToggle } from 'features/settingsAccordions/hooks/useExpanderToggle';
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
import { selectActiveTab } from 'features/ui/store/uiSelectors';
@@ -31,6 +33,9 @@ export const GenerationSettingsAccordion = memo(() => {
const activeTabName = useAppSelector(selectActiveTab);
const isFLUX = useAppSelector(selectIsFLUX);
const isSD3 = useAppSelector(selectIsSD3);
const isUpscaling = useMemo(() => {
return activeTabName === 'upscaling';
}, [activeTabName]);
const selectBadges = useMemo(
() =>
createMemoizedSelector(selectLoRAsSlice, (loras) => {
@@ -75,9 +80,12 @@ export const GenerationSettingsAccordion = memo(() => {
<Expander label={t('accordions.advanced.options')} isOpen={isOpenExpander} onToggle={onToggleExpander}>
<Flex gap={4} flexDir="column" pb={4}>
<FormControlGroup formLabelProps={formLabelProps}>
{!isFLUX && !isSD3 && <ParamScheduler />}
{!isFLUX && !isSD3 && !isUpscaling && <ParamScheduler />}
{isUpscaling && <ParamUpscaleScheduler />}
<ParamSteps />
{isFLUX ? <ParamGuidance /> : <ParamCFGScale />}
{isFLUX && <ParamGuidance />}
{isUpscaling && <ParamUpscaleCFGScale />}
{!isFLUX && !isUpscaling && <ParamCFGScale />}
</FormControlGroup>
</Flex>
</Expander>

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
__version__ = "5.6.1"
__version__ = "5.6.2"