Files
IxMxAMAR 15e4b0da4e release(v0.1.2): fix critical loader collision + 6 Gemini-review findings
Critical:
- rename nodes/ -> mp_nodes/, shared/ -> mp_shared/ to avoid shadowing
  ComfyUI core's nodes.py via sys.path injection (root cause of v0.1.1
  'nodes is not a package' startup failure)
- http_post now streams response and enforces 50MB cap mid-stream (DoS)
- AES key derivation: HKDF -> PBKDF2-HMAC-SHA256 600k iters + random salt
  (work factor against weak-key brute force; ciphertext format changed)
- fs_mkdir/copy/move/delete confined to ComfyUI input/output/temp + ~ by
  default; UTILITY_MEGAPACK_ALLOW_ARBITRARY_PATHS=1 to override

UX / correctness:
- combo settings now declare options array (themes dropdown was empty)
- LATENT default 1x4x8x8 zeros -> {} (avoids Flux/SD3 shape crashes)
- @op decorator rejects reserved widget names mode/theme at register time
- _pad_outputs docstring updated to match relaxed opaque-type behavior
2026-05-13 21:36:54 +05:30

153 lines
3.7 KiB
Python

"""Math, statistics, and randomness."""
import random
import statistics
from .. import op
@op(
op_id="math_add",
display_name="Math Add",
category="Math & Signals",
input_schema={"required": {
"a": ("FLOAT", {"default": 0.0}),
"b": ("FLOAT", {"default": 0.0}),
}},
output_indices=(2,),
)
def math_add(self, a, b):
return (float(a) + float(b),)
@op(
op_id="math_subtract",
display_name="Math Subtract",
category="Math & Signals",
input_schema={"required": {
"a": ("FLOAT", {"default": 0.0}),
"b": ("FLOAT", {"default": 0.0}),
}},
output_indices=(2,),
)
def math_subtract(self, a, b):
return (float(a) - float(b),)
@op(
op_id="math_multiply",
display_name="Math Multiply",
category="Math & Signals",
input_schema={"required": {
"a": ("FLOAT", {"default": 0.0}),
"b": ("FLOAT", {"default": 0.0}),
}},
output_indices=(2,),
)
def math_multiply(self, a, b):
return (float(a) * float(b),)
@op(
op_id="math_divide",
display_name="Math Divide",
category="Math & Signals",
input_schema={"required": {
"a": ("FLOAT", {"default": 0.0}),
"b": ("FLOAT", {"default": 1.0}),
}},
output_indices=(2,),
description="Raises ZeroDivisionError when b == 0.",
)
def math_divide(self, a, b):
if b == 0:
raise ZeroDivisionError("division by zero")
return (float(a) / float(b),)
@op(
op_id="math_clamp",
display_name="Math Clamp",
category="Math & Signals",
input_schema={"required": {
"value": ("FLOAT", {"default": 0.0}),
"lo": ("FLOAT", {"default": 0.0}),
"hi": ("FLOAT", {"default": 1.0}),
}},
output_indices=(2,),
)
def math_clamp(self, value, lo, hi):
return (float(max(lo, min(hi, value))),)
@op(
op_id="math_lerp",
display_name="Math Lerp",
category="Math & Signals",
input_schema={"required": {
"a": ("FLOAT", {"default": 0.0}),
"b": ("FLOAT", {"default": 1.0}),
"t": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0}),
}},
output_indices=(2,),
)
def math_lerp(self, a, b, t):
return (float(a) + (float(b) - float(a)) * float(t),)
@op(
op_id="stats_mean",
display_name="Stats Mean",
category="Math & Signals",
input_schema={"required": {"values": ("LIST", {"default": []})}},
output_indices=(2,),
)
def stats_mean(self, values):
if not values:
return (0.0,)
return (float(statistics.fmean(values)),)
@op(
op_id="stats_median",
display_name="Stats Median",
category="Math & Signals",
input_schema={"required": {"values": ("LIST", {"default": []})}},
output_indices=(2,),
)
def stats_median(self, values):
if not values:
return (0.0,)
return (float(statistics.median(values)),)
@op(
op_id="stats_std",
display_name="Stats Stdev (population)",
category="Math & Signals",
input_schema={"required": {"values": ("LIST", {"default": []})}},
output_indices=(2,),
description="Population standard deviation. Returns 0 for fewer than 2 values.",
)
def stats_std(self, values):
if not values or len(values) < 2:
return (0.0,)
return (float(statistics.pstdev(values)),)
@op(
op_id="random_uniform",
display_name="Random Uniform",
category="Math & Signals",
input_schema={"required": {
"lo": ("FLOAT", {"default": 0.0}),
"hi": ("FLOAT", {"default": 1.0}),
"seed": ("INT", {"default": -1, "min": -1, "max": 0xFFFFFFFF}),
}},
output_indices=(2,),
description="seed = -1 means non-deterministic; otherwise reproducible.",
)
def random_uniform(self, lo, hi, seed=-1):
rng = random.Random() if seed == -1 else random.Random(seed)
return (rng.uniform(float(lo), float(hi)),)