cddb07a176
docs / deploy (push) Has been cancelled
docs / changes (push) Has been cancelled
docs / check-and-build (push) Has been cancelled
build container image / cpu (push) Has been cancelled
build container image / cuda (push) Has been cancelled
build container image / rocm (push) Has been cancelled
frontend checks / frontend-checks (push) Has been cancelled
frontend tests / frontend-tests (push) Has been cancelled
lfs checks / lfs-check (push) Has been cancelled
python checks / python-checks (push) Has been cancelled
python tests / py3.12: macos-default (push) Has been cancelled
python tests / py3.11: windows-cpu (push) Has been cancelled
python tests / py3.12: windows-cpu (push) Has been cancelled
python tests / py3.11: linux-cpu (push) Has been cancelled
typegen checks / typegen-checks (push) Has been cancelled
uv lock checks / uv-lock-checks (push) Has been cancelled
openapi checks / openapi-checks (push) Has been cancelled
python tests / py3.11: macos-default (push) Has been cancelled
python tests / py3.12: linux-cpu (push) Has been cancelled
114 lines
4.9 KiB
Python
114 lines
4.9 KiB
Python
from typing import Literal, Self
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
|
|
from invokeai.backend.model_manager.configs.base import Config_Base
|
|
from invokeai.backend.model_manager.configs.identification_utils import NotAMatchError
|
|
from invokeai.backend.model_manager.model_on_disk import ModelOnDisk
|
|
from invokeai.backend.model_manager.taxonomy import BaseModelType, ModelFormat, ModelSourceType, ModelType
|
|
|
|
ExternalGenerationMode = Literal["txt2img", "img2img", "inpaint"]
|
|
ExternalMaskFormat = Literal["alpha", "binary", "none"]
|
|
ExternalPanelControlName = Literal["reference_images", "dimensions", "seed"]
|
|
|
|
|
|
class ExternalImageSize(BaseModel):
|
|
width: int = Field(gt=0)
|
|
height: int = Field(gt=0)
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
class ExternalResolutionPreset(BaseModel):
|
|
label: str = Field(min_length=1, description="Display label, e.g. '1:1 (1K)'")
|
|
aspect_ratio: str = Field(min_length=1, description="Aspect ratio string, e.g. '1:1'")
|
|
image_size: str = Field(min_length=1, description="Image size preset, e.g. '1K'")
|
|
width: int = Field(gt=0)
|
|
height: int = Field(gt=0)
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
class ExternalModelCapabilities(BaseModel):
|
|
modes: list[ExternalGenerationMode] = Field(default_factory=lambda: ["txt2img"])
|
|
supports_reference_images: bool = Field(default=False)
|
|
supports_negative_prompt: bool = Field(default=True)
|
|
supports_seed: bool = Field(default=False)
|
|
supports_guidance: bool = Field(default=False)
|
|
supports_steps: bool = Field(default=False)
|
|
max_images_per_request: int | None = Field(default=None, gt=0)
|
|
max_image_size: ExternalImageSize | None = Field(default=None)
|
|
allowed_aspect_ratios: list[str] | None = Field(default=None)
|
|
aspect_ratio_sizes: dict[str, ExternalImageSize] | None = Field(default=None)
|
|
resolution_presets: list[ExternalResolutionPreset] | None = Field(default=None)
|
|
max_reference_images: int | None = Field(default=None, gt=0)
|
|
mask_format: ExternalMaskFormat = Field(default="none")
|
|
input_image_required_for: list[ExternalGenerationMode] | None = Field(default=None)
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
class ExternalApiModelDefaultSettings(BaseModel):
|
|
width: int | None = Field(default=None, gt=0)
|
|
height: int | None = Field(default=None, gt=0)
|
|
num_images: int | None = Field(default=None, gt=0)
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
class ExternalModelPanelControl(BaseModel):
|
|
name: ExternalPanelControlName
|
|
slider_min: float | None = Field(default=None)
|
|
slider_max: float | None = Field(default=None)
|
|
number_input_min: float | None = Field(default=None)
|
|
number_input_max: float | None = Field(default=None)
|
|
fine_step: float | None = Field(default=None)
|
|
coarse_step: float | None = Field(default=None)
|
|
marks: list[float] | None = Field(default=None)
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
class ExternalModelPanelSchema(BaseModel):
|
|
prompts: list[ExternalModelPanelControl] = Field(default_factory=list)
|
|
image: list[ExternalModelPanelControl] = Field(default_factory=list)
|
|
generation: list[ExternalModelPanelControl] = Field(default_factory=list)
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
class ExternalApiModelConfig(Config_Base):
|
|
base: Literal[BaseModelType.External] = Field(default=BaseModelType.External)
|
|
type: Literal[ModelType.ExternalImageGenerator] = Field(default=ModelType.ExternalImageGenerator)
|
|
format: Literal[ModelFormat.ExternalApi] = Field(default=ModelFormat.ExternalApi)
|
|
|
|
provider_id: str = Field(min_length=1, description="External provider ID")
|
|
provider_model_id: str = Field(min_length=1, description="Provider-specific model ID")
|
|
capabilities: ExternalModelCapabilities = Field(description="Provider capability matrix")
|
|
default_settings: ExternalApiModelDefaultSettings | None = Field(default=None)
|
|
panel_schema: ExternalModelPanelSchema | None = Field(default=None)
|
|
tags: list[str] | None = Field(default=None)
|
|
is_default: bool = Field(default=False)
|
|
|
|
source_type: ModelSourceType = Field(default=ModelSourceType.External)
|
|
path: str = Field(default="")
|
|
source: str = Field(default="")
|
|
hash: str = Field(default="")
|
|
file_size: int = Field(default=0, ge=0)
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
@model_validator(mode="after")
|
|
def _populate_external_fields(self) -> "ExternalApiModelConfig":
|
|
if not self.path:
|
|
self.path = f"external://{self.provider_id}/{self.provider_model_id}"
|
|
if not self.source:
|
|
self.source = self.path
|
|
if not self.hash:
|
|
self.hash = f"external:{self.provider_id}:{self.provider_model_id}"
|
|
return self
|
|
|
|
@classmethod
|
|
def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, object]) -> Self:
|
|
raise NotAMatchError("external API models are not probed from disk")
|