Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions comfy_api/latest/_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,61 @@ class Load3DAnimation(Load3D):
...


@comfytype(io_type="LAYERS")
class Layers(ComfyTypeIO):
BlendMode = Literal[
"normal", "multiply", "screen", "overlay", "darken", "lighten",
"color-dodge", "color-burn", "hard-light", "soft-light", "difference",
"exclusion", "linear-dodge", "linear-burn", "vivid-light", "pin-light",
"linear-light", "hard-mix", "subtract", "divide", "grain-extract",
"grain-merge", "hue", "saturation", "color", "luminosity",
]

class LayerItem(TypedDict):
image: torch.Tensor
type: Literal["raster"]
x: NotRequired[int]
y: NotRequired[int]
mask: NotRequired[torch.Tensor]
z_index: int
name: NotRequired[str]
opacity: NotRequired[float]
blend_mode: NotRequired["Layers.BlendMode"]
visible: NotRequired[bool]
flip_h: NotRequired[bool]
flip_v: NotRequired[bool]
rotation: NotRequired[float]
w: NotRequired[int]
h: NotRequired[int]

class Document(TypedDict):
version: int
canvas: NotRequired[tuple[int, int]]
layers: list["Layers.LayerItem"]

Type = Document


@comfytype(io_type="COMPOSITOR")
class Compositor(ComfyTypeIO):
class LayerState(TypedDict):
version: NotRequired[int]
canvas: dict
background: NotRequired[dict]
inputs: NotRequired[list[str]]
order: NotRequired[list[int]]
layers: list[dict]

Type = LayerState

class Input(WidgetInput):
def __init__(self, id: str, display_name: str=None, optional=False, tooltip: str=None,
socketless: bool=True, default: dict=None, advanced: bool=None):
super().__init__(id, display_name, optional, tooltip, None, default, socketless, None, None, None, None, advanced)
if default is None:
self.default = {}


@comfytype(io_type="PHOTOMAKER")
class Photomaker(ComfyTypeIO):
Type = Any
Expand Down Expand Up @@ -2403,6 +2458,8 @@ def as_dict(self):
"Load3DModelInfo",
"Load3D",
"Load3DAnimation",
"Compositor",
"Layers",
"Photomaker",
"Point",
"FaceAnalysis",
Expand Down
47 changes: 46 additions & 1 deletion comfy_api_nodes/apis/bytedance.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@ class Seedream4TaskCreationRequest(BaseModel):
optimize_prompt_options: Seedream5OptimizePromptOptions | None = None


class Seedream5LayerOptimizePromptOptions(BaseModel):
mode: Literal["standard", "fast"] = Field(...)


class Seedream5LayerSeparationRequest(BaseModel):
model: str = Field(...)
prompt: str | None = Field(None)
image: str = Field(..., description="Single image URL")
size: str = Field("auto")
seed: int = Field(..., ge=0, le=2147483647)
response_format: str = Field("url")
output_format: str = Field("png")
layer_decomposition: bool = Field(True)
watermark: bool = Field(False)
optimize_prompt_options: Seedream5LayerOptimizePromptOptions | None = Field(None)


class ImageTaskCreationResponse(BaseModel):
model: str = Field(...)
created: int = Field(..., description="Unix timestamp (in seconds) indicating time when the request was created.")
Expand Down Expand Up @@ -95,9 +112,10 @@ class Seedance2TaskCreationRequest(BaseModel):
generate_audio: bool | None = Field(None)
resolution: str | None = Field(None)
ratio: str | None = Field(None)
duration: int | None = Field(None, ge=4, le=15)
duration: int | None = Field(None)
seed: int | None = Field(None, ge=0, le=2147483647)
watermark: bool | None = Field(None)
output_format: str | None = Field(None)


class TaskCreationResponse(BaseModel):
Expand Down Expand Up @@ -186,6 +204,10 @@ class SeedanceVirtualLibraryCreateAssetRequest(BaseModel):
("dreamina-seedance-2-0-mini", True, "480p"): 0.0021,
("dreamina-seedance-2-0-mini", False, "720p"): 0.0035,
("dreamina-seedance-2-0-mini", True, "720p"): 0.0021,
("dreamina-seedance-2-5-260628", False, "480p"): 0.0107,
("dreamina-seedance-2-5-260628", True, "480p"): 0.0064,
("dreamina-seedance-2-5-260628", False, "720p"): 0.0107,
("dreamina-seedance-2-5-260628", True, "720p"): 0.0064,
}


Expand Down Expand Up @@ -304,7 +326,30 @@ def seedance2_price_per_1k_tokens(model_id: str, has_video_input: bool, resoluti
"480p": {"min": 409_600, "max": 927_408},
"720p": {"min": 409_600, "max": 927_408},
},
"dreamina-seedance-2-5-260628": {
"480p": {"min": 409_600, "max": 8_295_044},
"720p": {"min": 409_600, "max": 8_295_044},
},
}

SEEDANCE2_REFERENCE_LIMITS_DEFAULT = {
"max_images": 9,
"max_videos": 3,
"max_audios": 3,
"max_total_seconds": 15.1,
}
SEEDANCE2_REFERENCE_LIMITS = {
"dreamina-seedance-2-5-260628": {
"max_images": 30,
"max_videos": 10,
"max_audios": 10,
"max_total_seconds": 30.1,
},
}


def seedance2_reference_limits(model_id: str) -> dict:
return SEEDANCE2_REFERENCE_LIMITS.get(model_id, SEEDANCE2_REFERENCE_LIMITS_DEFAULT)

# The time in this dictionary are given for 10 seconds duration.
VIDEO_TASKS_EXECUTION_TIME = {
Expand Down
Loading
Loading