The Log window and the terminal share one rule. Levels come from FunPack's own
[Log] severities; ComfyUI and other packs are matched on strict error/warning
markers and tracebacks, not on words in prose.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FACCerXXJ2TbeLuRi6k5AG
The H3 run trains with a loop of our own (LoRA on the attention and feed-forward projections of the
50 blocks, per-block checkpoint, uniform noise levels, musubi-tuner's approach) while ComfyUI carries
the batches. Every Log record is flushed to disk as it is said and reloaded on start; the run
writes each stage and step to it. ComfyUI's own offloading toggle is ignored by the new loop.
UNTESTED on the real weights.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpnF7GwNGMbngU11wjym7P
The wording fix a commit ago was written by hand in two files and the same
mislabel was still sitting in four others -- traits, chain, modifier install and
node schema all reported a thing that loaded, recognised its work and then
raised as one that "did not load", sending a reader after an import error that
never happened. Three hand-written strings would have drifted, so log.broke()
now says it once and every site calls it.
Two of the new tests were vacuous when first written -- "nothing said did not
load" is also true where nothing ran at all, and picking the first provider
found lands on one whose traits exclude the test's model. Both assert the line
is present before asserting the wrong line is not.
One finding, confirmed, plus four sites it did not name.
Colour is a preference, so it is a setting: hex in, hex out, one spelling,
refused if it is not one. A module handed "red" in one place and "#f00" in
another guesses wrong somewhere.
Image and mask are NOT settings and deliberately have no type. They are
data -- tensors the app uploads and the graph wires -- and ComfyUI already
has socket types for both. Putting a drawn mask in a JSON settings payload
would be inventing a second way to move something that already moves.
Runs now have an id. Previews, progress, results and log lines all have to
be attributable to one generation, and ComfyUI gives a node no way to ask
which run it is in. So FunPack marks its own, every log record carries it,
and the history can be filtered to a single run. Readable rather than a
uuid, because it is going to be read: "run 7" is findable in a wall of
output and a hex string is not.
The colour element was caught by the registry-driven rule test before it was
finished -- an element with no catalogue demo is neither shown nor attacked,
so coverage keeps up with the registry instead of lagging behind it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
[Log] Info: FunPack Diffusion Model Loader | flux.safetensors loaded, attention sage
[Log] Alert: MiniMaxH3ImageToVideo node | no "first_image" input is connected
[Log] Warning: FunPack LoRA Loader | style.safetensors is empty and will not load
[Log] Critical: torch | cannot allocate 14 GB (3 GB free); the run will not start
The difference between the middle two is the one that matters. Alert is a
choice you may not have made on purpose. Warning is something that will NOT
do what its name says -- the level v4 needed and did not have, which is how
560 handlers came to swallow a failure and carry on, so a feature could be
switched on, do nothing, and never say so.
Info is not decoration either: "loaded on GPU using sage attention" is how
an attention setting that did nothing gets noticed months before the
pictures look wrong enough to investigate.
Every call site moved -- there is no note() left to be vague through -- and
the loaders now say what they actually loaded rather than only what they
were asked for. Records are kept in a bounded ring as well as printed, so a
long rental session cannot turn the log into a memory leak, and served at
/funpack/api/log so a person can read it somewhere other than a terminal
full of ComfyUI's own output. There is a page for it.
Also dropped the preflight this was traded for: min and max are already
declared and already enforced at both doors, and a second protection layer
around a check that exists is ceremony.
Two mistakes worth keeping: a log line reached into the model's shape to
describe it and could have failed the load it was only narrating; and both
new pages passed `children` to an element that takes `rows`, which the kit
accepted and silently dropped. It throws on an unknown element and not on an
unknown prop.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Static serving routes through a pure resolve(), so the extension allowlist and
the traversal guard are tested without aiohttp. modules/ serves .js only: a
module cannot ship a stylesheet even if one is written.