Compare commits

..

13 Commits

Author SHA1 Message Date
c89cd46725 Merge branch 'master' into cloud-openapi-projection 2026-06-16 12:22:51 +08:00
135abed8da ComfyUI v0.25.0 2026-06-15 23:45:14 -04:00
a439dcae07 Update nodes titles (#14417) 2026-06-16 11:42:00 +08:00
5db51b76b4 Fix odd-height crash and edge bleed in unaligned-width image/video decode (#14491)
a1d95f3f padded the decode width to the next multiple of 32 with the pad filter to fix libswscale's float YUV->GBR edge corruption, but kept the pad target height equal to the source height. The pad filter requires the target height to be a multiple of the input's vertical chroma subsampling factor, so a chroma-subsampled input such as yuv420p (the format the gbrpf32le float branch decodes) with an odd height makes the filter round the target below the input height and fail to configure: 'Padded dimensions cannot be smaller than input dimensions' (Errno 22). This is reachable from LoadImage, which routes static images through VideoFromFile, on a lossy WebP whose width is not a multiple of 32 and whose height is odd.

The pad filter also fills the added border with black, and chroma upsampling bleeds that black into the cropped edge of every unaligned-width subsampled decode.

Pad both axes to the next multiple of 32 (32 is a multiple of every vertical subsampling factor, including yuv410p's 4 that a plain even rounding misses) and run fillborders mode=smear to replicate the real edge into the padding so it never bleeds into the cropped output, then crop both axes back to the source size. Aligned-width and uint8 paths run the identical to_ndarray call as before and are byte-identical to master; only unaligned-width subsampled inputs change, from a crash or edge artifact to a clean, deterministic decode.
2026-06-15 20:23:09 -07:00
b13ca1ce7b main: support fallback to aimdo 0.4.9 (#14489)
The aimdo 0.4.10 protocol causing startup failure to be too early and
before the aimdo version warning can happen. This causes user
confusion. Limp on with 0.4.9 as it will work and users will see the
version warning.
2026-06-15 20:22:24 -07:00
c47e21a3e0 chore(openapi): sync shared API contract from cloud@00ef9cc 2026-06-15 19:14:41 +00:00
2f4c4e983c [Partner Nodes] fix(SoniloTextToMusic): always require "duration" to be specified (#14484) 2026-06-16 00:20:01 +08:00
83a3f03218 chore: update workflow templates to v0.10.0 (#14482) 2026-06-15 08:06:15 -07:00
ec4dec93d2 Comfy Aimdo 0.4.10 + Dynamic --reserve-vram + --vram-headroom (#14480)
* main: implement --vram-headroom

Implement --vram-headroom for dynamic vram as a hybrid debug/diagnostic
option that can be used for people who still report shared VRAM spills.
They can trial and error the setting to maintain a bit more headroom to
avoid shared VRAM spills.

* main: implement --reserve-vram

Implement --reserve-vram as extra headroom on the simple method which
is semantically as close as possible to the stated functionality and
formet behaviour of non-dynamic VRAM.
2026-06-15 07:54:36 -07:00
7d4194d984 chore: update embedded docs to v0.5.4 (#14478) 2026-06-15 16:35:36 +08:00
4388eb781a This is already auto enabled by default. (#14476) 2026-06-14 18:47:22 -07:00
e1b9366898 bump manager version to 4.2.2 (#14471) 2026-06-14 14:42:03 -04:00
5897d0c3ae [Partner Nodes] feat(Tripo3d): add new "Import 3D" node (#14466)
Signed-off-by: bigcat88 <bigcat88@icloud.com>
2026-06-14 17:19:20 +03:00
15 changed files with 186 additions and 53 deletions

View File

@ -382,11 +382,7 @@ For AMD 7600 and maybe other RDNA3 cards: ```HSA_OVERRIDE_GFX_VERSION=11.0.0 pyt
### AMD ROCm Tips ### AMD ROCm Tips
You can enable experimental memory efficient attention on recent pytorch in ComfyUI on some AMD GPUs using this command, it should already be enabled by default on RDNA3. If this improves speed for you on latest pytorch on your GPU please report it so that I can enable it by default. You can try setting this env variable `PYTORCH_TUNABLEOP_ENABLED=1` which might speed things up at the cost of a very slow initial run.
```TORCH_ROCM_AOTRITON_ENABLE_EXPERIMENTAL=1 python main.py --use-pytorch-cross-attention```
You can also try setting this env variable `PYTORCH_TUNABLEOP_ENABLED=1` which might speed things up at the cost of a very slow initial run.
# Notes # Notes

View File

@ -145,6 +145,7 @@ vram_group.add_argument("--novram", action="store_true", help="When lowvram isn'
vram_group.add_argument("--cpu", action="store_true", help="To use the CPU for everything (slow).") vram_group.add_argument("--cpu", action="store_true", help="To use the CPU for everything (slow).")
parser.add_argument("--reserve-vram", type=float, default=None, help="Set the amount of vram in GB you want to reserve for use by your OS/other software. By default some amount is reserved depending on your OS.") parser.add_argument("--reserve-vram", type=float, default=None, help="Set the amount of vram in GB you want to reserve for use by your OS/other software. By default some amount is reserved depending on your OS.")
parser.add_argument("--vram-headroom", type=float, default=0, help="Set the amount of vram in GB for DynamicVRAM to maintain as extra headroom above default. ComfyUI will try and keep this much VRAM completely free and unused, even counting VRAM from other apps.")
parser.add_argument("--async-offload", nargs='?', const=2, type=int, default=None, metavar="NUM_STREAMS", help="Use async weight offloading. An optional argument controls the amount of offload streams. Default is 2. Enabled by default on Nvidia.") parser.add_argument("--async-offload", nargs='?', const=2, type=int, default=None, metavar="NUM_STREAMS", help="Use async weight offloading. An optional argument controls the amount of offload streams. Default is 2. Enabled by default on Nvidia.")
parser.add_argument("--disable-async-offload", action="store_true", help="Disable async weight offloading.") parser.add_argument("--disable-async-offload", action="store_true", help="Disable async weight offloading.")

View File

@ -325,21 +325,25 @@ class VideoFromFile(VideoInput):
checked_alpha = True checked_alpha = True
# Fix non-deterministic video decode when the video width is not a multiple of 32 # Fix non-deterministic video decode when the video width is not a multiple of 32
# For non-yuvj pixel formats (all H.264/H.265 video) # For non-yuvj pixel formats: most H.264/H.265 video and static images (e.g. lossy WebP via LoadImage)
# Pad both axes to a multiple of 32 and smear the border so the alignment padding never bleeds into the cropped edges
if image_format in ('gbrpf32le', 'gbrapf32le') and frame.width % 32 != 0: if image_format in ('gbrpf32le', 'gbrapf32le') and frame.width % 32 != 0:
if align_graph is None: if align_graph is None:
pad_w = ((frame.width + 31) // 32) * 32 pad_w = ((frame.width + 31) // 32) * 32
pad_h = ((frame.height + 31) // 32) * 32
g = av.filter.Graph() g = av.filter.Graph()
g_src = g.add_buffer(width=frame.width, height=frame.height, g_src = g.add_buffer(width=frame.width, height=frame.height,
format=frame.format.name, time_base=video_stream.time_base) format=frame.format.name, time_base=video_stream.time_base)
g_pad = g.add('pad', f'{pad_w}:{frame.height}:0:0') g_pad = g.add('pad', f'{pad_w}:{pad_h}:0:0')
g_fill = g.add('fillborders', f'left=0:right={pad_w - frame.width}:top=0:bottom={pad_h - frame.height}:mode=smear')
g_sink = g.add('buffersink') g_sink = g.add('buffersink')
g_src.link_to(g_pad) g_src.link_to(g_pad)
g_pad.link_to(g_sink) g_pad.link_to(g_fill)
g_fill.link_to(g_sink)
g.configure() g.configure()
align_graph = (g, g_src, g_sink) align_graph = (g, g_src, g_sink)
align_graph[1].push(frame) align_graph[1].push(frame)
img = np.ascontiguousarray(align_graph[2].pull().to_ndarray(format=image_format)[:, :frame.width]) img = np.ascontiguousarray(align_graph[2].pull().to_ndarray(format=image_format)[:frame.height, :frame.width])
else: else:
img = frame.to_ndarray(format=image_format) img = frame.to_ndarray(format=image_format)
if frame.rotation != 0: if frame.rotation != 0:

View File

@ -208,6 +208,10 @@ class TripoMultiviewToModelRequest(BaseModel):
quad: bool | None = Field(False, description="Whether to apply quad to the generated model") quad: bool | None = Field(False, description="Whether to apply quad to the generated model")
class TripoTexturePrompt(BaseModel):
text: str | None = Field(None, description="Text guidance for texture generation")
class TripoTextureModelRequest(BaseModel): class TripoTextureModelRequest(BaseModel):
type: TripoTaskType = Field(TripoTaskType.TEXTURE_MODEL, description="Type of task") type: TripoTaskType = Field(TripoTaskType.TEXTURE_MODEL, description="Type of task")
original_model_task_id: str = Field(..., description="The task ID of the original model") original_model_task_id: str = Field(..., description="The task ID of the original model")
@ -219,6 +223,11 @@ class TripoTextureModelRequest(BaseModel):
texture_alignment: TripoTextureAlignment | None = Field( texture_alignment: TripoTextureAlignment | None = Field(
TripoTextureAlignment.ORIGINAL_IMAGE, description="The texture alignment method" TripoTextureAlignment.ORIGINAL_IMAGE, description="The texture alignment method"
) )
texture_prompt: TripoTexturePrompt | None = Field(
None,
description="Optional guidance for texturing. Required in practice for imported models, "
"which carry no source image to infer texture from.",
)
class TripoRefineModelRequest(BaseModel): class TripoRefineModelRequest(BaseModel):
@ -307,6 +316,17 @@ class TripoP1MultiviewToModelRequest(TripoP1CommonRequest):
orientation: str | None = None orientation: str | None = None
class TripoImportModelRequest(BaseModel):
"""Request for the comfy-api composite import endpoint (/proxy/tripo/v2/openapi/import).
The model file is uploaded to ComfyUI API storage first; the backend downloads it from
`url`, re-uploads it to Tripo's storage and creates the import_model task server-side.
"""
url: str = Field(..., description="ComfyUI API storage download URL of the model file")
format: str = Field(..., description='File format: "glb", "fbx", "obj" or "stl"')
class TripoTaskOutput(BaseModel): class TripoTaskOutput(BaseModel):
model: str | None = Field(None, description="URL to the model") model: str | None = Field(None, description="URL to the model")
base_model: str | None = Field(None, description="URL to the base model") base_model: str | None = Field(None, description="URL to the base model")

View File

@ -111,11 +111,10 @@ class SoniloTextToMusic(IO.ComfyNode):
), ),
IO.Int.Input( IO.Int.Input(
"duration", "duration",
default=0, default=30,
min=0, min=1,
max=360, max=360,
tooltip="Target duration in seconds. Set to 0 to let the model " tooltip="Target duration in seconds. Maximum: 6 minutes.",
"infer the duration from the prompt. Maximum: 6 minutes.",
), ),
IO.Int.Input( IO.Int.Input(
"seed", "seed",
@ -150,14 +149,13 @@ class SoniloTextToMusic(IO.ComfyNode):
async def execute( async def execute(
cls, cls,
prompt: str, prompt: str,
duration: int = 0, duration: int = 1,
seed: int = 0, seed: int = 0,
) -> IO.NodeOutput: ) -> IO.NodeOutput:
validate_string(prompt, strip_whitespace=True, min_length=1) validate_string(prompt, strip_whitespace=True, min_length=1, max_length=1000)
form = aiohttp.FormData() form = aiohttp.FormData()
form.add_field("prompt", prompt) form.add_field("prompt", prompt)
if duration > 0: form.add_field("duration", str(duration))
form.add_field("duration", str(duration))
audio_bytes = await _stream_sonilo_music( audio_bytes = await _stream_sonilo_music(
cls, cls,
ApiEndpoint(path="/proxy/sonilo/t2m/generate", method="POST"), ApiEndpoint(path="/proxy/sonilo/t2m/generate", method="POST"),

View File

@ -1,6 +1,6 @@
from typing_extensions import override from typing_extensions import override
from comfy_api.latest import IO, ComfyExtension, Input from comfy_api.latest import IO, ComfyExtension, Input, Types
from comfy_api_nodes.apis.tripo import ( from comfy_api_nodes.apis.tripo import (
TripoAnimateRetargetRequest, TripoAnimateRetargetRequest,
TripoAnimateRigRequest, TripoAnimateRigRequest,
@ -8,6 +8,7 @@ from comfy_api_nodes.apis.tripo import (
TripoFileEmptyReference, TripoFileEmptyReference,
TripoFileReference, TripoFileReference,
TripoImageToModelRequest, TripoImageToModelRequest,
TripoImportModelRequest,
TripoModelVersion, TripoModelVersion,
TripoMultiviewToModelRequest, TripoMultiviewToModelRequest,
TripoOrientation, TripoOrientation,
@ -21,6 +22,7 @@ from comfy_api_nodes.apis.tripo import (
TripoTaskType, TripoTaskType,
TripoTextToModelRequest, TripoTextToModelRequest,
TripoTextureModelRequest, TripoTextureModelRequest,
TripoTexturePrompt,
TripoUrlReference, TripoUrlReference,
) )
from comfy_api_nodes.util import ( from comfy_api_nodes.util import (
@ -28,6 +30,7 @@ from comfy_api_nodes.util import (
download_url_to_file_3d, download_url_to_file_3d,
poll_op, poll_op,
sync_op, sync_op,
upload_3d_model_to_comfyapi,
upload_images_to_comfyapi, upload_images_to_comfyapi,
) )
@ -538,6 +541,14 @@ class TripoTextureNode(IO.ComfyNode):
optional=True, optional=True,
advanced=True, advanced=True,
), ),
IO.String.Input(
"texture_prompt",
default="",
multiline=True,
optional=True,
tooltip="Optional text guidance for texturing. Required in practice for imported "
"models (Tripo: Import Model), which carry no source image to infer colors from.",
),
], ],
outputs=[ outputs=[
IO.String.Output(display_name="model_file"), # for backward compatibility only IO.String.Output(display_name="model_file"), # for backward compatibility only
@ -571,6 +582,7 @@ class TripoTextureNode(IO.ComfyNode):
texture_seed: int | None = None, texture_seed: int | None = None,
texture_quality: str | None = None, texture_quality: str | None = None,
texture_alignment: str | None = None, texture_alignment: str | None = None,
texture_prompt: str = "",
) -> IO.NodeOutput: ) -> IO.NodeOutput:
response = await sync_op( response = await sync_op(
cls, cls,
@ -583,6 +595,7 @@ class TripoTextureNode(IO.ComfyNode):
texture_seed=texture_seed, texture_seed=texture_seed,
texture_quality=texture_quality, texture_quality=texture_quality,
texture_alignment=texture_alignment, texture_alignment=texture_alignment,
texture_prompt=TripoTexturePrompt(text=texture_prompt.strip()) if texture_prompt.strip() else None,
), ),
) )
return await poll_until_finished(cls, response, average_duration=80) return await poll_until_finished(cls, response, average_duration=80)
@ -915,6 +928,90 @@ class TripoConversionNode(IO.ComfyNode):
return await poll_until_finished(cls, response, average_duration=30) return await poll_until_finished(cls, response, average_duration=30)
class TripoImportModelNode(IO.ComfyNode):
"""Imports an external 3D model into Tripo, producing a MODEL_TASK_ID for post-processing nodes."""
SUPPORTED_FORMATS = ("glb", "fbx", "obj", "stl")
@classmethod
def define_schema(cls):
return IO.Schema(
node_id="TripoImportModelNode",
display_name="Tripo: Import Model",
category="partner/3d/Tripo",
description="Import an external 3D model (e.g. from Rodin, Hunyuan3D or a local file) into Tripo "
"to use it with Tripo's post-processing nodes: Texture, Rig, Convert. "
"GLB is recommended: textures survive import only when embedded in the file. "
"Note that texturing an imported model requires a texture prompt.",
inputs=[
IO.MultiType.Input(
"model_3d",
types=[IO.File3DGLB, IO.File3DFBX, IO.File3DOBJ, IO.File3DSTL, IO.File3DAny],
tooltip="3D model to import (GLB / FBX / OBJ / STL, up to 150 MB). "
"OBJ and STL files carry no embedded textures.",
),
],
outputs=[
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
],
hidden=[
IO.Hidden.auth_token_comfy_org,
IO.Hidden.api_key_comfy_org,
IO.Hidden.unique_id,
],
is_api_node=True,
price_badge=IO.PriceBadge(
expr="""{"type":"text","text":"Free"}""",
),
)
@classmethod
async def execute(cls, model_3d: Types.File3D) -> IO.NodeOutput:
file_format = (model_3d.format or "").lstrip(".").lower()
if file_format == "gltf":
raise ValueError(
"GLTF (.gltf) references external files and cannot be imported. Export a single-file GLB instead."
)
if file_format not in cls.SUPPORTED_FORMATS:
raise ValueError(
f"Unsupported 3D format '{file_format or 'unknown'}'. "
f"Tripo import supports: {', '.join(f.upper() for f in cls.SUPPORTED_FORMATS)}."
)
size = len(model_3d.get_bytes())
if size > 150 * 1024 * 1024:
raise ValueError(f"Model file is {size / (1024 * 1024):.1f} MB; Tripo import allows up to 150 MB.")
url = await upload_3d_model_to_comfyapi(cls, model_3d, file_format)
response = await sync_op(
cls,
endpoint=ApiEndpoint(path="/proxy/tripo/v2/openapi/import", method="POST"),
response_model=TripoTaskResponse,
data=TripoImportModelRequest(url=url, format=file_format),
)
if response.code != 0:
raise RuntimeError(f"Failed to import model: {response.error}")
task_id = response.data.task_id
response_poll = await poll_op(
cls,
poll_endpoint=ApiEndpoint(path=f"/proxy/tripo/v2/openapi/task/{task_id}"),
response_model=TripoTaskResponse,
failed_statuses=[
TripoTaskStatus.FAILED,
TripoTaskStatus.CANCELLED,
TripoTaskStatus.UNKNOWN,
TripoTaskStatus.BANNED,
TripoTaskStatus.EXPIRED,
],
status_extractor=lambda x: x.data.status,
progress_extractor=lambda x: x.data.progress,
estimated_duration=10,
)
if response_poll.data.status != TripoTaskStatus.SUCCESS:
raise RuntimeError(f"Failed to import model: {response_poll}")
return IO.NodeOutput(task_id)
def _p1_price_expr(*, geometry_credits: int, textured_credits: int, detailed_credits: int) -> str: def _p1_price_expr(*, geometry_credits: int, textured_credits: int, detailed_credits: int) -> str:
return ( return (
"(" "("
@ -1292,6 +1389,7 @@ class TripoExtension(ComfyExtension):
TripoP1TextToModelNode, TripoP1TextToModelNode,
TripoP1ImageToModelNode, TripoP1ImageToModelNode,
TripoP1MultiviewToModelNode, TripoP1MultiviewToModelNode,
TripoImportModelNode,
TripoTextureNode, TripoTextureNode,
TripoRefineNode, TripoRefineNode,
TripoRigNode, TripoRigNode,

View File

@ -14,7 +14,7 @@ class RTDETR_detect(io.ComfyNode):
def define_schema(cls): def define_schema(cls):
return io.Schema( return io.Schema(
node_id="RTDETR_detect", node_id="RTDETR_detect",
display_name="RT-DETR Detect", display_name="Run Real-Time Detection (RT-DETR)",
category="image/detection", category="image/detection",
search_aliases=["bbox", "bounding box", "object detection", "coco"], search_aliases=["bbox", "bounding box", "object detection", "coco"],
inputs=[ inputs=[

View File

@ -264,7 +264,7 @@ class SAM3_VideoTrack(io.ComfyNode):
def define_schema(cls): def define_schema(cls):
return io.Schema( return io.Schema(
node_id="SAM3_VideoTrack", node_id="SAM3_VideoTrack",
display_name="SAM3 Video Track", display_name="Run SAM3 Video Track",
category="image/detection", category="image/detection",
search_aliases=["sam3", "video", "track", "propagate"], search_aliases=["sam3", "video", "track", "propagate"],
inputs=[ inputs=[

View File

@ -1,3 +1,3 @@
# This file is automatically generated by the build process when version is # This file is automatically generated by the build process when version is
# updated in pyproject.toml. # updated in pyproject.toml.
__version__ = "0.24.0" __version__ = "0.25.0"

45
main.py
View File

@ -55,7 +55,11 @@ if __name__ == "__main__" and args.debug_hang:
import comfy_aimdo.control import comfy_aimdo.control
if enables_dynamic_vram(): if enables_dynamic_vram():
comfy_aimdo.control.init() try:
comfy_aimdo.control.init(simple_vram_headroom=None if args.reserve_vram is None else int(args.reserve_vram * 1024 ** 3))
except TypeError:
# comfy-aimdo 0.4.9 protocol.
comfy_aimdo.control.init()
if os.name == "nt": if os.name == "nt":
os.environ['MIMALLOC_PURGE_DELAY'] = '0' os.environ['MIMALLOC_PURGE_DELAY'] = '0'
@ -231,23 +235,30 @@ import comfy.model_patcher
if args.enable_dynamic_vram or (enables_dynamic_vram() and comfy.model_management.is_nvidia() and not comfy.model_management.is_wsl()): if args.enable_dynamic_vram or (enables_dynamic_vram() and comfy.model_management.is_nvidia() and not comfy.model_management.is_wsl()):
if (not args.enable_dynamic_vram) and (comfy.model_management.torch_version_numeric < (2, 8)): if (not args.enable_dynamic_vram) and (comfy.model_management.torch_version_numeric < (2, 8)):
logging.warning("Unsupported Pytorch detected. DynamicVRAM support requires Pytorch version 2.8 or later. Falling back to legacy ModelPatcher. VRAM estimates may be unreliable especially on Windows") logging.warning("Unsupported Pytorch detected. DynamicVRAM support requires Pytorch version 2.8 or later. Falling back to legacy ModelPatcher. VRAM estimates may be unreliable especially on Windows")
elif comfy_aimdo.control.init_devices(d.index for d in comfy.model_management.get_all_torch_devices()):
if args.verbose == 'DEBUG':
comfy_aimdo.control.set_log_debug()
elif args.verbose == 'CRITICAL':
comfy_aimdo.control.set_log_critical()
elif args.verbose == 'ERROR':
comfy_aimdo.control.set_log_error()
elif args.verbose == 'WARNING':
comfy_aimdo.control.set_log_warning()
else: #INFO
comfy_aimdo.control.set_log_info()
comfy.model_patcher.CoreModelPatcher = comfy.model_patcher.ModelPatcherDynamic
comfy.memory_management.aimdo_enabled = True
logging.info("DynamicVRAM support detected and enabled")
else: else:
logging.warning("No working comfy-aimdo install detected. DynamicVRAM support disabled. Falling back to legacy ModelPatcher. VRAM estimates may be unreliable especially on Windows") try:
aimdo_initialized = comfy_aimdo.control.init_devices((d.index, int(args.vram_headroom * 1024 ** 3)) for d in comfy.model_management.get_all_torch_devices())
except TypeError:
# comfy-aimdo 0.4.9 protocol.
aimdo_initialized = comfy_aimdo.control.init_devices(d.index for d in comfy.model_management.get_all_torch_devices())
if aimdo_initialized:
if args.verbose == 'DEBUG':
comfy_aimdo.control.set_log_debug()
elif args.verbose == 'CRITICAL':
comfy_aimdo.control.set_log_critical()
elif args.verbose == 'ERROR':
comfy_aimdo.control.set_log_error()
elif args.verbose == 'WARNING':
comfy_aimdo.control.set_log_warning()
else: #INFO
comfy_aimdo.control.set_log_info()
comfy.model_patcher.CoreModelPatcher = comfy.model_patcher.ModelPatcherDynamic
comfy.memory_management.aimdo_enabled = True
logging.info("DynamicVRAM support detected and enabled")
else:
logging.warning("No working comfy-aimdo install detected. DynamicVRAM support disabled. Falling back to legacy ModelPatcher. VRAM estimates may be unreliable especially on Windows")
def cuda_malloc_warning(): def cuda_malloc_warning():

View File

@ -1 +1 @@
comfyui_manager==4.2.1 comfyui_manager==4.2.2

View File

@ -20,6 +20,8 @@ from PIL.PngImagePlugin import PngInfo
import numpy as np import numpy as np
import safetensors.torch import safetensors.torch
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), "comfy"))
import comfy.diffusers_load import comfy.diffusers_load
import comfy.samplers import comfy.samplers
import comfy.sample import comfy.sample
@ -2293,9 +2295,6 @@ async def init_external_custom_nodes():
Returns: Returns:
None None
""" """
# TODO: remove at some point when custom nodes don't break.
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), "comfy"))
base_node_names = set(NODE_CLASS_MAPPINGS.keys()) base_node_names = set(NODE_CLASS_MAPPINGS.keys())
node_paths = folder_paths.get_folder_paths("custom_nodes") node_paths = folder_paths.get_folder_paths("custom_nodes")
node_import_times = [] node_import_times = []

View File

@ -896,11 +896,6 @@ components:
additionalProperties: true additionalProperties: true
description: The workflow graph to execute description: The workflow graph to execute
type: object type: object
prompt_id:
description: Optional client-supplied job id. Must be a UUID in canonical lowercase hyphenated form; it is echoed back in the response. Omitted or null means the server generates one.
format: uuid
nullable: true
type: string
workflow_id: workflow_id:
description: UUID identifying the cloud workflow entity to associate with this job description: UUID identifying the cloud workflow entity to associate with this job
type: string type: string
@ -1800,7 +1795,9 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/ErrorResponse' $ref: '#/components/schemas/ErrorResponse'
description: Invalid request (no fields provided) description: |
Invalid request — no fields provided, or `preview_id` is the zero UUID
(`INVALID_PREVIEW_ID`).
"401": "401":
content: content:
application/json: application/json:
@ -1812,7 +1809,10 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/ErrorResponse' $ref: '#/components/schemas/ErrorResponse'
description: Asset not found description: |
Asset not found — returned both when the asset being updated does
not exist and when `preview_id` does not reference an asset
accessible to the caller.
"500": "500":
content: content:
application/json: application/json:
@ -3050,6 +3050,12 @@ paths:
schema: schema:
$ref: '#/components/schemas/PromptErrorResponse' $ref: '#/components/schemas/PromptErrorResponse'
description: Payment required - Insufficient credits description: Payment required - Insufficient credits
"413":
content:
application/json:
schema:
$ref: '#/components/schemas/PromptErrorResponse'
description: Workflow JSON too large
"429": "429":
content: content:
application/json: application/json:

View File

@ -1,6 +1,6 @@
[project] [project]
name = "ComfyUI" name = "ComfyUI"
version = "0.24.0" version = "0.25.0"
readme = "README.md" readme = "README.md"
license = { file = "LICENSE" } license = { file = "LICENSE" }
requires-python = ">=3.10" requires-python = ">=3.10"

View File

@ -1,6 +1,6 @@
comfyui-frontend-package==1.45.15 comfyui-frontend-package==1.45.15
comfyui-workflow-templates==0.9.98 comfyui-workflow-templates==0.10.0
comfyui-embedded-docs==0.5.3 comfyui-embedded-docs==0.5.4
torch torch
torchsde torchsde
torchvision torchvision
@ -23,7 +23,7 @@ SQLAlchemy>=2.0.0
filelock filelock
av>=16.0.0 av>=16.0.0
comfy-kitchen==0.2.10 comfy-kitchen==0.2.10
comfy-aimdo==0.4.9 comfy-aimdo==0.4.10
requests requests
simpleeval>=1.0.0 simpleeval>=1.0.0
blake3 blake3