mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-01-10 06:10:50 +08:00
add strict typing for JSONata rules
This commit is contained in:
parent
b0f98297da
commit
c431de7367
@ -1258,9 +1258,24 @@ class PriceBadgeDepends:
|
||||
if not isinstance(self.input_groups, list) or any(not isinstance(x, str) for x in self.input_groups):
|
||||
raise ValueError("PriceBadgeDepends.input_groups must be a list[str].")
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
def as_dict(self, schema_inputs: list["Input"]) -> dict[str, Any]:
|
||||
# Build lookup: widget_id -> io_type
|
||||
input_types: dict[str, str] = {}
|
||||
for inp in schema_inputs:
|
||||
input_types[inp.id] = inp.get_io_type()
|
||||
|
||||
# Enrich widgets with type information, raising error for unknown widgets
|
||||
widgets_data: list[dict[str, str]] = []
|
||||
for w in self.widgets:
|
||||
if w not in input_types:
|
||||
raise ValueError(
|
||||
f"PriceBadge depends_on.widgets references unknown widget '{w}'. "
|
||||
f"Available widgets: {list(input_types.keys())}"
|
||||
)
|
||||
widgets_data.append({"name": w, "type": input_types[w]})
|
||||
|
||||
return {
|
||||
"widgets": self.widgets,
|
||||
"widgets": widgets_data,
|
||||
"inputs": self.inputs,
|
||||
"input_groups": self.input_groups,
|
||||
}
|
||||
@ -1279,10 +1294,10 @@ class PriceBadge:
|
||||
raise ValueError("PriceBadge.expr must be a non-empty string.")
|
||||
self.depends_on.validate()
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
def as_dict(self, schema_inputs: list["Input"]) -> dict[str, Any]:
|
||||
return {
|
||||
"engine": self.engine,
|
||||
"depends_on": self.depends_on.as_dict(),
|
||||
"depends_on": self.depends_on.as_dict(schema_inputs),
|
||||
"expr": self.expr,
|
||||
}
|
||||
|
||||
@ -1438,7 +1453,7 @@ class Schema:
|
||||
experimental=self.is_experimental,
|
||||
api_node=self.is_api_node,
|
||||
python_module=getattr(cls, "RELATIVE_PYTHON_MODULE", "nodes"),
|
||||
price_badge=self.price_badge.as_dict() if self.price_badge is not None else None,
|
||||
price_badge=self.price_badge.as_dict(self.inputs) if self.price_badge is not None else None,
|
||||
)
|
||||
return info
|
||||
|
||||
@ -1471,7 +1486,7 @@ class Schema:
|
||||
experimental=self.is_experimental,
|
||||
api_node=self.is_api_node,
|
||||
python_module=getattr(cls, "RELATIVE_PYTHON_MODULE", "nodes"),
|
||||
price_badge=self.price_badge.as_dict() if self.price_badge is not None else None,
|
||||
price_badge=self.price_badge.as_dict(self.inputs) if self.price_badge is not None else None,
|
||||
)
|
||||
return info
|
||||
|
||||
|
||||
@ -523,7 +523,7 @@ class Flux2ProImageNode(IO.ComfyNode):
|
||||
PRICE_BADGE_EXPR = """
|
||||
(
|
||||
$MP := 1024 * 1024;
|
||||
$outMP := $max([1, $floor(((widgets.width.n * widgets.height.n) + $MP - 1) / $MP)]);
|
||||
$outMP := $max([1, $floor(((widgets.width * widgets.height) + $MP - 1) / $MP)]);
|
||||
$outputCost := 0.03 + 0.015 * ($outMP - 1);
|
||||
inputs.images.connected
|
||||
? {
|
||||
@ -654,7 +654,7 @@ class Flux2MaxImageNode(Flux2ProImageNode):
|
||||
PRICE_BADGE_EXPR = """
|
||||
(
|
||||
$MP := 1024 * 1024;
|
||||
$outMP := $max([1, $floor(((widgets.width.n * widgets.height.n) + $MP - 1) / $MP)]);
|
||||
$outMP := $max([1, $floor(((widgets.width * widgets.height) + $MP - 1) / $MP)]);
|
||||
$outputCost := 0.07 + 0.03 * ($outMP - 1);
|
||||
|
||||
inputs.images.connected
|
||||
|
||||
@ -374,7 +374,7 @@ class ByteDanceSeedreamNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model"]),
|
||||
expr="""
|
||||
(
|
||||
$price := $contains(widgets.model.s, "seedream-4-5-251128") ? 0.04 : 0.03;
|
||||
$price := $contains(widgets.model, "seedream-4-5-251128") ? 0.04 : 0.03;
|
||||
{
|
||||
"type":"usd",
|
||||
"usd": $price,
|
||||
@ -987,12 +987,12 @@ PRICE_BADGE_VIDEO = IO.PriceBadge(
|
||||
"1080p":[0.85,0.88]
|
||||
}
|
||||
};
|
||||
$model := widgets.model.s;
|
||||
$model := widgets.model;
|
||||
$modelKey :=
|
||||
$contains($model, "seedance-1-0-pro-fast") ? "seedance-1-0-pro-fast" :
|
||||
$contains($model, "seedance-1-0-pro") ? "seedance-1-0-pro" :
|
||||
"seedance-1-0-lite";
|
||||
$resolution := widgets.resolution.s;
|
||||
$resolution := widgets.resolution;
|
||||
$resKey :=
|
||||
$contains($resolution, "1080") ? "1080p" :
|
||||
$contains($resolution, "720") ? "720p" :
|
||||
@ -1001,7 +1001,7 @@ PRICE_BADGE_VIDEO = IO.PriceBadge(
|
||||
$baseRange := $lookup($modelPrices, $resKey);
|
||||
$min10s := $baseRange[0];
|
||||
$max10s := $baseRange[1];
|
||||
$scale := widgets.duration.n / 10;
|
||||
$scale := widgets.duration / 10;
|
||||
$minCost := $min10s * $scale;
|
||||
$maxCost := $max10s * $scale;
|
||||
($minCost = $maxCost)
|
||||
|
||||
@ -313,7 +313,7 @@ class GeminiNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.model.s;
|
||||
$m := widgets.model;
|
||||
|
||||
$contains($m, "gemini-2.5-flash")
|
||||
? {"type":"list_usd","usd":[0.0003,0.0025]}
|
||||
@ -723,7 +723,7 @@ class GeminiImage2(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["resolution"]),
|
||||
expr="""
|
||||
(
|
||||
$r := widgets.resolution.s;
|
||||
$r := widgets.resolution;
|
||||
($contains($r,"1k") or $contains($r,"2k"))
|
||||
? {"type":"usd","usd":0.134,"format":{"suffix":"/Image","approximate":true}}
|
||||
: $contains($r,"4k")
|
||||
|
||||
@ -302,8 +302,8 @@ class IdeogramV1(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["num_images", "turbo"]),
|
||||
expr="""
|
||||
(
|
||||
$n := widgets.num_images.n;
|
||||
$base := (widgets.turbo.b = true) ? 0.0286 : 0.0858;
|
||||
$n := widgets.num_images;
|
||||
$base := (widgets.turbo = true) ? 0.0286 : 0.0858;
|
||||
{"type":"usd","usd": $round($base * $n, 2)}
|
||||
)
|
||||
""",
|
||||
@ -450,8 +450,8 @@ class IdeogramV2(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["num_images", "turbo"]),
|
||||
expr="""
|
||||
(
|
||||
$n := widgets.num_images.n;
|
||||
$base := (widgets.turbo.b = true) ? 0.0715 : 0.1144;
|
||||
$n := widgets.num_images;
|
||||
$base := (widgets.turbo = true) ? 0.0715 : 0.1144;
|
||||
{"type":"usd","usd": $round($base * $n, 2)}
|
||||
)
|
||||
""",
|
||||
@ -615,8 +615,8 @@ class IdeogramV3(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["rendering_speed", "num_images"], inputs=["character_image"]),
|
||||
expr="""
|
||||
(
|
||||
$n := widgets.num_images.n;
|
||||
$speed := widgets.rendering_speed.s;
|
||||
$n := widgets.num_images;
|
||||
$speed := widgets.rendering_speed;
|
||||
$hasChar := inputs.character_image.connected;
|
||||
$base :=
|
||||
$contains($speed,"quality") ? ($hasChar ? 0.286 : 0.1287) :
|
||||
|
||||
@ -768,7 +768,7 @@ class KlingTextToVideoNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["mode"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.mode.s;
|
||||
$m := widgets.mode;
|
||||
$contains($m,"v2-5-turbo")
|
||||
? ($contains($m,"10") ? {"type":"usd","usd":0.7} : {"type":"usd","usd":0.35})
|
||||
: $contains($m,"v2-1-master")
|
||||
@ -849,9 +849,9 @@ class OmniProTextToVideoNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration", "resolution"]),
|
||||
expr="""
|
||||
(
|
||||
$mode := (widgets.resolution.s = "720p") ? "std" : "pro";
|
||||
$mode := (widgets.resolution = "720p") ? "std" : "pro";
|
||||
$rates := {"std": 0.084, "pro": 0.112};
|
||||
{"type":"usd","usd": $lookup($rates, $mode) * widgets.duration.n}
|
||||
{"type":"usd","usd": $lookup($rates, $mode) * widgets.duration}
|
||||
)
|
||||
""",
|
||||
),
|
||||
@ -927,9 +927,9 @@ class OmniProFirstLastFrameNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration", "resolution"]),
|
||||
expr="""
|
||||
(
|
||||
$mode := (widgets.resolution.s = "720p") ? "std" : "pro";
|
||||
$mode := (widgets.resolution = "720p") ? "std" : "pro";
|
||||
$rates := {"std": 0.084, "pro": 0.112};
|
||||
{"type":"usd","usd": $lookup($rates, $mode) * widgets.duration.n}
|
||||
{"type":"usd","usd": $lookup($rates, $mode) * widgets.duration}
|
||||
)
|
||||
""",
|
||||
),
|
||||
@ -1032,9 +1032,9 @@ class OmniProImageToVideoNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration", "resolution"]),
|
||||
expr="""
|
||||
(
|
||||
$mode := (widgets.resolution.s = "720p") ? "std" : "pro";
|
||||
$mode := (widgets.resolution = "720p") ? "std" : "pro";
|
||||
$rates := {"std": 0.084, "pro": 0.112};
|
||||
{"type":"usd","usd": $lookup($rates, $mode) * widgets.duration.n}
|
||||
{"type":"usd","usd": $lookup($rates, $mode) * widgets.duration}
|
||||
)
|
||||
""",
|
||||
),
|
||||
@ -1117,9 +1117,9 @@ class OmniProVideoToVideoNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration", "resolution"]),
|
||||
expr="""
|
||||
(
|
||||
$mode := (widgets.resolution.s = "720p") ? "std" : "pro";
|
||||
$mode := (widgets.resolution = "720p") ? "std" : "pro";
|
||||
$rates := {"std": 0.126, "pro": 0.168};
|
||||
{"type":"usd","usd": $lookup($rates, $mode) * widgets.duration.n}
|
||||
{"type":"usd","usd": $lookup($rates, $mode) * widgets.duration}
|
||||
)
|
||||
""",
|
||||
),
|
||||
@ -1213,7 +1213,7 @@ class OmniProEditVideoNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["resolution"]),
|
||||
expr="""
|
||||
(
|
||||
$mode := (widgets.resolution.s = "720p") ? "std" : "pro";
|
||||
$mode := (widgets.resolution = "720p") ? "std" : "pro";
|
||||
$rates := {"std": 0.126, "pro": 0.168};
|
||||
{"type":"usd","usd": $lookup($rates, $mode), "format":{"suffix":"/second"}}
|
||||
)
|
||||
@ -1462,9 +1462,9 @@ class KlingImage2VideoNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["mode", "model_name", "duration"]),
|
||||
expr="""
|
||||
(
|
||||
$mode := widgets.mode.s;
|
||||
$model := widgets.model_name.s;
|
||||
$dur := widgets.duration.s;
|
||||
$mode := widgets.mode;
|
||||
$model := widgets.model_name;
|
||||
$dur := widgets.duration;
|
||||
$contains($model,"v2-5-turbo")
|
||||
? ($contains($dur,"10") ? {"type":"usd","usd":0.7} : {"type":"usd","usd":0.35})
|
||||
: ($contains($model,"v2-1-master") or $contains($model,"v2-master"))
|
||||
@ -1635,7 +1635,7 @@ class KlingStartEndFrameNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["mode"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.mode.s;
|
||||
$m := widgets.mode;
|
||||
$contains($m,"v2-5-turbo")
|
||||
? ($contains($m,"10") ? {"type":"usd","usd":0.7} : {"type":"usd","usd":0.35})
|
||||
: $contains($m,"v2-1")
|
||||
@ -1811,9 +1811,9 @@ class KlingDualCharacterVideoEffectNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["mode", "model_name", "duration"]),
|
||||
expr="""
|
||||
(
|
||||
$mode := widgets.mode.s;
|
||||
$model := widgets.model_name.s;
|
||||
$dur := widgets.duration.s;
|
||||
$mode := widgets.mode;
|
||||
$model := widgets.model_name;
|
||||
$dur := widgets.duration;
|
||||
($contains($model,"v1-6") or $contains($model,"v1-5"))
|
||||
? (
|
||||
$contains($mode,"pro")
|
||||
@ -1898,7 +1898,7 @@ class KlingSingleImageVideoEffectNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["effect_scene"]),
|
||||
expr="""
|
||||
(
|
||||
($contains(widgets.effect_scene.s,"dizzydizzy") or $contains(widgets.effect_scene.s,"bloombloom"))
|
||||
($contains(widgets.effect_scene,"dizzydizzy") or $contains(widgets.effect_scene,"bloombloom"))
|
||||
? {"type":"usd","usd":0.49}
|
||||
: {"type":"usd","usd":0.28}
|
||||
)
|
||||
@ -2180,12 +2180,12 @@ class KlingImageGenerationNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model_name", "n"], inputs=["image"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.model_name.s;
|
||||
$m := widgets.model_name;
|
||||
$base :=
|
||||
$contains($m,"kling-v1-5")
|
||||
? (inputs.image.connected ? 0.028 : 0.014)
|
||||
: ($contains($m,"kling-v1") ? 0.0035 : 0.014);
|
||||
{"type":"usd","usd": $base * widgets.n.n}
|
||||
{"type":"usd","usd": $base * widgets.n}
|
||||
)
|
||||
""",
|
||||
),
|
||||
@ -2274,7 +2274,7 @@ class TextToVideoWithAudio(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration", "generate_audio"]),
|
||||
expr="""{"type":"usd","usd": 0.07 * widgets.duration.n * (widgets.generate_audio.b ? 2 : 1)}""",
|
||||
expr="""{"type":"usd","usd": 0.07 * widgets.duration * (widgets.generate_audio ? 2 : 1)}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -2342,7 +2342,7 @@ class ImageToVideoWithAudio(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration", "generate_audio"]),
|
||||
expr="""{"type":"usd","usd": 0.07 * widgets.duration.n * (widgets.generate_audio.b ? 2 : 1)}""",
|
||||
expr="""{"type":"usd","usd": 0.07 * widgets.duration * (widgets.generate_audio ? 2 : 1)}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -2429,7 +2429,7 @@ class MotionControl(IO.ComfyNode):
|
||||
expr="""
|
||||
(
|
||||
$prices := {"std": 0.07, "pro": 0.112};
|
||||
{"type":"usd","usd": $lookup($prices, widgets.mode.s), "format":{"suffix":"/second"}}
|
||||
{"type":"usd","usd": $lookup($prices, widgets.mode), "format":{"suffix":"/second"}}
|
||||
)
|
||||
""",
|
||||
),
|
||||
|
||||
@ -35,9 +35,9 @@ PRICE_BADGE = IO.PriceBadge(
|
||||
$pps := {
|
||||
"ltx-2 (pro)": {"1920x1080":0.06,"2560x1440":0.12,"3840x2160":0.24},
|
||||
"ltx-2 (fast)": {"1920x1080":0.04,"2560x1440":0.08,"3840x2160":0.16}
|
||||
}[widgets.model.s][widgets.resolution.s];
|
||||
}[widgets.model][widgets.resolution];
|
||||
|
||||
{"type":"usd","usd": $pps * widgets.duration.n}
|
||||
{"type":"usd","usd": $pps * widgets.duration}
|
||||
)
|
||||
""",
|
||||
)
|
||||
|
||||
@ -193,7 +193,7 @@ class LumaImageGenerationNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.model.s;
|
||||
$m := widgets.model;
|
||||
$contains($m,"photon-flash-1")
|
||||
? {"type":"usd","usd":0.0027}
|
||||
: $contains($m,"photon-1")
|
||||
@ -320,7 +320,7 @@ class LumaImageModifyNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.model.s;
|
||||
$m := widgets.model;
|
||||
$contains($m,"photon-flash-1")
|
||||
? {"type":"usd","usd":0.0027}
|
||||
: $contains($m,"photon-1")
|
||||
@ -612,9 +612,9 @@ PRICE_BADGE_VIDEO = IO.PriceBadge(
|
||||
}
|
||||
};
|
||||
|
||||
$m := widgets.model.s;
|
||||
$d := widgets.duration.s;
|
||||
$r := widgets.resolution.s;
|
||||
$m := widgets.model;
|
||||
$d := widgets.duration;
|
||||
$r := widgets.resolution;
|
||||
|
||||
$modelKey :=
|
||||
$contains($m,"ray-flash-2") ? "ray-flash-2" :
|
||||
|
||||
@ -350,8 +350,8 @@ class MinimaxHailuoVideoNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["resolution", "duration"]),
|
||||
expr="""
|
||||
(
|
||||
$r := widgets.resolution.s;
|
||||
$d := widgets.duration.s;
|
||||
$r := widgets.resolution;
|
||||
$d := widgets.duration;
|
||||
|
||||
$price :=
|
||||
$contains($r,"768p")
|
||||
|
||||
@ -234,14 +234,9 @@ class MoonvalleyImg2VideoNode(IO.ComfyNode):
|
||||
],
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["length"]),
|
||||
expr="""
|
||||
(
|
||||
$len := widgets.length.s;
|
||||
{"type":"usd","usd": ($len = "10s" ? 3.0 : 1.5)}
|
||||
)
|
||||
""",
|
||||
), # TO-DO: This is 1:1 code from frontend, but this makes no sense as we don't have `length` widget
|
||||
depends_on=IO.PriceBadgeDepends(),
|
||||
expr="""{"type":"usd","usd": 1.5}""",
|
||||
),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -361,14 +356,9 @@ class MoonvalleyVideo2VideoNode(IO.ComfyNode):
|
||||
],
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["length"]),
|
||||
expr="""
|
||||
(
|
||||
$len := widgets.length.s;
|
||||
{"type":"usd","usd": ($len = "10s" ? 4.0 : 2.25)}
|
||||
)
|
||||
""",
|
||||
), # TO-DO: This is 1:1 code from frontend, but this makes no sense as we don't have `length` widget
|
||||
depends_on=IO.PriceBadgeDepends(),
|
||||
expr="""{"type":"usd","usd": 2.25}""",
|
||||
),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -490,14 +480,9 @@ class MoonvalleyTxt2VideoNode(IO.ComfyNode):
|
||||
],
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["length"]),
|
||||
expr="""
|
||||
(
|
||||
$len := widgets.length.s;
|
||||
{"type":"usd","usd": ($len = "10s" ? 3.0 : 1.5)}
|
||||
)
|
||||
""",
|
||||
), # TO-DO: This is 1:1 code from frontend, but this makes no sense as we don't have `length` widget
|
||||
depends_on=IO.PriceBadgeDepends(),
|
||||
expr="""{"type":"usd","usd": 1.5}""",
|
||||
),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
||||
@ -164,8 +164,8 @@ class OpenAIDalle2(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["size", "n"]),
|
||||
expr="""
|
||||
(
|
||||
$size := widgets.size.s;
|
||||
$nRaw := widgets.n.n;
|
||||
$size := widgets.size;
|
||||
$nRaw := widgets.n;
|
||||
$n := ($nRaw != null and $nRaw != 0) ? $nRaw : 1;
|
||||
|
||||
$base :=
|
||||
@ -308,8 +308,8 @@ class OpenAIDalle3(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["size", "quality"]),
|
||||
expr="""
|
||||
(
|
||||
$size := widgets.size.s;
|
||||
$q := widgets.quality.s;
|
||||
$size := widgets.size;
|
||||
$q := widgets.quality;
|
||||
$hd := $contains($q, "hd");
|
||||
|
||||
$price :=
|
||||
@ -456,8 +456,8 @@ class OpenAIGPTImage1(IO.ComfyNode):
|
||||
"medium": [0.046, 0.07],
|
||||
"high": [0.167, 0.3]
|
||||
};
|
||||
$range := $lookup($ranges, widgets.quality.s);
|
||||
$n := widgets.n.n;
|
||||
$range := $lookup($ranges, widgets.quality);
|
||||
$n := widgets.n;
|
||||
($n = 1)
|
||||
? {"type":"range_usd","min_usd": $range[0], "max_usd": $range[1]}
|
||||
: {
|
||||
@ -628,7 +628,7 @@ class OpenAIChatNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.model.s;
|
||||
$m := widgets.model;
|
||||
|
||||
$contains($m,"o4-mini") ? {"type":"list_usd","usd":[0.0011,0.0044]} :
|
||||
$contains($m,"o1-pro") ? {"type":"list_usd","usd":[0.15,0.6]} :
|
||||
|
||||
@ -423,9 +423,9 @@ PRICE_BADGE_VIDEO = IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration_seconds", "quality", "motion_mode"]),
|
||||
expr="""
|
||||
(
|
||||
$d := widgets.duration_seconds.s;
|
||||
$q := widgets.quality.s;
|
||||
$m := widgets.motion_mode.s;
|
||||
$d := widgets.duration_seconds;
|
||||
$q := widgets.quality;
|
||||
$m := widgets.motion_mode;
|
||||
|
||||
$price :=
|
||||
$contains($d,"5")
|
||||
|
||||
@ -380,7 +380,7 @@ class RecraftTextToImageNode(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["n"]),
|
||||
expr="""{"type":"usd","usd": $round(0.04 * widgets.n.n, 2)}""",
|
||||
expr="""{"type":"usd","usd": $round(0.04 * widgets.n, 2)}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -496,7 +496,7 @@ class RecraftImageToImageNode(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["n"]),
|
||||
expr="""{"type":"usd","usd": $round(0.04 * widgets.n.n, 2)}""",
|
||||
expr="""{"type":"usd","usd": $round(0.04 * widgets.n, 2)}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -601,7 +601,7 @@ class RecraftImageInpaintingNode(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["n"]),
|
||||
expr="""{"type":"usd","usd": $round(0.04 * widgets.n.n, 2)}""",
|
||||
expr="""{"type":"usd","usd": $round(0.04 * widgets.n, 2)}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -706,7 +706,7 @@ class RecraftTextToVectorNode(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["n"]),
|
||||
expr="""{"type":"usd","usd": $round(0.08 * widgets.n.n, 2)}""",
|
||||
expr="""{"type":"usd","usd": $round(0.08 * widgets.n, 2)}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -776,8 +776,8 @@ class RecraftVectorizeImageNode(IO.ComfyNode):
|
||||
],
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["n"]),
|
||||
expr="""{"type":"usd","usd": $round(0.01 * widgets.n.n, 2)}""",
|
||||
depends_on=IO.PriceBadgeDepends(),
|
||||
expr="""{"type":"usd","usd": 0.01}""",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@ -186,7 +186,7 @@ class RunwayImageToVideoNodeGen3a(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration"]),
|
||||
expr="""{"type":"usd","usd": 0.0715 * widgets.duration.n}""",
|
||||
expr="""{"type":"usd","usd": 0.0715 * widgets.duration}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -280,7 +280,7 @@ class RunwayImageToVideoNodeGen4(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration"]),
|
||||
expr="""{"type":"usd","usd": 0.0715 * widgets.duration.n}""",
|
||||
expr="""{"type":"usd","usd": 0.0715 * widgets.duration}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -382,7 +382,7 @@ class RunwayFirstLastFrameNode(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration"]),
|
||||
expr="""{"type":"usd","usd": 0.0715 * widgets.duration.n}""",
|
||||
expr="""{"type":"usd","usd": 0.0715 * widgets.duration}""",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@ -93,9 +93,9 @@ class OpenAIVideoSora2(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model", "size", "duration"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.model.s;
|
||||
$size := widgets.size.s;
|
||||
$dur := widgets.duration.n;
|
||||
$m := widgets.model;
|
||||
$size := widgets.size;
|
||||
$dur := widgets.duration;
|
||||
$isPro := $contains($m, "sora-2-pro");
|
||||
$isSora2 := $contains($m, "sora-2");
|
||||
$isProSize := ($size = "1024x1792" or $size = "1792x1024");
|
||||
|
||||
@ -271,7 +271,7 @@ class StabilityStableImageSD_3_5Node(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model"]),
|
||||
expr="""
|
||||
(
|
||||
$contains(widgets.model.s,"large")
|
||||
$contains(widgets.model,"large")
|
||||
? {"type":"usd","usd":0.065}
|
||||
: {"type":"usd","usd":0.035}
|
||||
)
|
||||
|
||||
@ -131,18 +131,18 @@ class TripoTextToModelNode(IO.ComfyNode):
|
||||
),
|
||||
expr="""
|
||||
(
|
||||
$isV14 := $contains(widgets.model_version.s,"v1.4");
|
||||
$style := widgets.style.s;
|
||||
$isV14 := $contains(widgets.model_version,"v1.4");
|
||||
$style := widgets.style;
|
||||
$hasStyle := ($style != "" and $style != "none");
|
||||
$withTexture := widgets.texture.b or widgets.pbr.b;
|
||||
$isHdTexture := (widgets.texture_quality.s = "detailed");
|
||||
$isDetailedGeometry := (widgets.geometry_quality.s = "detailed");
|
||||
$withTexture := widgets.texture or widgets.pbr;
|
||||
$isHdTexture := (widgets.texture_quality = "detailed");
|
||||
$isDetailedGeometry := (widgets.geometry_quality = "detailed");
|
||||
$baseCredits :=
|
||||
$isV14 ? 20 : ($withTexture ? 20 : 10);
|
||||
$credits :=
|
||||
$baseCredits
|
||||
+ ($hasStyle ? 5 : 0)
|
||||
+ (widgets.quad.b ? 5 : 0)
|
||||
+ (widgets.quad ? 5 : 0)
|
||||
+ ($isHdTexture ? 10 : 0)
|
||||
+ ($isDetailedGeometry ? 20 : 0);
|
||||
{"type":"usd","usd": $round($credits * 0.01, 2)}
|
||||
@ -256,18 +256,18 @@ class TripoImageToModelNode(IO.ComfyNode):
|
||||
),
|
||||
expr="""
|
||||
(
|
||||
$isV14 := $contains(widgets.model_version.s,"v1.4");
|
||||
$style := widgets.style.s;
|
||||
$isV14 := $contains(widgets.model_version,"v1.4");
|
||||
$style := widgets.style;
|
||||
$hasStyle := ($style != "" and $style != "none");
|
||||
$withTexture := widgets.texture.b or widgets.pbr.b;
|
||||
$isHdTexture := (widgets.texture_quality.s = "detailed");
|
||||
$isDetailedGeometry := (widgets.geometry_quality.s = "detailed");
|
||||
$withTexture := widgets.texture or widgets.pbr;
|
||||
$isHdTexture := (widgets.texture_quality = "detailed");
|
||||
$isDetailedGeometry := (widgets.geometry_quality = "detailed");
|
||||
$baseCredits :=
|
||||
$isV14 ? 30 : ($withTexture ? 30 : 20);
|
||||
$credits :=
|
||||
$baseCredits
|
||||
+ ($hasStyle ? 5 : 0)
|
||||
+ (widgets.quad.b ? 5 : 0)
|
||||
+ (widgets.quad ? 5 : 0)
|
||||
+ ($isHdTexture ? 10 : 0)
|
||||
+ ($isDetailedGeometry ? 20 : 0);
|
||||
{"type":"usd","usd": $round($credits * 0.01, 2)}
|
||||
@ -391,15 +391,15 @@ class TripoMultiviewToModelNode(IO.ComfyNode):
|
||||
),
|
||||
expr="""
|
||||
(
|
||||
$isV14 := $contains(widgets.model_version.s,"v1.4");
|
||||
$withTexture := widgets.texture.b or widgets.pbr.b;
|
||||
$isHdTexture := (widgets.texture_quality.s = "detailed");
|
||||
$isDetailedGeometry := (widgets.geometry_quality.s = "detailed");
|
||||
$isV14 := $contains(widgets.model_version,"v1.4");
|
||||
$withTexture := widgets.texture or widgets.pbr;
|
||||
$isHdTexture := (widgets.texture_quality = "detailed");
|
||||
$isDetailedGeometry := (widgets.geometry_quality = "detailed");
|
||||
$baseCredits :=
|
||||
$isV14 ? 30 : ($withTexture ? 30 : 20);
|
||||
$credits :=
|
||||
$baseCredits
|
||||
+ (widgets.quad.b ? 5 : 0)
|
||||
+ (widgets.quad ? 5 : 0)
|
||||
+ ($isHdTexture ? 10 : 0)
|
||||
+ ($isDetailedGeometry ? 20 : 0);
|
||||
{"type":"usd","usd": $round($credits * 0.01, 2)}
|
||||
@ -501,7 +501,7 @@ class TripoTextureNode(IO.ComfyNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["texture_quality"]),
|
||||
expr="""
|
||||
(
|
||||
$tq := widgets.texture_quality.s;
|
||||
$tq := widgets.texture_quality;
|
||||
{"type":"usd","usd": ($contains($tq,"detailed") ? 0.2 : 0.1)}
|
||||
)
|
||||
""",
|
||||
@ -772,24 +772,24 @@ class TripoConversionNode(IO.ComfyNode):
|
||||
),
|
||||
expr="""
|
||||
(
|
||||
$face := (widgets.face_limit.n != null) ? widgets.face_limit.n : -1;
|
||||
$texSize := (widgets.texture_size.n != null) ? widgets.texture_size.n : 4096;
|
||||
$flatThresh := (widgets.flatten_bottom_threshold.n != null) ? widgets.flatten_bottom_threshold.n : 0;
|
||||
$scale := (widgets.scale_factor.n != null) ? widgets.scale_factor.n : 1;
|
||||
$texFmt := (widgets.texture_format.s != "" ? widgets.texture_format.s : "jpeg");
|
||||
$part := widgets.part_names.s;
|
||||
$fbx := (widgets.fbx_preset.s != "" ? widgets.fbx_preset.s : "blender");
|
||||
$orient := (widgets.export_orientation.s != "" ? widgets.export_orientation.s : "default");
|
||||
$face := (widgets.face_limit != null) ? widgets.face_limit : -1;
|
||||
$texSize := (widgets.texture_size != null) ? widgets.texture_size : 4096;
|
||||
$flatThresh := (widgets.flatten_bottom_threshold != null) ? widgets.flatten_bottom_threshold : 0;
|
||||
$scale := (widgets.scale_factor != null) ? widgets.scale_factor : 1;
|
||||
$texFmt := (widgets.texture_format != "" ? widgets.texture_format : "jpeg");
|
||||
$part := widgets.part_names;
|
||||
$fbx := (widgets.fbx_preset != "" ? widgets.fbx_preset : "blender");
|
||||
$orient := (widgets.export_orientation != "" ? widgets.export_orientation : "default");
|
||||
$advanced :=
|
||||
widgets.quad.b or
|
||||
widgets.force_symmetry.b or
|
||||
widgets.flatten_bottom.b or
|
||||
widgets.pivot_to_center_bottom.b or
|
||||
widgets.with_animation.b or
|
||||
widgets.pack_uv.b or
|
||||
widgets.bake.b or
|
||||
widgets.export_vertex_colors.b or
|
||||
widgets.animate_in_place.b or
|
||||
widgets.quad or
|
||||
widgets.force_symmetry or
|
||||
widgets.flatten_bottom or
|
||||
widgets.pivot_to_center_bottom or
|
||||
widgets.with_animation or
|
||||
widgets.pack_uv or
|
||||
widgets.bake or
|
||||
widgets.export_vertex_colors or
|
||||
widgets.animate_in_place or
|
||||
($face != -1) or
|
||||
($texSize != 4096) or
|
||||
($flatThresh != 0) or
|
||||
|
||||
@ -124,7 +124,7 @@ class VeoVideoGenerationNode(IO.ComfyNode):
|
||||
is_api_node=True,
|
||||
price_badge=IO.PriceBadge(
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["duration_seconds"]),
|
||||
expr="""{"type":"usd","usd": 0.5 * widgets.duration_seconds.n}""",
|
||||
expr="""{"type":"usd","usd": 0.5 * widgets.duration_seconds}""",
|
||||
),
|
||||
)
|
||||
|
||||
@ -355,8 +355,8 @@ class Veo3VideoGenerationNode(VeoVideoGenerationNode):
|
||||
depends_on=IO.PriceBadgeDepends(widgets=["model", "generate_audio"]),
|
||||
expr="""
|
||||
(
|
||||
$m := widgets.model.s;
|
||||
$a := widgets.generate_audio.b;
|
||||
$m := widgets.model;
|
||||
$a := widgets.generate_audio;
|
||||
($contains($m,"veo-3.0-fast-generate-001") or $contains($m,"veo-3.1-fast-generate"))
|
||||
? {"type":"usd","usd": ($a ? 1.2 : 0.8)}
|
||||
: ($contains($m,"veo-3.0-generate-001") or $contains($m,"veo-3.1-generate"))
|
||||
@ -446,9 +446,9 @@ class Veo3FirstLastFrameNode(IO.ComfyNode):
|
||||
"veo-3.1-fast-generate": { "audio": 0.15, "no_audio": 0.10 },
|
||||
"veo-3.1-generate": { "audio": 0.40, "no_audio": 0.20 }
|
||||
};
|
||||
$m := widgets.model.s;
|
||||
$ga := (widgets.generate_audio.s = "true");
|
||||
$seconds := widgets.duration.n;
|
||||
$m := widgets.model;
|
||||
$ga := (widgets.generate_audio = "true");
|
||||
$seconds := widgets.duration;
|
||||
$modelKey :=
|
||||
$contains($m, "veo-3.1-fast-generate") ? "veo-3.1-fast-generate" :
|
||||
$contains($m, "veo-3.1-generate") ? "veo-3.1-generate" :
|
||||
|
||||
@ -531,9 +531,9 @@ class WanTextToVideoApi(IO.ComfyNode):
|
||||
expr="""
|
||||
(
|
||||
$ppsTable := { "480p": 0.05, "720p": 0.1, "1080p": 0.15 };
|
||||
$resKey := $substringBefore(widgets.size.s, ":");
|
||||
$resKey := $substringBefore(widgets.size, ":");
|
||||
$pps := $lookup($ppsTable, $resKey);
|
||||
{ "type": "usd", "usd": $round($pps * widgets.duration.n, 2) }
|
||||
{ "type": "usd", "usd": $round($pps * widgets.duration, 2) }
|
||||
)
|
||||
""",
|
||||
),
|
||||
@ -703,8 +703,8 @@ class WanImageToVideoApi(IO.ComfyNode):
|
||||
expr="""
|
||||
(
|
||||
$ppsTable := { "480p": 0.05, "720p": 0.1, "1080p": 0.15 };
|
||||
$pps := $lookup($ppsTable, widgets.resolution.s);
|
||||
{ "type": "usd", "usd": $round($pps * widgets.duration.n, 2) }
|
||||
$pps := $lookup($ppsTable, widgets.resolution);
|
||||
{ "type": "usd", "usd": $round($pps * widgets.duration, 2) }
|
||||
)
|
||||
""",
|
||||
),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user