Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 13:22:06 +08:00

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")