API/DB updates per PR feedback

This commit is contained in:
Mary Hipp 2024-08-09 16:27:37 -04:00
parent 12ba15bfa9
commit 97553a7de2
13 changed files with 220 additions and 204 deletions

View File

@ -31,7 +31,7 @@ from invokeai.app.services.session_processor.session_processor_default import (
) )
from invokeai.app.services.session_queue.session_queue_sqlite import SqliteSessionQueue from invokeai.app.services.session_queue.session_queue_sqlite import SqliteSessionQueue
from invokeai.app.services.shared.sqlite.sqlite_util import init_db from invokeai.app.services.shared.sqlite.sqlite_util import init_db
from invokeai.app.services.style_preset_images.style_preset_images_default import StylePresetImageFileStorageDisk from invokeai.app.services.style_preset_images.style_preset_images_disk import StylePresetImageFileStorageDisk
from invokeai.app.services.style_preset_records.style_preset_records_sqlite import SqliteStylePresetRecordsStorage from invokeai.app.services.style_preset_records.style_preset_records_sqlite import SqliteStylePresetRecordsStorage
from invokeai.app.services.urls.urls_default import LocalUrlService from invokeai.app.services.urls.urls_default import LocalUrlService
from invokeai.app.services.workflow_records.workflow_records_sqlite import SqliteWorkflowRecordsStorage from invokeai.app.services.workflow_records.workflow_records_sqlite import SqliteWorkflowRecordsStorage
@ -113,9 +113,7 @@ class ApiDependencies:
urls = LocalUrlService() urls = LocalUrlService()
workflow_records = SqliteWorkflowRecordsStorage(db=db) workflow_records = SqliteWorkflowRecordsStorage(db=db)
style_preset_records = SqliteStylePresetRecordsStorage(db=db) style_preset_records = SqliteStylePresetRecordsStorage(db=db)
style_preset_images_service = StylePresetImageFileStorageDisk( style_preset_image_files = StylePresetImageFileStorageDisk(style_preset_images_folder / "style_preset_images")
style_preset_images_folder / "style_preset_images"
)
services = InvocationServices( services = InvocationServices(
board_image_records=board_image_records, board_image_records=board_image_records,
@ -142,7 +140,7 @@ class ApiDependencies:
tensors=tensors, tensors=tensors,
conditioning=conditioning, conditioning=conditioning,
style_preset_records=style_preset_records, style_preset_records=style_preset_records,
style_preset_images_service=style_preset_images_service, style_preset_image_files=style_preset_image_files,
) )
ApiDependencies.invoker = Invoker(services) ApiDependencies.invoker = Invoker(services)

View File

@ -32,7 +32,7 @@ async def get_style_preset(
) -> StylePresetRecordWithImage: ) -> StylePresetRecordWithImage:
"""Gets a style preset""" """Gets a style preset"""
try: try:
image = ApiDependencies.invoker.services.style_preset_images_service.get_url(style_preset_id) image = ApiDependencies.invoker.services.style_preset_image_files.get_url(style_preset_id)
style_preset = ApiDependencies.invoker.services.style_preset_records.get(style_preset_id) style_preset = ApiDependencies.invoker.services.style_preset_records.get(style_preset_id)
return StylePresetRecordWithImage(image=image, **style_preset.model_dump()) return StylePresetRecordWithImage(image=image, **style_preset.model_dump())
except StylePresetNotFoundError: except StylePresetNotFoundError:
@ -67,20 +67,22 @@ async def update_style_preset(
raise HTTPException(status_code=415, detail="Failed to read image") raise HTTPException(status_code=415, detail="Failed to read image")
try: try:
ApiDependencies.invoker.services.style_preset_images_service.save(pil_image, style_preset_id) ApiDependencies.invoker.services.style_preset_image_files.save(style_preset_id, pil_image)
except ValueError as e: except ValueError as e:
raise HTTPException(status_code=409, detail=str(e)) raise HTTPException(status_code=409, detail=str(e))
else: else:
try: try:
ApiDependencies.invoker.services.style_preset_images_service.delete(style_preset_id) ApiDependencies.invoker.services.style_preset_image_files.delete(style_preset_id)
except StylePresetImageFileNotFoundException: except StylePresetImageFileNotFoundException:
pass pass
preset_data = PresetData(positive_prompt=positive_prompt, negative_prompt=negative_prompt) preset_data = PresetData(positive_prompt=positive_prompt, negative_prompt=negative_prompt)
changes = StylePresetChanges(name=name, preset_data=preset_data) changes = StylePresetChanges(name=name, preset_data=preset_data)
style_preset_image = ApiDependencies.invoker.services.style_preset_images_service.get_url(style_preset_id) style_preset_image = ApiDependencies.invoker.services.style_preset_image_files.get_url(style_preset_id)
style_preset = ApiDependencies.invoker.services.style_preset_records.update(id=style_preset_id, changes=changes) style_preset = ApiDependencies.invoker.services.style_preset_records.update(
style_preset_id=style_preset_id, changes=changes
)
return StylePresetRecordWithImage(image=style_preset_image, **style_preset.model_dump()) return StylePresetRecordWithImage(image=style_preset_image, **style_preset.model_dump())
@ -93,7 +95,7 @@ async def delete_style_preset(
) -> None: ) -> None:
"""Deletes a style preset""" """Deletes a style preset"""
try: try:
ApiDependencies.invoker.services.style_preset_images_service.delete(style_preset_id) ApiDependencies.invoker.services.style_preset_image_files.delete(style_preset_id)
except StylePresetImageFileNotFoundException: except StylePresetImageFileNotFoundException:
pass pass
@ -131,11 +133,11 @@ async def create_style_preset(
raise HTTPException(status_code=415, detail="Failed to read image") raise HTTPException(status_code=415, detail="Failed to read image")
try: try:
ApiDependencies.invoker.services.style_preset_images_service.save(pil_image, new_style_preset.id) ApiDependencies.invoker.services.style_preset_image_files.save(new_style_preset.id, pil_image)
except ValueError as e: except ValueError as e:
raise HTTPException(status_code=409, detail=str(e)) raise HTTPException(status_code=409, detail=str(e))
preset_image = ApiDependencies.invoker.services.style_preset_images_service.get_url(new_style_preset.id) preset_image = ApiDependencies.invoker.services.style_preset_image_files.get_url(new_style_preset.id)
return StylePresetRecordWithImage(image=preset_image, **new_style_preset.model_dump()) return StylePresetRecordWithImage(image=preset_image, **new_style_preset.model_dump())
@ -151,7 +153,7 @@ async def list_style_presets() -> list[StylePresetRecordWithImage]:
style_presets_with_image: list[StylePresetRecordWithImage] = [] style_presets_with_image: list[StylePresetRecordWithImage] = []
style_presets = ApiDependencies.invoker.services.style_preset_records.get_many() style_presets = ApiDependencies.invoker.services.style_preset_records.get_many()
for preset in style_presets: for preset in style_presets:
image = ApiDependencies.invoker.services.style_preset_images_service.get_url(preset.id) image = ApiDependencies.invoker.services.style_preset_image_files.get_url(preset.id)
style_preset_with_image = StylePresetRecordWithImage(image=image, **preset.model_dump()) style_preset_with_image = StylePresetRecordWithImage(image=image, **preset.model_dump())
style_presets_with_image.append(style_preset_with_image) style_presets_with_image.append(style_preset_with_image)
@ -176,7 +178,7 @@ async def get_style_preset_image(
"""Gets an image file that previews the model""" """Gets an image file that previews the model"""
try: try:
path = ApiDependencies.invoker.services.style_preset_images_service.get_path(style_preset_id) path = ApiDependencies.invoker.services.style_preset_image_files.get_path(style_preset_id)
response = FileResponse( response = FileResponse(
path, path,

View File

@ -64,7 +64,7 @@ class InvocationServices:
tensors: "ObjectSerializerBase[torch.Tensor]", tensors: "ObjectSerializerBase[torch.Tensor]",
conditioning: "ObjectSerializerBase[ConditioningFieldData]", conditioning: "ObjectSerializerBase[ConditioningFieldData]",
style_preset_records: "StylePresetRecordsStorageBase", style_preset_records: "StylePresetRecordsStorageBase",
style_preset_images_service: "StylePresetImageFileStorageBase", style_preset_image_files: "StylePresetImageFileStorageBase",
): ):
self.board_images = board_images self.board_images = board_images
self.board_image_records = board_image_records self.board_image_records = board_image_records
@ -90,4 +90,4 @@ class InvocationServices:
self.tensors = tensors self.tensors = tensors
self.conditioning = conditioning self.conditioning = conditioning
self.style_preset_records = style_preset_records self.style_preset_records = style_preset_records
self.style_preset_images_service = style_preset_images_service self.style_preset_image_files = style_preset_image_files

View File

@ -8,14 +8,14 @@ class Migration14Callback:
self._create_style_presets(cursor) self._create_style_presets(cursor)
def _create_style_presets(self, cursor: sqlite3.Cursor) -> None: def _create_style_presets(self, cursor: sqlite3.Cursor) -> None:
"""Create the table used to store model metadata downloaded from remote sources.""" """Create the table used to store style presets."""
tables = [ tables = [
"""--sql """--sql
CREATE TABLE IF NOT EXISTS style_presets ( CREATE TABLE IF NOT EXISTS style_presets (
id TEXT NOT NULL PRIMARY KEY, id TEXT NOT NULL PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL,
preset_data TEXT NOT NULL, preset_data TEXT NOT NULL,
is_default BOOLEAN DEFAULT FALSE, type TEXT NOT NULL DEFAULT "user",
created_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), created_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')),
-- Updated via trigger -- Updated via trigger
updated_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) updated_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW'))
@ -47,10 +47,10 @@ class Migration14Callback:
def build_migration_14() -> Migration: def build_migration_14() -> Migration:
""" """
Build the migration from database version 12 to 14.. Build the migration from database version 13 to 14..
This migration does the following: This migration does the following:
- Adds `archived` columns to the board table. - Create the table used to store style presets.
""" """
migration_14 = Migration( migration_14 = Migration(
from_version=13, from_version=13,

View File

@ -23,7 +23,7 @@ class StylePresetImageFileStorageBase(ABC):
pass pass
@abstractmethod @abstractmethod
def save(self, image: PILImageType, style_preset_id: str) -> None: def save(self, style_preset_id: str, image: PILImageType) -> None:
"""Saves a style preset image.""" """Saves a style preset image."""
pass pass

View File

@ -1,19 +1,19 @@
class StylePresetImageFileNotFoundException(Exception): class StylePresetImageFileNotFoundException(Exception):
"""Raised when an image file is not found in storage.""" """Raised when an image file is not found in storage."""
def __init__(self, message="Style preset image file not found"): def __init__(self, message: str = "Style preset image file not found"):
super().__init__(message) super().__init__(message)
class StylePresetImageFileSaveException(Exception): class StylePresetImageFileSaveException(Exception):
"""Raised when an image cannot be saved.""" """Raised when an image cannot be saved."""
def __init__(self, message="Style preset image file not saved"): def __init__(self, message: str = "Style preset image file not saved"):
super().__init__(message) super().__init__(message)
class StylePresetImageFileDeleteException(Exception): class StylePresetImageFileDeleteException(Exception):
"""Raised when an image cannot be deleted.""" """Raised when an image cannot be deleted."""
def __init__(self, message="Style preset image file not deleted"): def __init__(self, message: str = "Style preset image file not deleted"):
super().__init__(message) super().__init__(message)

View File

@ -28,14 +28,11 @@ class StylePresetImageFileStorageDisk(StylePresetImageFileStorageBase):
try: try:
path = self.get_path(style_preset_id) path = self.get_path(style_preset_id)
if not self._validate_path(path):
raise StylePresetImageFileNotFoundException
return Image.open(path) return Image.open(path)
except FileNotFoundError as e: except FileNotFoundError as e:
raise StylePresetImageFileNotFoundException from e raise StylePresetImageFileNotFoundException from e
def save(self, image: PILImageType, style_preset_id: str) -> None: def save(self, style_preset_id: str, image: PILImageType) -> None:
try: try:
self._validate_storage_folders() self._validate_storage_folders()
image_path = self._style_preset_images_folder / (style_preset_id + ".webp") image_path = self._style_preset_images_folder / (style_preset_id + ".webp")

View File

@ -11,7 +11,7 @@ class StylePresetRecordsStorageBase(ABC):
"""Base class for style preset storage services.""" """Base class for style preset storage services."""
@abstractmethod @abstractmethod
def get(self, id: str) -> StylePresetRecordDTO: def get(self, style_preset_id: str) -> StylePresetRecordDTO:
"""Get style preset by id.""" """Get style preset by id."""
pass pass
@ -21,12 +21,12 @@ class StylePresetRecordsStorageBase(ABC):
pass pass
@abstractmethod @abstractmethod
def update(self, id: str, changes: StylePresetChanges) -> StylePresetRecordDTO: def update(self, style_preset_id: str, changes: StylePresetChanges) -> StylePresetRecordDTO:
"""Updates a style preset.""" """Updates a style preset."""
pass pass
@abstractmethod @abstractmethod
def delete(self, id: str) -> None: def delete(self, style_preset_id: str) -> None:
"""Deletes a style preset.""" """Deletes a style preset."""
pass pass

View File

@ -1,7 +1,10 @@
from enum import Enum
from typing import Any, Optional from typing import Any, Optional
from pydantic import BaseModel, Field, TypeAdapter from pydantic import BaseModel, Field, TypeAdapter
from invokeai.app.util.metaenum import MetaEnum
class StylePresetNotFoundError(Exception): class StylePresetNotFoundError(Exception):
"""Raised when a style preset is not found""" """Raised when a style preset is not found"""
@ -15,6 +18,12 @@ class PresetData(BaseModel, extra="forbid"):
PresetDataValidator = TypeAdapter(PresetData) PresetDataValidator = TypeAdapter(PresetData)
class PresetType(str, Enum, metaclass=MetaEnum):
User = "user"
Default = "default"
Project = "project"
class StylePresetChanges(BaseModel, extra="forbid"): class StylePresetChanges(BaseModel, extra="forbid"):
name: Optional[str] = Field(default=None, description="The style preset's new name.") name: Optional[str] = Field(default=None, description="The style preset's new name.")
preset_data: Optional[PresetData] = Field(default=None, description="The updated data for style preset.") preset_data: Optional[PresetData] = Field(default=None, description="The updated data for style preset.")
@ -23,7 +32,7 @@ class StylePresetChanges(BaseModel, extra="forbid"):
class StylePresetWithoutId(BaseModel): class StylePresetWithoutId(BaseModel):
name: str = Field(description="The name of the style preset.") name: str = Field(description="The name of the style preset.")
preset_data: PresetData = Field(description="The preset data") preset_data: PresetData = Field(description="The preset data")
is_default: Optional[bool] = Field(description="Whether or not the style preset is default", default=False) type: PresetType = Field(description="The type of style preset", default=PresetType.User)
class StylePresetRecordDTO(StylePresetWithoutId): class StylePresetRecordDTO(StylePresetWithoutId):

View File

@ -5,6 +5,7 @@ from invokeai.app.services.invoker import Invoker
from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase
from invokeai.app.services.style_preset_records.style_preset_records_base import StylePresetRecordsStorageBase from invokeai.app.services.style_preset_records.style_preset_records_base import StylePresetRecordsStorageBase
from invokeai.app.services.style_preset_records.style_preset_records_common import ( from invokeai.app.services.style_preset_records.style_preset_records_common import (
PresetType,
StylePresetChanges, StylePresetChanges,
StylePresetNotFoundError, StylePresetNotFoundError,
StylePresetRecordDTO, StylePresetRecordDTO,
@ -24,7 +25,7 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
self._invoker = invoker self._invoker = invoker
self._sync_default_style_presets() self._sync_default_style_presets()
def get(self, id: str) -> StylePresetRecordDTO: def get(self, style_preset_id: str) -> StylePresetRecordDTO:
"""Gets a style preset by ID.""" """Gets a style preset by ID."""
try: try:
self._lock.acquire() self._lock.acquire()
@ -34,11 +35,11 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
FROM style_presets FROM style_presets
WHERE id = ?; WHERE id = ?;
""", """,
(id,), (style_preset_id,),
) )
row = self._cursor.fetchone() row = self._cursor.fetchone()
if row is None: if row is None:
raise StylePresetNotFoundError(f"Style preset with id {id} not found") raise StylePresetNotFoundError(f"Style preset with id {style_preset_id} not found")
return StylePresetRecordDTO.from_dict(dict(row)) return StylePresetRecordDTO.from_dict(dict(row))
except Exception: except Exception:
self._conn.rollback() self._conn.rollback()
@ -47,7 +48,7 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
self._lock.release() self._lock.release()
def create(self, style_preset: StylePresetWithoutId) -> StylePresetRecordDTO: def create(self, style_preset: StylePresetWithoutId) -> StylePresetRecordDTO:
id = uuid_string() style_preset_id = uuid_string()
try: try:
self._lock.acquire() self._lock.acquire()
self._cursor.execute( self._cursor.execute(
@ -56,11 +57,16 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
id, id,
name, name,
preset_data, preset_data,
is_default type
) )
VALUES (?, ?, ?, ?); VALUES (?, ?, ?, ?);
""", """,
(id, style_preset.name, style_preset.preset_data.model_dump_json(), style_preset.is_default), (
style_preset_id,
style_preset.name,
style_preset.preset_data.model_dump_json(),
style_preset.type,
),
) )
self._conn.commit() self._conn.commit()
except Exception: except Exception:
@ -68,9 +74,9 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
raise raise
finally: finally:
self._lock.release() self._lock.release()
return self.get(id) return self.get(style_preset_id)
def update(self, id: str, changes: StylePresetChanges) -> StylePresetRecordDTO: def update(self, style_preset_id: str, changes: StylePresetChanges) -> StylePresetRecordDTO:
try: try:
self._lock.acquire() self._lock.acquire()
# Change the name of a style preset # Change the name of a style preset
@ -81,7 +87,7 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
SET name = ? SET name = ?
WHERE id = ?; WHERE id = ?;
""", """,
(changes.name, id), (changes.name, style_preset_id),
) )
# Change the preset data for a style preset # Change the preset data for a style preset
@ -92,7 +98,7 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
SET preset_data = ? SET preset_data = ?
WHERE id = ?; WHERE id = ?;
""", """,
(changes.preset_data.model_dump_json(), id), (changes.preset_data.model_dump_json(), style_preset_id),
) )
self._conn.commit() self._conn.commit()
@ -101,9 +107,9 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
raise raise
finally: finally:
self._lock.release() self._lock.release()
return self.get(id) return self.get(style_preset_id)
def delete(self, id: str) -> None: def delete(self, style_preset_id: str) -> None:
try: try:
self._lock.acquire() self._lock.acquire()
self._cursor.execute( self._cursor.execute(
@ -111,7 +117,7 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
DELETE from style_presets DELETE from style_presets
WHERE id = ?; WHERE id = ?;
""", """,
(id,), (style_preset_id,),
) )
self._conn.commit() self._conn.commit()
except Exception: except Exception:
@ -147,26 +153,25 @@ class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase):
def _sync_default_style_presets(self) -> None: def _sync_default_style_presets(self) -> None:
"""Syncs default style presets to the database. Internal use only.""" """Syncs default style presets to the database. Internal use only."""
# First delete all existing default style presets
try: try:
self._lock.acquire() self._lock.acquire()
self._cursor.execute( self._cursor.execute(
"""--sql """--sql
DELETE FROM style_presets DELETE FROM style_presets
WHERE is_default = True; WHERE type = "default";
""" """
) )
try:
with open(Path(__file__).parent / Path("default_style_presets.json"), "r") as file:
presets: list[StylePresetWithoutId] = json.load(file)
for preset in presets:
style_preset = StylePresetWithoutId(is_default=True, **preset)
self.create(style_preset)
except Exception:
raise Exception()
self._conn.commit() self._conn.commit()
except Exception: except Exception:
self._conn.rollback() self._conn.rollback()
raise raise
finally: finally:
self._lock.release() self._lock.release()
# Next, parse and create the default style presets
with self._lock, open(Path(__file__).parent / Path("default_style_presets.json"), "r") as file:
presets = json.load(file)
for preset in presets:
style_preset = StylePresetWithoutId.model_validate(preset)
style_preset.type = PresetType.Default
self.create(style_preset)

View File

@ -32,8 +32,8 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI
dispatch( dispatch(
prefilledFormDataChanged({ prefilledFormDataChanged({
name, name,
positivePrompt: positive_prompt, positivePrompt: positive_prompt || '',
negativePrompt: negative_prompt, negativePrompt: negative_prompt || '',
imageUrl: preset.image, imageUrl: preset.image,
}) })
); );
@ -105,7 +105,7 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI
)} )}
</Flex> </Flex>
{!preset.is_default && ( {preset.type !== 'default' && (
<Flex alignItems="center" gap={1}> <Flex alignItems="center" gap={1}>
<IconButton <IconButton
size="sm" size="sm"

View File

@ -24,7 +24,7 @@ export const StylePresetMenu = () => {
const groupedData = filteredData.reduce( const groupedData = filteredData.reduce(
(acc: { defaultPresets: StylePresetRecordWithImage[]; presets: StylePresetRecordWithImage[] }, preset) => { (acc: { defaultPresets: StylePresetRecordWithImage[]; presets: StylePresetRecordWithImage[] }, preset) => {
if (preset.is_default) { if (preset.type === 'default') {
acc.defaultPresets.push(preset); acc.defaultPresets.push(preset);
} else { } else {
acc.presets.push(preset); acc.presets.push(preset);

View File

@ -7561,151 +7561,151 @@ export type components = {
project_id: string | null; project_id: string | null;
}; };
InvocationOutputMap: { InvocationOutputMap: {
float_to_int: components["schemas"]["IntegerOutput"];
collect: components["schemas"]["CollectInvocationOutput"];
create_denoise_mask: components["schemas"]["DenoiseMaskOutput"];
mul: components["schemas"]["IntegerOutput"];
compel: components["schemas"]["ConditioningOutput"];
segment_anything_processor: components["schemas"]["ImageOutput"];
blank_image: components["schemas"]["ImageOutput"];
cv_inpaint: components["schemas"]["ImageOutput"];
sdxl_model_loader: components["schemas"]["SDXLModelLoaderOutput"];
grounding_dino: components["schemas"]["BoundingBoxCollectionOutput"];
range: components["schemas"]["IntegerCollectionOutput"];
boolean_collection: components["schemas"]["BooleanCollectionOutput"];
color: components["schemas"]["ColorOutput"];
vae_loader: components["schemas"]["VAEOutput"];
lblend: components["schemas"]["LatentsOutput"];
mlsd_image_processor: components["schemas"]["ImageOutput"];
pair_tile_image: components["schemas"]["PairTileImageOutput"];
calculate_image_tiles_min_overlap: components["schemas"]["CalculateImageTilesOutput"];
save_image: components["schemas"]["ImageOutput"];
integer: components["schemas"]["IntegerOutput"];
scheduler: components["schemas"]["SchedulerOutput"];
metadata: components["schemas"]["MetadataOutput"];
midas_depth_image_processor: components["schemas"]["ImageOutput"];
prompt_from_file: components["schemas"]["StringCollectionOutput"];
add: components["schemas"]["IntegerOutput"];
sdxl_lora_loader: components["schemas"]["SDXLLoRALoaderOutput"];
img_chan: components["schemas"]["ImageOutput"];
img_lerp: components["schemas"]["ImageOutput"];
sdxl_refiner_compel_prompt: components["schemas"]["ConditioningOutput"];
freeu: components["schemas"]["UNetOutput"];
tiled_multi_diffusion_denoise_latents: components["schemas"]["LatentsOutput"];
div: components["schemas"]["IntegerOutput"];
float_math: components["schemas"]["FloatOutput"];
random_range: components["schemas"]["IntegerCollectionOutput"];
normalbae_image_processor: components["schemas"]["ImageOutput"];
lresize: components["schemas"]["LatentsOutput"];
t2i_adapter: components["schemas"]["T2IAdapterOutput"];
bounding_box: components["schemas"]["BoundingBoxOutput"];
lineart_anime_image_processor: components["schemas"]["ImageOutput"];
string_replace: components["schemas"]["StringOutput"];
spandrel_image_to_image_autoscale: components["schemas"]["ImageOutput"];
image: components["schemas"]["ImageOutput"];
dynamic_prompt: components["schemas"]["StringCollectionOutput"];
seamless: components["schemas"]["SeamlessModeOutput"];
lscale: components["schemas"]["LatentsOutput"];
tensor_mask_to_image: components["schemas"]["ImageOutput"];
merge_tiles_to_image: components["schemas"]["ImageOutput"];
latents: components["schemas"]["LatentsOutput"];
create_gradient_mask: components["schemas"]["GradientMaskOutput"];
lora_selector: components["schemas"]["LoRASelectorOutput"];
lora_collection_loader: components["schemas"]["LoRALoaderOutput"];
integer_collection: components["schemas"]["IntegerCollectionOutput"];
round_float: components["schemas"]["FloatOutput"];
mediapipe_face_processor: components["schemas"]["ImageOutput"];
dw_openpose_image_processor: components["schemas"]["ImageOutput"];
lineart_image_processor: components["schemas"]["ImageOutput"];
infill_lama: components["schemas"]["ImageOutput"];
rand_float: components["schemas"]["FloatOutput"];
rand_int: components["schemas"]["IntegerOutput"];
mask_combine: components["schemas"]["ImageOutput"];
calculate_image_tiles: components["schemas"]["CalculateImageTilesOutput"];
img_blur: components["schemas"]["ImageOutput"];
float: components["schemas"]["FloatOutput"];
tile_to_properties: components["schemas"]["TileToPropertiesOutput"]; tile_to_properties: components["schemas"]["TileToPropertiesOutput"];
img_scale: components["schemas"]["ImageOutput"]; color: components["schemas"]["ColorOutput"];
img_channel_offset: components["schemas"]["ImageOutput"];
crop_latents: components["schemas"]["LatentsOutput"];
face_off: components["schemas"]["FaceOffOutput"];
denoise_latents: components["schemas"]["LatentsOutput"];
controlnet: components["schemas"]["ControlOutput"];
img_mul: components["schemas"]["ImageOutput"];
float_collection: components["schemas"]["FloatCollectionOutput"];
zoe_depth_image_processor: components["schemas"]["ImageOutput"];
pidi_image_processor: components["schemas"]["ImageOutput"];
spandrel_image_to_image: components["schemas"]["ImageOutput"];
i2l: components["schemas"]["LatentsOutput"];
integer_math: components["schemas"]["IntegerOutput"];
depth_anything_image_processor: components["schemas"]["ImageOutput"];
content_shuffle_image_processor: components["schemas"]["ImageOutput"];
metadata_item: components["schemas"]["MetadataItemOutput"];
img_nsfw: components["schemas"]["ImageOutput"];
mask_edge: components["schemas"]["ImageOutput"];
img_hue_adjust: components["schemas"]["ImageOutput"];
infill_rgba: components["schemas"]["ImageOutput"];
esrgan: components["schemas"]["ImageOutput"];
alpha_mask_to_tensor: components["schemas"]["MaskOutput"];
img_pad_crop: components["schemas"]["ImageOutput"];
sub: components["schemas"]["IntegerOutput"];
clip_skip: components["schemas"]["CLIPSkipInvocationOutput"];
boolean: components["schemas"]["BooleanOutput"]; boolean: components["schemas"]["BooleanOutput"];
conditioning_collection: components["schemas"]["ConditioningCollectionOutput"]; mediapipe_face_processor: components["schemas"]["ImageOutput"];
calculate_image_tiles_even_split: components["schemas"]["CalculateImageTilesOutput"]; face_mask_detection: components["schemas"]["FaceMaskOutput"];
sdxl_refiner_compel_prompt: components["schemas"]["ConditioningOutput"];
img_channel_offset: components["schemas"]["ImageOutput"];
segment_anything: components["schemas"]["MaskOutput"];
boolean_collection: components["schemas"]["BooleanCollectionOutput"];
denoise_latents: components["schemas"]["LatentsOutput"];
img_paste: components["schemas"]["ImageOutput"];
face_identifier: components["schemas"]["ImageOutput"];
img_hue_adjust: components["schemas"]["ImageOutput"];
controlnet: components["schemas"]["ControlOutput"];
lineart_anime_image_processor: components["schemas"]["ImageOutput"];
img_ilerp: components["schemas"]["ImageOutput"];
float_range: components["schemas"]["FloatCollectionOutput"];
img_scale: components["schemas"]["ImageOutput"];
lora_selector: components["schemas"]["LoRASelectorOutput"];
float_to_int: components["schemas"]["IntegerOutput"];
mask_edge: components["schemas"]["ImageOutput"];
face_off: components["schemas"]["FaceOffOutput"];
canvas_paste_back: components["schemas"]["ImageOutput"];
image: components["schemas"]["ImageOutput"];
mask_combine: components["schemas"]["ImageOutput"];
integer_collection: components["schemas"]["IntegerCollectionOutput"];
compel: components["schemas"]["ConditioningOutput"];
normalbae_image_processor: components["schemas"]["ImageOutput"];
img_watermark: components["schemas"]["ImageOutput"];
tiled_multi_diffusion_denoise_latents: components["schemas"]["LatentsOutput"];
integer: components["schemas"]["IntegerOutput"];
spandrel_image_to_image: components["schemas"]["ImageOutput"];
color_correct: components["schemas"]["ImageOutput"]; color_correct: components["schemas"]["ImageOutput"];
latents_collection: components["schemas"]["LatentsCollectionOutput"]; latents_collection: components["schemas"]["LatentsCollectionOutput"];
infill_patchmatch: components["schemas"]["ImageOutput"]; img_lerp: components["schemas"]["ImageOutput"];
range_of_size: components["schemas"]["IntegerCollectionOutput"];
string_join_three: components["schemas"]["StringOutput"];
tile_image_processor: components["schemas"]["ImageOutput"];
img_resize: components["schemas"]["ImageOutput"];
string_join: components["schemas"]["StringOutput"];
sdxl_lora_collection_loader: components["schemas"]["SDXLLoRALoaderOutput"];
canny_image_processor: components["schemas"]["ImageOutput"];
string: components["schemas"]["StringOutput"]; string: components["schemas"]["StringOutput"];
string_collection: components["schemas"]["StringCollectionOutput"]; sub: components["schemas"]["IntegerOutput"];
ip_adapter: components["schemas"]["IPAdapterOutput"];
canvas_paste_back: components["schemas"]["ImageOutput"];
rectangle_mask: components["schemas"]["MaskOutput"];
sdxl_compel_prompt: components["schemas"]["ConditioningOutput"];
show_image: components["schemas"]["ImageOutput"];
img_conv: components["schemas"]["ImageOutput"];
img_paste: components["schemas"]["ImageOutput"];
heuristic_resize: components["schemas"]["ImageOutput"];
infill_cv2: components["schemas"]["ImageOutput"];
leres_image_processor: components["schemas"]["ImageOutput"];
l2i: components["schemas"]["ImageOutput"];
hed_image_processor: components["schemas"]["ImageOutput"];
main_model_loader: components["schemas"]["ModelLoaderOutput"];
string_split_neg: components["schemas"]["StringPosNegOutput"];
step_param_easing: components["schemas"]["FloatCollectionOutput"];
iterate: components["schemas"]["IterateInvocationOutput"];
string_split: components["schemas"]["String2Output"];
merge_metadata: components["schemas"]["MetadataOutput"];
face_mask_detection: components["schemas"]["FaceMaskOutput"];
img_watermark: components["schemas"]["ImageOutput"];
lora_loader: components["schemas"]["LoRALoaderOutput"];
float_range: components["schemas"]["FloatCollectionOutput"];
sdxl_refiner_model_loader: components["schemas"]["SDXLRefinerModelLoaderOutput"];
mask_from_id: components["schemas"]["ImageOutput"];
core_metadata: components["schemas"]["MetadataOutput"];
segment_anything: components["schemas"]["MaskOutput"];
invert_tensor_mask: components["schemas"]["MaskOutput"];
infill_tile: components["schemas"]["ImageOutput"];
model_identifier: components["schemas"]["ModelIdentifierOutput"];
noise: components["schemas"]["NoiseOutput"];
img_crop: components["schemas"]["ImageOutput"];
img_ilerp: components["schemas"]["ImageOutput"];
conditioning: components["schemas"]["ConditioningOutput"];
tomask: components["schemas"]["ImageOutput"];
face_identifier: components["schemas"]["ImageOutput"];
color_map_image_processor: components["schemas"]["ImageOutput"];
image_collection: components["schemas"]["ImageCollectionOutput"];
img_channel_multiply: components["schemas"]["ImageOutput"];
image_mask_to_tensor: components["schemas"]["MaskOutput"];
unsharp_mask: components["schemas"]["ImageOutput"]; unsharp_mask: components["schemas"]["ImageOutput"];
mask_from_id: components["schemas"]["ImageOutput"];
dw_openpose_image_processor: components["schemas"]["ImageOutput"];
string_split_neg: components["schemas"]["StringPosNegOutput"];
pidi_image_processor: components["schemas"]["ImageOutput"];
lresize: components["schemas"]["LatentsOutput"];
round_float: components["schemas"]["FloatOutput"];
float: components["schemas"]["FloatOutput"];
string_collection: components["schemas"]["StringCollectionOutput"];
freeu: components["schemas"]["UNetOutput"];
metadata_item: components["schemas"]["MetadataItemOutput"];
merge_metadata: components["schemas"]["MetadataOutput"];
calculate_image_tiles_min_overlap: components["schemas"]["CalculateImageTilesOutput"];
merge_tiles_to_image: components["schemas"]["ImageOutput"];
iterate: components["schemas"]["IterateInvocationOutput"];
float_collection: components["schemas"]["FloatCollectionOutput"];
lblend: components["schemas"]["LatentsOutput"];
ideal_size: components["schemas"]["IdealSizeOutput"]; ideal_size: components["schemas"]["IdealSizeOutput"];
tomask: components["schemas"]["ImageOutput"];
string_split: components["schemas"]["String2Output"];
mul: components["schemas"]["IntegerOutput"];
string_replace: components["schemas"]["StringOutput"];
seamless: components["schemas"]["SeamlessModeOutput"];
tile_image_processor: components["schemas"]["ImageOutput"];
image_mask_to_tensor: components["schemas"]["MaskOutput"];
rand_int: components["schemas"]["IntegerOutput"];
bounding_box: components["schemas"]["BoundingBoxOutput"];
main_model_loader: components["schemas"]["ModelLoaderOutput"];
img_channel_multiply: components["schemas"]["ImageOutput"];
random_range: components["schemas"]["IntegerCollectionOutput"];
noise: components["schemas"]["NoiseOutput"];
sdxl_refiner_model_loader: components["schemas"]["SDXLRefinerModelLoaderOutput"];
rectangle_mask: components["schemas"]["MaskOutput"];
invert_tensor_mask: components["schemas"]["MaskOutput"];
core_metadata: components["schemas"]["MetadataOutput"];
img_chan: components["schemas"]["ImageOutput"];
depth_anything_image_processor: components["schemas"]["ImageOutput"];
step_param_easing: components["schemas"]["FloatCollectionOutput"];
infill_lama: components["schemas"]["ImageOutput"];
calculate_image_tiles: components["schemas"]["CalculateImageTilesOutput"];
float_math: components["schemas"]["FloatOutput"];
lora_loader: components["schemas"]["LoRALoaderOutput"];
dynamic_prompt: components["schemas"]["StringCollectionOutput"];
lscale: components["schemas"]["LatentsOutput"];
sdxl_lora_collection_loader: components["schemas"]["SDXLLoRALoaderOutput"];
leres_image_processor: components["schemas"]["ImageOutput"];
i2l: components["schemas"]["LatentsOutput"];
sdxl_model_loader: components["schemas"]["SDXLModelLoaderOutput"];
infill_rgba: components["schemas"]["ImageOutput"];
range_of_size: components["schemas"]["IntegerCollectionOutput"];
lora_collection_loader: components["schemas"]["LoRALoaderOutput"];
rand_float: components["schemas"]["FloatOutput"];
spandrel_image_to_image_autoscale: components["schemas"]["ImageOutput"];
heuristic_resize: components["schemas"]["ImageOutput"];
div: components["schemas"]["IntegerOutput"];
save_image: components["schemas"]["ImageOutput"];
midas_depth_image_processor: components["schemas"]["ImageOutput"];
integer_math: components["schemas"]["IntegerOutput"];
collect: components["schemas"]["CollectInvocationOutput"];
alpha_mask_to_tensor: components["schemas"]["MaskOutput"];
blank_image: components["schemas"]["ImageOutput"];
string_join: components["schemas"]["StringOutput"];
pair_tile_image: components["schemas"]["PairTileImageOutput"];
hed_image_processor: components["schemas"]["ImageOutput"];
img_nsfw: components["schemas"]["ImageOutput"];
conditioning_collection: components["schemas"]["ConditioningCollectionOutput"];
img_blur: components["schemas"]["ImageOutput"];
model_identifier: components["schemas"]["ModelIdentifierOutput"];
clip_skip: components["schemas"]["CLIPSkipInvocationOutput"];
sdxl_compel_prompt: components["schemas"]["ConditioningOutput"];
infill_patchmatch: components["schemas"]["ImageOutput"];
metadata: components["schemas"]["MetadataOutput"];
img_crop: components["schemas"]["ImageOutput"];
tensor_mask_to_image: components["schemas"]["ImageOutput"];
show_image: components["schemas"]["ImageOutput"];
canny_image_processor: components["schemas"]["ImageOutput"];
esrgan: components["schemas"]["ImageOutput"];
prompt_from_file: components["schemas"]["StringCollectionOutput"];
image_collection: components["schemas"]["ImageCollectionOutput"];
calculate_image_tiles_even_split: components["schemas"]["CalculateImageTilesOutput"];
img_pad_crop: components["schemas"]["ImageOutput"];
l2i: components["schemas"]["ImageOutput"];
sdxl_lora_loader: components["schemas"]["SDXLLoRALoaderOutput"];
range: components["schemas"]["IntegerCollectionOutput"];
scheduler: components["schemas"]["SchedulerOutput"];
lineart_image_processor: components["schemas"]["ImageOutput"];
content_shuffle_image_processor: components["schemas"]["ImageOutput"];
create_gradient_mask: components["schemas"]["GradientMaskOutput"];
ip_adapter: components["schemas"]["IPAdapterOutput"];
color_map_image_processor: components["schemas"]["ImageOutput"];
string_join_three: components["schemas"]["StringOutput"];
infill_cv2: components["schemas"]["ImageOutput"];
mlsd_image_processor: components["schemas"]["ImageOutput"];
segment_anything_processor: components["schemas"]["ImageOutput"];
img_mul: components["schemas"]["ImageOutput"];
conditioning: components["schemas"]["ConditioningOutput"];
cv_inpaint: components["schemas"]["ImageOutput"];
t2i_adapter: components["schemas"]["T2IAdapterOutput"];
add: components["schemas"]["IntegerOutput"];
crop_latents: components["schemas"]["LatentsOutput"];
infill_tile: components["schemas"]["ImageOutput"];
latents: components["schemas"]["LatentsOutput"];
img_resize: components["schemas"]["ImageOutput"];
create_denoise_mask: components["schemas"]["DenoiseMaskOutput"];
img_conv: components["schemas"]["ImageOutput"];
grounding_dino: components["schemas"]["BoundingBoxCollectionOutput"];
zoe_depth_image_processor: components["schemas"]["ImageOutput"];
vae_loader: components["schemas"]["VAEOutput"];
}; };
/** /**
* InvocationStartedEvent * InvocationStartedEvent
@ -10569,6 +10569,11 @@ export type components = {
*/ */
negative_prompt: string; negative_prompt: string;
}; };
/**
* PresetType
* @enum {string}
*/
PresetType: "user" | "default" | "project";
/** /**
* ProgressImage * ProgressImage
* @description The progress image sent intermittently during processing * @description The progress image sent intermittently during processing
@ -12977,16 +12982,16 @@ export type components = {
name: string; name: string;
/** @description The preset data */ /** @description The preset data */
preset_data: components["schemas"]["PresetData"]; preset_data: components["schemas"]["PresetData"];
/**
* @description The type of style preset
* @default user
*/
type?: components["schemas"]["PresetType"];
/** /**
* Id * Id
* @description The style preset ID. * @description The style preset ID.
*/ */
id: string; id: string;
/**
* Is Default
* @description Whether or not the style preset is default
*/
is_default: boolean;
/** /**
* Image * Image
* @description The path for image * @description The path for image