[pull] master from comfyanonymous:master - #106
Open
pull[bot] wants to merge 4432 commits into
Open
Conversation
These were alll non-dynamic (some non-ModelPatcher) code path calling FreeMemory for management requiring up-front memory freeing. Convert it to dynamic to avoid legacy free behaviour mixing into otherwise dynamic workflows.
Some long running chaos testing on a 512GB RAM RTX6000 pro showed that this is a little bit too low for common template workflows switching around. The original number was just a guess from me, so go with the scientific result instead.
…#15075) Signed-off-by: bigcat88 <bigcat88@icloud.com>
Signed-off-by: bigcat88 <bigcat88@icloud.com>
…from the comfy-api (#15091) Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
* [Partner Nodes] feat(Recraft): add V4.1 models and V4 image edit nodes Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] chore(Recraft): change old nodes names to contain "V3" Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Recraft): remove v4 model from the image edit nodes; fix the default "strength" value Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] chore(Recraft): remove new image edit nodes Signed-off-by: bigcat88 <bigcat88@icloud.com> --------- Signed-off-by: bigcat88 <bigcat88@icloud.com>
…er access for dataset stuff. (#14807)
…viewPointCloud outputs (#16038)
…node (#16041) * [Partner Nodes] feat(MiniMax): add H3 Max option to H3 reference-to-video node Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
The frontend's partner-nodes run gate (Comfy-Org/ComfyUI_frontend#15248) reads this key from /features as its kill switch. Registering it makes --feature-flag partner_run_gate_enabled=false coerce to a real boolean; unregistered keys pass through as strings, and the string "false" is truthy to the frontend, so the switch would silently not work.
ComfyUI Desktop has proven to be the easiest way to install and manage local ComfyUI instances. We will still maintain a portable version for now but this change is to nudge the community in using Desktop instead.
…le node (#16043) Signed-off-by: bigcat88 <bigcat88@icloud.com> Co-authored-by: Purz <97489706+purzbeats@users.noreply.github.com>
…ng parameters and six new nodes (#16060) * [Partner Nodes] fix(Tripo): keep the real output format for quad meshes and converted models Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Tripo): allow face_limit up to 2,000,000 on Image and Multiview nodes Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Tripo): disable PBR when texture is off instead of silently generating textures Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Tripo): price badges charge texture add-ons only when textured and add the 8K texture tier Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] feat(Tripo): texture node gains model version, style image and single/multiview reference guidance, always sends texture=true and keeps the FBX Tripo returns for quad and FBX-imported sources Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] feat(Tripo): rig node gains model version, rig type with automatic rig check, Mixamo spec and FBX output Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] feat(Tripo): retarget node gains the v1.0 biped preset library, output format, geometry/in-place options and FBX output, and refuses v1.0 mixamo rigs up front Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] feat(Tripo): add Rig Check, Segment Model, Complete Mesh Parts and Retopology nodes Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] feat(Tripo): add Image to Multiview and Edit Multiview nodes Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] feat(Tripo): texture node accepts segmented models with part_names and refuses image-less sources without a prompt up front Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] chore(Tripo): stop offering the retired v1.4-20240625 model version and stop sending the ignored style parameter Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] feat(Tripo): Multiview to Model honours quad again; smart_low_poly and auto_size on the Text, Image and Multiview to Model nodes Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Tripo): Text to Model defaults to v3.1; negative prompts over 255 characters, blank prompts and seeds outside Tripo's int32 range are rejected before any upload Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Tripo): convert node sends the animation and bake flags it shows, real export orientations, bake_scale preset, 8K texture size and a non-zero scale_factor Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] feat(Tripo): P1 nodes gain the 8K extreme texture tier and warn that meshopt output cannot be previewed Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Tripo): fail loudly when Tripo returns a format other than GLB or FBX Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Tripo): drop preset:biped:press-up, the one biped preset Tripo rejects Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] chore(Tripo): explain in the auto_size tooltip that Tripo stores the real-world size as a scene transform for textured models Signed-off-by: bigcat88 <bigcat88@icloud.com> --------- Signed-off-by: bigcat88 <bigcat88@icloud.com>
…video and first-last-frame nodes (#16094) Signed-off-by: bigcat88 <bigcat88@icloud.com> Co-authored-by: Purz <97489706+purzbeats@users.noreply.github.com>
Aimdo 0.5.2 fixes a shot-flag leak im aimdo that would silence the abort cleanup process for non-first steps.
…ws on Comfy Cloud GPUs (#15935) * feat(api-nodes): add Comfy Cloud partner nodes Ports the Comfy Cloud provider client from #15282, trimmed to the surface we intend to ship and with three fixes. - Ship 4 capability nodes (text-to-image, text-to-video, image-to-video, image-edit) plus 7 named workflows; drop the other 16 POC classes. The capability aliases resolve backend-side, so the model behind a shape can be swapped without a client release. - Pin output-URL validation to the backend's bucket allowlist rather than accepting any bucket on storage.googleapis.com. - Name the three timeouts (platform run ceiling, poll budget, output download) and poll under an explicit budget instead of the stock 40-minute default. - Narrow the workflow contract to the shipped set. Tests: 67 pass across tests-unit/comfy_api_nodes_test. * feat(api-nodes): add the Z-Image Turbo Comfy Cloud node Z-Image Turbo is the most selected Desktop template by a wide margin (168k selections in 90 days, 34% ahead of the next), and it was not in the curated set. At 8 steps it also finishes far quicker than the existing text-to-image pipeline, which matters on a surface billed per GPU-second. * feat(api-nodes): add Flux 2, Ideogram 4, LongCat and Capybara cloud nodes Four new OSS model families, each biased to the newest shipped templates and each validated by running its graph on a real GPU before the manifest was frozen. Duplicates were deliberately left out: Krea 2 Turbo and Z-Image Turbo int8 are models already curated at a different quantisation, and shipping them would give a user two nodes that do the same thing. * fix(api-nodes): accept the partner-node asset buckets for Comfy Cloud outputs Staging and prod point PARTNER_NODES_ASSET_STORAGE_BUCKET_NAME, the key comfy-cloud shares with the other partner providers, at partner-nodes-assets and partner-nodes-assets-staging. The node accepted only comfy-cloud-assets*, so an output from either would have been rejected after the GPU had already run and the caller had been billed. Both bucket families are ours; what this list defends against is an output URL naming a bucket we do not own, and the signed-URL and host checks are unchanged. A test pins the set, because the matching list lives in cloud and this half ships on the ComfyUI release train, so a one-sided widening would persist until the next release. * fix(api-nodes): quote the rate Comfy Cloud actually charges The badge advertised $0.001295/GPU-second while Metronome charged $0.00185, so every run under-quoted the user by about 43%. Two live runs billed at the higher rate, and the live rate card confirms it: the 'GPU Hour Usage' metric sums gpu_seconds and prices per gpu_type, with rtx_pro_6000 at 0.185 cents per GPU-second. 0.001295 was a hardcoded constant with no counterpart anywhere in cloud, so it was never anchored to the rate card. This one is not either, which is why the comment says so plainly: nothing links them, and a pricing change has to be mirrored here by hand and ride the release train. * fix(api-nodes): show a real message when Comfy Cloud is unavailable Two problems met on the same path. comfy-api's error envelope is flat, {"error": code, "message": text}, but _friendly_http_message only unwrapped a NESTED error object, so the message was skipped and the user was shown the raw JSON of the whole body. And 503 is in _RETRY_STATUS, so a provider that is switched off was retried three times with backoff before producing that. The user pressed Run and waited through the backoff to read a payload. Now the flat envelope is surfaced verbatim, which also fixes every other comfy-api error a node can hit, and a refusal carrying a known terminal code short-circuits the retry. A 503 without such a code is still transient and still retried. * refactor(api-nodes): name every Comfy Cloud node for its provider Twelve of the sixteen nodes carried a bare model name, so a user searching "flux" saw the paid cloud node and the free local one side by side with nothing on the name to tell them apart. Prefix them all, matching the convention every other partner uses (Bria FIBO Image Edit, ElevenLabs Text to Speech), and drop the task suffix where the model only ships one. node_id is unchanged: it is the class_type saved inside user workflows. * refactor(api-nodes): describe what each Comfy Cloud node actually does Sixteen nodes shared three generic bodies ("Runs this image workflow on Comfy Cloud"), so the tooltip never said which model runs or why you would pick one node over the one beside it. Each node now describes its own graph: the model, the sampler budget where it drives cost, and the constraints worth knowing before you wire it up (Krea 2 bakes in the darkbrush LoRA, LTX cannot exceed the supplied audio, MiniMax generates its soundtrack in the same pass). The rate suffix stated one number five ways over two lines. It now states it once and answers the question a local user is actually asking, which is whether they need a Cloud plan. It stays in the description rather than moving to the price badge because that badge only renders on Nodes 2.0, and a plain local install still defaults to the classic canvas. Drops COMFY_CLOUD_GPU_HOUR_USD and COMFY_CLOUD_GPU_HOUR_CREDITS, which after this have no callers outside the test asserting them. * fix(api-nodes): apply the Comfy Cloud bucket allowlist to the normalized path Three findings from review, all in the client half. The bucket allowlist read the first segment of the path as written, but a client resolves dot segments before it sends the request. So .../comfy-cloud-assets/../other-bucket/output.png advertised an allowed bucket to the check and fetched from another one on the wire, which is the whole point of pinning the bucket. The proxy branch already normalized; the signed-URL branch now does too, and two traversal cases join the reject parametrize. _with_input_sockets clears socketless on every widget, so a graph can link any node output into prompt, instruction or negative_prompt. A linked int reached value.strip() and raised AttributeError instead of naming the field the way the BOOLEAN, INT and FLOAT branches all do. _UINT32_MAX had no references, and the oversized-image test only ever reached the per-side branch: (1, 8193, 1, 3) is 8193 pixels total, so the megapixel limit was never exercised even though the shared error text made the assertion pass. Left alone deliberately: reparenting the four video nodes onto _ComfyCloudWorkflowNode is a redesign of the execution path this port is meant to carry across unchanged; bounding decoded audio by its peak float32 representation rather than its raw size is a real tightening but sits in shared decode used by every API node, and the guard this PR adds is already a bound where there was none; and exempting disk-backed file handles from the in-memory download cap changes behaviour that a test here asserts on purpose, with no caller passing such a handle today. * refactor(api-nodes): cut the Comfy Cloud surface nothing here uses A leanness pass ahead of core review. No behaviour change to the execution path, polling, cancel wiring, auth or the output-URL allowlist. Shared util/ narrowed to what this feature requires. Three of the four shared files were carrying changes Comfy Cloud does not need, and two of them would have altered behaviour for every other API node: - util/conversions.py and util/__init__.py revert entirely. The 256 MiB decoded-audio bound guarded audio_bytes_to_audio_input, which this PR never calls but elevenlabs, fishaudio, sonilo, heygen and bytedance all do; it would have started rejecting large decodes for them. The bytes | BytesIO widening existed only for download_url_to_audio_input. - download_url_to_audio_input is removed. It had no caller anywhere, having come across with the port for the audio nodes this PR drops. This was disclosed as a loose end in the PR body. - The 512 MiB in-memory download cap is removed for the same reason: not required here, and every existing BytesIO download would have gained a new failure mode from an unrelated PR. - The can_reset_sink guards are removed as dead defence. Every sink in the tree is a path, a BytesIO or an open file, all of them resettable. - allow_redirects comes off download_url_to_file_3d, which no node here calls. What stays in util/ is exactly what the feature needs, and each now says why in the diff: allow_redirects on the two download helpers Comfy Cloud uses (a redirect would fetch from a bucket _validated_output_url never vetted), the matching status >= 300 check so a refused redirect fails instead of writing the redirect body as the image, the BytesIO reset before a retry so a mid-stream failure does not concatenate two bodies, and client.py's flat-envelope message and terminal-refusal no-retry, which the kill switch depends on. Request model narrowed to the shipped inputs. ComfyCloudWorkflowInputs declared 43 fields; 15 are set by the 16 nodes. The other 28 are the POC's dropped audio and 3D nodes. Same argument the PR already makes for narrowing ComfyCloudWorkflow. _TEXT_LIMITS loses the 7 keys that name no input id on any shipped node. Node boilerplate collapsed, not restructured. Five nodes differed only in workflow id, name and blurb, each repeating an identical define_schema and execute; they now subclass _ComfyCloudPromptSeedImageNode and declare nothing else. The three copies of the IO.Schema construction collapse into _cloud_schema, which also makes cls.category load-bearing instead of being set and ignored. The four video nodes keep their own base and _run_video_workflow, unchanged. Also: the bucket-allowlist comment pointed at server/middleware/comfy_cloud.go for a set declared in config/config.go; the two MiniMax nodes repeated the eight aspect ratios inline, in a different order from _ASPECT_RATIOS but the same set, and now share it; the best-effort cancel says why it swallows rather than using a bare pass; the video section had lines up to 353 chars against a ~120 norm elsewhere in comfy_api_nodes. Tests: the two removed util bounds take their tests with them; the retry reset keeps its coverage and the refused redirect gains some. Test names carrying POC vocabulary ("legacy nodes" for what the PR calls the primary capability surface, IMAGE_POC_NODES) are renamed for what they cover, and Z-Image Turbo joins the parametrized set so the new shared base is exercised end to end. tests-unit 1547 passed / 10 skipped, ruff clean, pylint 10.00/10. * fix(api-nodes): let the Wan 2.2 graph supply its own negative prompt The negative_prompt widget shipped with the default "graph tested Chinese quality negative". That is a note describing a value, not the value. It is not only cosmetic. The backend holds the real one -- comfyCloudWan22DefaultNegativePrompt in comfy_cloud_workflows.go, the 30-term Chinese quality negative the frozen graph was tuned with -- and binds it to node 78 only when the caller supplies none: negative := comfyCloudWan22DefaultNegativePrompt if inputs.NegativePrompt != nil { negative = *inputs.NegativePrompt } negative_prompt is a required argument of execute() and was always sent, so that branch was unreachable from ComfyUI and every default run replaced a 30-term quality negative with a five-word English placeholder. CodeRabbit flagged the placeholder and proposed default="". That does not fix it: "" is still non-nil on the wire, so the graph default stays unreachable and every default run submits an empty negative instead. Default to empty AND omit the field when it is blank, so an untouched widget reaches the backend as absent and the graph's own negative applies. A typed value still wins. Nothing is mirrored client-side, so there is no second copy of a frozen-graph constant to drift -- the failure mode this PR already calls out for the price badge. Verified against cloud 6341e21e9c: the manifest's node 78 text and the Go constant are the same string. tests-unit/comfy_api_nodes_test 80 passed, full tests-unit 1550 passed / 10 skipped, ruff clean, pylint 10.00/10. * refactor(api-nodes): cut the Comfy Cloud comments back to the repo norm The file ran at 6.2% comment lines against 0.1-1.0% for every other partner node. What survives is what cannot be read off the code: the bucket set's coupling to cloud's config.go, the price being a hand-maintained mirror of the rate card, why the output path is normalised before the allowlist is applied, and why negative_prompt is omitted rather than sent empty. * refactor(api-nodes): stop requiring response fields the node never reads polling_url and cancel_url are declared on the generate response but nothing reads them: _task_endpoints derives both paths from task_id, which is what keeps a backend-supplied URL from being followed. Requiring them could only ever fail a call over a field we ignore, so they are optional now. Drops output_urls, which nothing reads at all. * refactor(api-nodes): put the task back in every Comfy Cloud node name Dropping the task where a model shipped only one node left names like "Comfy Cloud Krea 2" and "Comfy Cloud LongCat", which say nothing about what the node does. Every other provider with a large surface keeps it: Kling 3.0 Image to Video, Wan 2.7 Text to Video, ByteDance First-Last-Frame to Video. Also adopts the house spellings for the shapes that have one: First-Last-Frame to Video rather than First & Last Frame, Upscale Image rather than Upscale, and "with Audio" for the MiniMax pair, which is how Kling marks the same thing. node_id is untouched. * refactor(api-nodes): give the workflow ids a shape that can outlive v1 The ids are the wire contract and they freeze the moment a release carries them: an old client keeps sending the old string forever, and cloud deploys independently of the release train, so renaming one later is a break rather than a refactor. The old set could not survive that. "text-to-image" claimed a generic name unqualified; "creative-image" and "image-audio-performance" were template filenames rather than descriptions; "2-3", "0-1" and "2-2" mangled version numbers; and "image.qwen-image-edit-2511.v1" stuttered. Now <model>/<task>, mirroring the node display names so the two cannot drift: "Comfy Cloud Flux 2 Text to Image" is flux-2/text-to-image. The four aliases become default/*, which is the part that carries meaning: the prefix says the model behind the id can change while the id does not. Nothing in the old names said so, and that was the most dangerous ambiguity in the set. Drops the .v1 suffix. The id is frozen either way, so a pre-registered v1 buys nothing; an incompatible change needs a new id regardless. * feat(api-nodes): expose the rest of each Comfy Cloud pipeline's controls The nodes showed a prompt, sometimes a seed, and hid everything the curated graph could actually do. Flux 2 has a turbo switch and two step counts, Ideogram 4 has its own rendering-speed presets, LongCat and Capybara have negative prompts, Wan 2.2 and MiniMax H3 have a resolution stage, SeedVR2 has a seed and four colour-correction modes. All of it is on the node now. The split is what keeps the node readable: the first view stays the controls someone actually reaches for, and the sampler dials sit behind the advanced flag. Aspect ratio is a dropdown even where the graph takes a width and a height, because the ratio is the choice and the pixels are this pipeline's own render size. Seeds now start at 42 everywhere. They were 0 on the image nodes and fifteen-digit constants on the video ones, which read as meaningful and was not. * feat(api-nodes): cut the shipped set to seven nodes Matches the registry: four capability nodes, plus MiniMax H3 text-to-video and Z-Image Turbo (the only two with real Desktop template demand) and Flux 2, which is what exercises the turbo switch and the advanced input split. The nine removed nodes keep their node_id and workflow id in history, so re-adding one is a revert rather than a redesign. * feat(api-nodes): give Flux 2 a LoRA picker and both image nodes a model picker The advanced section of the two controlled image nodes tuned the schedule but never the weights, so Flux 2 could only ever run the one Turbo LoRA and Z-Image Turbo the one checkpoint. Both pickers are combos of KEYS, not filenames. Cloud maps each key to the file it holds, which is what keeps the picker from becoming a free-text weight path the caller could point anywhere. - Flux 2 gains `lora` (12 options: two turbo accelerators plus ten styles) and `model` (fp8 or bf16 dev). The LoRA is loaded only while turbo is on, so turbo off is still the no-LoRA dev pass; the tooltip says so, and says a style entry wants turbo_steps raised. - Z-Image Turbo gains `model` across its three distilled precisions. Both are advanced, so the plain view is unchanged at four controls and five. * feat(api-nodes): give the two default image nodes a speed switch and weight picker The capability nodes showed a prompt and a seed and hid two controls their pipelines already carried: a speed/quality switch, and behind it the weights. The pickers are combos of KEYS naming the TRADE-OFF, not the model. A default/* id is a pointer whose model is re-pointed over time, and a saved graph stores the key, so the key has to outlive the move: fast, balanced and quality do, a model name would not, and a test holds that line. - Text to Image gains turbo in the plain view, the way Flux 2 has it, plus model across two precisions and lora across two accelerators, both advanced. The LoRA only matters while turbo is on and the tooltip says so. - Image Edit gains turbo and model across three precisions. That graph has no LoRA to point at, so there is no lora input, and its tooltip is honest that the switch is a bare short schedule with nothing to soften the loss. - Text to Video and Image to Video are unchanged. Their pipelines have no interchangeable sibling weight. Plain view stays at three controls and four. * feat(api-nodes): add the default-pointer pickers and name pinned weights fully Adds model/lora/turbo controls to the two default image pointers, and renames the pinned pickers' options from "bf16"/"dev-fp8" to the full model names, which is what a local subgraph picker shows for the same weight. The default/* options stay trade-off tiers rather than model names, since those ids re-point and a saved graph stores the option. * refactor(api-nodes): drop the four capability nodes Mirrors the registry. Tests that used them as generic stand-ins now run against a shipped node and drive it from its own schema defaults, so the next workflow added does not break them again. Two tests went rather than being contorted: the batch-rejection guard, which no shipped workflow can reach now that nothing takes an IMAGE input, and the key-format assertion, which contradicted naming the pickers after their weights. What protects that path is the server-side allowlist, which the Go side tests. * feat(api-nodes): let a Comfy Cloud node return audio or a 3D model Output was a boolean, image-or-video, which blocked the 3D and audio workflows in the new catalog. It is now an explicit kind with a table mapping each to its schema output and its runner. The download helpers already existed; download_url_to_file_3d just could not refuse a redirect, so allow_redirects is threaded through it. That matters: the bucket pin decides where output bytes may come from, and following a redirect hands that decision back to the server we just checked. A test asserts every kind passes allow_redirects=False, and it fails if any one stops. * feat(api-nodes): add the Mage-Flow and MiniMax Music 3 Comfy Cloud nodes Two Mage-Flow text-to-image nodes, full and turbo, and the first node to use the audio output kind: MiniMax Music 3 text to audio. Each exposes every widget its frozen graph carries, because control is the reason to reach for a pipeline like this rather than a hosted endpoint. The plain view keeps the prompt, the framing, the seed and one quality-against- speed switch; the rest is advanced. Mage-Flow frames itself with a ratio and a pixel budget rather than a width and a height, because its graph sizes through a resolution selector. MiniMax Music 3 takes lyrics as a second prompt, caps length with max_duration, and switches between a tiled and a single-pass waveform decode. The two Mage-Flow nodes share a base class: the same pipeline at two schedule lengths, differing only in step and cfg defaults and which checkpoints load. Its seed is capped at int64 rather than uint64, which is what the music graph's seed node accepts. Sampler and scheduler are three entries each rather than ComfyUI's 45 and 9: the dropdowns list only options executed against these graphs on a cloud GPU, since cloud rejects a key its allowlist does not hold. * feat(api-nodes): add the three MiniMax H3 video Comfy Cloud nodes Image to Video takes a first frame and an optional last frame, running fl2va between the two keyframes when both are connected. Video Continuation takes the closing frame of a previous clip so several can be chained into a longer sequence. Reference to Video takes up to four reference images through an autogrow input, numbered by connection order so the prompt can address them as <Picture 1> upwards. All three open on the headline controls -- media, prompt, aspect ratio, resolution, duration and seed, plus reference-to-video's ref_image_size quality-against-speed switch -- and keep steps, denoise and the text encoder picker behind the advanced flag. The turbo LoRA branch these templates carry is not exposed: its candidate weights have catalog entries but no bytes in the mirror, so cloud's frozen graphs leave the branch out until they are uploaded. * fix(api-nodes): give MiniMax H3 duration whole seconds The graph quantises length to 17-frame steps at 24fps, so a 0.01s step offered 1001 settable values that collapsed to 15 outcomes, and both ends escaped their own bounds (5.00 -> 5.17s, 15.00 -> 15.08s). Only 8.00 was honest. An int slider matches Kling and LTXV, the two other video nodes here, and reaches 11 of those 15 lengths; the four it drops are decimals nobody would type. Server-side stays FLOAT: node 132 is a PrimitiveFloat and an integer decodes into it cleanly, so no manifest or digest changes. * refactor(api-nodes): rename the MiniMax H3 video nodes for what they do Per review. The node with two keyframes was called Image to Video and the single-keyframe node was called Video Continuation, which reads backwards: Image to Video -> First-Last Frame to Video Video Continuation -> Image to Video Text to Video with Audio -> Text to Video Class names, workflow ids and descriptions all follow, so class_type, id and display name cannot drift. "with Audio" goes because every H3 video node produces sound; naming it on one implied the others do not. Also reorders the shared inputs to seed, aspect ratio, shot shape, then sampling, then weights, and applies the same order to every node so moving between them does not move the knobs. Renaming a class_type is free only until a release carries it. * feat(api-nodes): expose sampler, scheduler and text encoder on the Cloud nodes Per review. Mirrors the cloud bindings: Flux 2 sampler + text_encoder Z-Image Turbo sampler + scheduler + text_encoder MiniMax H3 sampler + scheduler on the three registry-backed nodes Flux 2 has no scheduler to expose; its tooltip says why so it does not read as an omission. Not added: the one-entry VAE pickers and an H3 model picker. Each has a single valid weight, so the control cannot change the output, and an input is far harder to remove than to add. Text to Video still runs the legacy builder and keeps its smaller surface until that is migrated. * feat(api-nodes): give Text to Video the same surface as its siblings It was the only H3 node still built from its own input helper, so it offered 6 inputs where the others offered 11 or 12. Moves it onto _minimax_h3_inputs and re-homes the class beside the other H3 nodes so it sits after the shared helper it now uses. Adds denoise, sampler, scheduler and text_encoder to match, and retires the now-unused _minimax_inputs helper. * refactor(comfy-cloud): simplify node surfaces per design review Applies alexisrolland's review. Categories become comfy cloud/{image, video,audio}; widget order is now prompt, negative_prompt, seed, aspect_ratio across every node; and the weights, sampler and step pickers users should not have to touch are gone. Removing a widget is behaviour-preserving here, verified against the frozen graphs rather than assumed: every value dropped is already baked into the manifest at the same default the node was sending. z-image bakes steps 8, shift 3, res_multistep/simple and z_image_turbo_bf16; flux-2 bakes euler, guidance 4, flux2_dev_fp8mixed and the turbo LoRA at strength 1; mage-flow and mage-flow-turbo each bake their own steps (30/4), cfg (5/1) and checkpoint, which is why the two variants no longer need per-subclass defaults at all. Also: negative_prompt and audio_quality are no longer advanced (a second prompt and a headline output choice, not tuning dials); tiled_decode and the tile controls are gone from Music 3 as lower-end-hardware knobs that do not apply on cloud; seed moves after the lyrics prompt. Constants left with no caller are deleted with their widgets. NOT applied, and answered on the PR: megapixels on Flux 2 and Z-Image. Only mage-flow has a megapixels binding on the cloud side; those two graphs size themselves from explicit width/height, so the widget would need a cloud manifest change to do anything. * feat(comfy-cloud): mark the nodes BETA in name and description The curated workflow set is expected to change: a node can gain or lose options, and a workflow can be retired. Say so on the node rather than only in release notes. Suffix, not prefix. The add-node menu and node search sort alphabetically, so a leading "[BETA]" would file all nine under "[" instead of under their model, and someone searching "flux" would no longer see the node next to the local one it sits beside. The description carries the same notice and leads with it, because the price badge only renders on Nodes 2.0 and a plain local install still defaults to the classic canvas, where the description is all the user gets. Free to remove later: display_name is not stored in a saved graph. node_id and the input names are the parts that are permanent. * fix(comfy-cloud): accept the first-last-frame workflow id (BE-12049) ComfyCloudMiniMaxH3FirstLastFrameToVideoNode submits "minimax-h3/first-last-frame-to-video", but the ComfyCloudWorkflow union still named the id by its old name, "minimax-h3/video-continuation". The union is what pydantic validates the outgoing request against, so that one node failed with a ValidationError on Run while the other eight worked. Found by QA on staging. A rename that reached the node and the server registry but not the client union. Why nothing caught it: the only parity check read workflow ids out of CONTROLLED_IMAGE_NODES, which covers the two image nodes, and asserted a subset. Video and audio ids were never compared, and a union entry naming no node was invisible in either direction. Replaced with an exact two-way comparison between the ids the module names and the ids the union declares. Ids are matched by shape rather than by call site, because the three ways a node reaches its id differ: the H3 nodes pass a literal, Mage Flow passes a ClassVar, and Music 3 goes through the _OUTPUT_KINDS dispatch table. Verified the test fails on the original bug before fixing it. * Apply suggestion from @alexisrolland * docs(comfy-cloud): the node rate is the list price, never a promo ComfyUI is pulled rather than pushed, so a user keeps whatever value they last pulled. A promotional rate shipped in this constant does not expire when the promotion does: the rate card returns to list, that user's node still quotes the discount, and they are charged more than they were shown, indefinitely and invisibly to us. Quoting above the charged rate is the safe direction. Quoting below it is the failure this comment exists to prevent, and it is the same shape as the 43% under-quote this file already corrected once. Records why the weekend promo runs in Metronome only. * chore(comfy-cloud): keep sending caption_cfg after its widget was removed Alexis's suggestion removed the caption_cfg widget. The value is still sent, deliberately, because this one differs from every other control dropped in this pass: the node default and the frozen graph DISAGREE. The manifest bakes cfg_scale 1.7 at node 37:13 while the node has always sent 1.5, so going silent would change what the GPU runs rather than preserve it, and every run QA'd so far used 1.5. Reconciling the two is a manifest decision rather than a node one. * Use resolution selectors for Cloud image nodes Amp-Thread-ID: https://ampcode.com/threads/T-01a06d0c-5a85-77c9-9753-cd5bb340998e Co-authored-by: Amp <amp@ampcode.com> * fix(comfy-cloud): the GPU rate is 0.001295, not 0.00185 Reverts a wrong "correction". An earlier commit changed the advertised rate from 0.001295 to 0.00185, read off rtx_pro_6000's Metronome rate card entry. The card entry is not what this path charges, and the node has been over-quoting every run by about 43% since. Verified by dividing a real billed event rather than reading a card: credits_used 1.98 / gpu_seconds 7.244173 = 0.273323 credits/GPU-second 0.273323 / 211 credits-per-USD = $0.0012954/GPU-second Which is 0.001295, the original value. Display precision goes to 6dp so the quote reads $0.001295 rather than rounding to $0.00129 and being wrong in the other direction. The comment now says to verify against a charge, not the rate card, because that is the mistake that produced this. Note the live rate is currently HALVED for a promotion. That number is deliberately not here: this constant is the list price, for the pull-based reason recorded above it. * Update nodes * Fix linting * Disable unit test for disabled nodes --------- Co-authored-by: Deep Mehta <deep@comfy.org> Co-authored-by: Alexis Rolland <alexisrolland@hotmail.com> Co-authored-by: Amp <amp@ampcode.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )