Recovery keyed on v.error, which a reset never sets, so nothing restarted
the load and _isSeeking() froze the transport at readyState 0. Play took
the same wait-for-metadata branch, so it was a no-op.
Reads the safetensors header's key names (same signatures core uses), so the
pipeline wires for whatever is actually loaded. An unidentifiable file proposes
no family rather than defaulting to LTX. Frame geometry migrates on change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Family is known at loader-save, so Engine Settings drops H3-dead knobs (and
LTX-dead h3_audio_clock) instead of explaining them per run. Values survive a
family switch; the now-redundant main-window chips are removed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
_refine_latent rejects nested latents at the door and every other caller
returns the clone unmodified, so the alias is unreachable. Noted so the next
audit does not re-open it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
expected_latent_frames had one caller (latent_overlap_frames), which the test
only imported and never called. The live layout path reads the sampler's own
scene_playback numbers. Tests: 968 passed, same as baseline.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Unreferenced, and negatives do not exist at CFG=1 where most generation happens.
Drops _v2_negative_prompt_advisor and its two private helpers (131 lines);
_v2_negative_text_conflicts_with_request keeps 2 live callers and stays.
Tests: 968 passed, same as baseline.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
14 more silent no-ops made audible: conditioning memory blend/repel/rollback,
Bounded Attention, ALG blur, guide image load, identity install, wired pins,
shortcut expansion. Both hook-removal leaks now name the restart.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
One mechanism for both: failed() names the attempt, the error and the effect on
the output, once per run; note_on_change states a standing condition once and
again only when it changes. 13 silent no-ops made audible, 4 repeats silenced.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
_ensureVideo already registers the url on both the create and reuse paths, so
window-materialized elements always could retry; the added registration was a
no-op and its comment described a bug that does not exist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
_classifyVideoError requires _urlClips registration and only _syncPool
registered, so anything the sliding window added mid-playback was stuck on
"Loading" after one transient error.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Project - Prompt (global) omits the postfix Studio appends to every scene, so
a linked node encoded less than Studio with no clue; the postfix is where
audio directions usually live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CLIP wins whenever it is connected and the wired CONDITIONING is never read;
the ownership label that knew this was computed and thrown away.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
H3's shifted schedules keep sigma high to the end, so max(0, 1-2*sigma) gave
the rating wrappers 0 of 4 steps on turbo and 4 of 20 at shift 3 while they
reported active. Read the base grid off the schedule; report the window.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Only the fixed-direction fallback announced its lift, so a working value
function was indistinguishable from nothing happening.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fitted on raw conditioning, it was handed H3's refined tensor and threw every
step; the run fell back to the fixed direction while reporting VF steering.
Take the gradient at the raw cond, lift it, cache it per scene.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
H3 refines conditioning in extra_conds, so c_crossattn is 5376-dim hidden
state while the taste store holds 5120-dim raw text: embed_guidance raised,
score_slider swallowed it and steered nothing. Lift via the model's own
preprocessor; same bridge fixes DynaShift's prompt weighting.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A pin is packed as condition rows, so its token count belongs to the grid it was
encoded on and upscale_2x crashed the model placing it. LTX guides are dropped
here; on H3 the pin is the anchor, so it is brought along instead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
H3's resizer interpolates to a requested size and takes 1.0-4.0; Lightricks' is a
fixed 2x network and now says it ignored the value instead of rounding quietly.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
'auto' will not fetch a 128-channel file for a 24-channel model, so the old text
sent H3 users to wait at the console for a download that never starts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both did LTX latent surgery unguarded: prepending frames off H3's 5k+2 grid and
attaching conditioning it never reads. Carry now pins the original reference at
frame 0; a mid-clip guide declines by the same rule as every other H3 pin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ComfyUI has no branch for this architecture, so the only published 24-channel
upsampler needed its own node pack — and second_pass_op on H3 needs a 24-channel
one to run. Shape and statistics come off the checkpoint; it owns its normalisation.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
H3 has no latent conditioning, so a carried tail was noise it could overwrite:
the seam matched and the rest of the shot knew nothing about the scene before it.
The previous scene's last latent frame becomes this scene's frame-0 pin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Core's latent-upscale loader is an if/elif with no else, so an unrecognised file
falls off the end as "cannot access local variable 'model'". The architectures it
knows are probed here first, and an unknown one is reported by name and key shape.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
It is a toggle now, not a value in the list: SLA takes H3's packed self-attention
and the chosen backend takes the text refiner, masked calls and dense-last steps.
When SLA does not take, the chosen backend is still installed on its own.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picked in the diffusion model loader's attention list, not wired as a node.
Six settings folded under Advanced; offered only where CUDA and Triton run it
and ignored on any model that is not H3. Kernel vendored from LightX2V.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Saving a pipeline mirrored it into the global default, so every later project
adopted an imported workflow. Only FunPack's own seeded loaders travel now; the
family is recorded on its own. Also: creating a linked input no longer self-aborts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A CONDITIONING output had no port to reach in guided mode. It wires explicitly
only — it replaces the typed prompt. An unwired pass-through no longer counts as
a source, which had made every CLIP consumer read as ambiguous.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Studio's latent port does not exist in this family, so the node could be added,
filled in and never connected. Its LATENT and keyframe CONDITIONING now reach the
sampler, with a test that every open core input stays reachable in both families.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rows are picked from a searchable list of installed files instead of typed into a
table of dropdowns, and an input the node calls advanced (the trained stack) is
folded away unless something feeds it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
An imported workflow was copied into every new project, so a fresh wizard setup
handed the user third-party loaders to wire. It now seeds FunPack's own and
carries the picked files across; an audio VAE feeds the audio latent too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
v2a scale and bounded attention install on attn2 / video_to_audio_attn, which the
block-only sweep never reached and never tagged. The census prints what is still
installed before sampling, so a count that grows is proof rather than a hunch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Empty is a working state now, logged as "No active LoRAs", so the hop every
LoRA needs is already wired into a fresh pipeline.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Seeded server-side on first read, once, per family — plus the family's own plumbing, so
nothing required is left to wire by hand. A seed never reaches the global default, which
would replace configured loaders with empty ones. Wizard and node picker follow.
Both were switched off on H3 because Lightricks' upsampler is 128-channel — a fact about
the file, not the family. They now load any upsampler ComfyUI can (core's loader handles
the rest), refuse a mismatched one by name, and never download the LTX file for H3.
A funpack_list widget renders as rows with Add/reorder/remove instead of raw JSON.
Loaders sit in a pinned section above everything else; imported workflows fall back to
what a node outputs. Removing a node joins its neighbours, the way ComfyUI's delete does.
Quantization + a per-model attention backend read from ComfyUI's own registry, so only
installed ones are offered. The LoRA loader now takes its own list and scores wrapper
prefixes against the model's key map, instead of applying a diffusers LoRA as a silent no-op.
The group button just sets the per-node bypass every card already has. The builder was
judging each node against a graph still holding its doomed siblings, so it refused any
bypass of connected nodes and left chains pointing at deleted ones — an output read only
by other leaving nodes needs no pass-through, and a leaving consumer needs no repair.
Groups come from the workflow's own group boxes and from each subgraph's name, so what
the author organised survives import. A group is a VIEW — nodes stay flat, every wire
keeps its real endpoints, there is no inside to navigate into. Search covers class, label,
widget names and values (model files) and socket types; it overrides folds.
They exist only in web/js/setgetnodes.js — no Python class — so the frontend resolves
them away and emitting one queues a type the backend has never heard of. Links are
re-pointed past each pair; a Get with no Set leaves the input unwired rather than dangling.
A subgraph instance's type is a uuid from definitions.subgraphs, so every node inside it
was lost and the graph queued a class ComfyUI has never heard of. Boundary links are
rewired both ways, and promoted widget values win over the inner node's stale copy.
Old frontends build their API base from location.pathname, so a page left open on the old
URL polled /funpack/<old>/api/health, got 404, and sat on "Reloading ComfyUI" forever —
never reaching the reload that would have hit the page redirect.
The strip list had grown a second and a third justification — "cross-shot" and
"experimental / expensive" — and those were decisions about what is worth someone's time,
made for them. Eleven settings came off a run that way, none of them hidden, so the
controls stayed on screen and did nothing.
Now it strips refinement only: the five rating-driven sampler knobs, the Studio refiner
keys, and the per-sampler velocity bias / rescue that replay a rated bank. Those cannot
work here — there is no rating UI to feed them. Cross-shot memory, guides, ALG, bounded
attention, identity transfer, segmented detailing, the plateau cache and context windows
all run as configured.
The lists now mirror the frontend's own gates, and a test reads engine_settings.js to
hold them in step: stripped-but-visible is a control that lies, hidden-but-live is the
same lie inverted.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Easy Gen loaded the same engine_settings.js and posted to the same endpoint with no
simple flag, so it always allowed the second pass. Simple mode stripped it because
"costs real time for a quality bet" got written into the rule, which is not a reason —
that is the user's call.
The rest of the strip list stands on a rule that actually holds: a setting belongs there
only if it CANNOT work in this mode — a no-op without a trained key (there is no rating
UI), or a relationship between shots (there is one shot). The second pass is neither. It
needs no rated history and no second shot, and upscaling a single shot is one of the
main things the mode is for.
The switch was on screen the whole time: Simple hides only the rating-gated knobs, so
Enable, the schedule and the between-pass operation all rendered and were then ignored.
Until this morning the run report that said so was being discarded too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Linked inputs failed in silence. A link whose member names a node that was replaced, or
a widget renamed out from under it, wrote nothing — the node kept its own value, the
project setting never reached the graph, and no report line, log line or UI element said
which value won.
Each way it can fail is now reported, in a new `ignored` bucket: a value the user SET
that did not reach the graph. That is its own class — the run is valid, it just isn't
the one they configured — so it is kept apart from `unsatisfied`, which is mostly
routine.
The editor was discarding the build report entirely, so every line the builder already
wrote (including the anchorless-scene and Simple-mode notes) went nowhere. `ignored` now
raises the timeline notice, and the links that DID fire are logged to the console with
their values, so a setting can be confirmed without reading the queued prompt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A resize, trim or split moved a shot off project length as a side effect of a drag, and
nothing moved it back. Editing Frames now resets those shots to follow it.
Custom is the exception, and the same one the rest of the app already makes: a shot set
to Custom is locked against timeline resize too. It is the one length typed on purpose,
so the warning above the field is now only about those — with the button to fold them in
as well.
Quiet patches record no history (they fire per keystroke), but this one discards work,
so it takes one undo point. Only the first keystroke of a burst finds anything left in
timeline mode, so the stack gets one entry, not one per character.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three unrelated reports.
Wires lost or "(not allowed)" after loading a project. /api/pipeline-ports read the
family from the GLOBAL models.json, so it described whichever project was saved last.
Open one on the other family and its saved wires point at ports that family has no rule
for. It takes ?pid= now, and the panel asks for the config before the rules that depend
on it. Reconcile also dropped a port wire when core_overrides named a deleted slot — it
cleared every other slot's wire to that port, then failed to add the replacement.
Guided mode also filtered harder than the builder validates. A node added through
"Any node…" has role `custom`, which no rule table mentions, so a custom VAE loader
could not reach the pipeline at all. A role with no rule for an output type now reaches
any port of that type; a role that HAS one keeps it, and internal links stay closed.
Both sides read the same list, since the panel hiding what the builder accepts is what
produced "(not allowed)".
Frames / scene silently missed shots. Any timeline resize, trim or split moves a scene
off project length for good, and nothing said so — typing 305 and rendering 450 read as
the edit being ignored. The Project panel now says how many shots it doesn't reach and
offers to put them back. The panel's fingerprint had to learn about scene state, or the
warning outlived the fix.
second_pass_op=upscale_2x no longer drops the i2v pin. The pinned frames in the upscaled
latent ARE the anchor — carried through the same upsampler as the rest of the clip — so
only the mask needed scaling to the new grid. Pass 2 at 4x the pixels was the run most
likely to drift off the reference, and it was the one running unpinned. The pin now
holds the upscaled anchor rather than the encoded source image, and the report says so.
Guide keyframes are still dropped: those are token indices, not pixels.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>