Repository navigation
Releases: seesee75-commits/ComfyUI-MiniMaxH3-Director
Release list
0.3.2
A voice on the subject, not on the timeline (issue #10). Every subject slot has an
Add voice button (Refs ON), or drop an audio file on the slot. That clip is sent to the model
as an <Audio N> reference tied to that subject:
<Audio 1> is the voice-timbre reference for <Subject 1> (S1).
<Audio 2> is the voice-timbre reference for <Subject 2> (S2).
It is not on the timeline, so it is not bounded by the render window and takes no output time —
two voice references and a background track no longer compete for one lane, and the render stays
as short as you made it. It does not depend on the audio-track switch either: a voice on a subject
is as deliberate as the subject's image. Voices go first in <Audio N> order (slot order), then
whatever sits on the timeline, inside H3's cap of three audio clips; a clip that does not fit is
named. The timeline's audio clips and their Voice of menu work as before. A slot with no
reference image cannot be a <Subject N>, so its voice goes out as a plain voice reference, which
the tooltip says. Override Audio together with a reference video still wins (a reference video's
soundtrack is numbered first), and it names the voice it set aside. The log warns when a voice file
is under the 2 s the model card asks for.
0.3.1
@Brioch's pull request #18, carried over by hand: it had stopped
merging after 0.2.3–0.3.0 touched the same planner and docs, so its behaviour was re-implemented
on the current code and its tests re-written against it. Every idea below is theirs.
- A reference no longer spends output time. A reference is an input to the model, not content
in the video —<Video k>and<Audio j>are never composited — but a clip had to overlap the
render window to be sent at all, and adding one stretched the window to cover it. The model card
wants each reference audio clip 10–15 s long, so three of them grew the output to 45 s: three
times the longest video H3 can make. Neither reference track touches the output length now,
and a clip is sent from wherever it sits; it lands after the last one, which for anything
longer than the window is out in the shaded area, where a reference belongs. A 5 s render
sends all three. Position still decides one thing, for audio only: whether the clip is also
part of the muxed soundtrack — inside the window it is both, past it a reference only, which
the clip's info panel says. A parked reference video is sent whole on its own trim instead of
losing its head to a window start it has nothing to do with. A retake keeps the old rule.
(lockclips are not references and still have to be in the window: a lock is a position in time.) - Every audio clip on the track plays its own file again. With two clips loaded both showed
up in the prompt and both drew their waveform, but only one could be heard: the editor stamped
the decoded buffer onto every clip that matched it, and a standalone clip has no blob URL to
match on, so the test wasundefined === undefinedfor the whole track. Only the preview was
affected; what was sent to the model was always right. - A reference clip that cannot be read says which one. A missing file or a trim past the end of
the audio was dropped in silence — and because<Audio N>is numbered before any file is opened,
that label and every one after it then named a reference the model never got. The log now names
the clip and its label. - Both per-type caps (3 audio, 3 video) name the clip they drop, like every other limit.
- Override Audio wins over the audio track outside the editor too: sent together, every
<Audio N>label would be one off (a reference video's soundtrack is numbered first). The clips
set aside are named, and Override Audio warns when the video it wants the soundtrack from is
parked past the window.
0.3.0
Your own audio in the video, with a way to choose how — and the lines the model needs to believe it.
- A clip set to
fully_copy/partially_copynow has a real chance of being copied. Setting
the marker was always possible (right-click a clip) and it wrote the guide's
retention_analysisline — but withnon_diegetic_music: N/Aand no soundscape line the
model sang something of its own. Measured on an 8 s singing clip, 20 steps: without the two
sound lines the audio was unrelated to the clip in all three runs (envelope correlation
0.08–0.17); with them the clip itself came back in four runs of six (0.96–0.98) and not in
the other two (0.10, 0.21), the same prompt on a different seed. So it is the guide's
behaviour and the model follows it most of the time, not always. The Director now writes
those two lines whenever a clip is set to a copy marker and the boxes are empty, in the
guide's own wording ("<Audio 1>is directly reused as the complete audience-only score");
text you write there still wins. The default staysreference, which follows a voice or
style and never copies. For audio that must come out as given, uselock. - New:
lock (exact audio)on an audio clip. Not a prompt wording but a different
mechanism, the one the LTX Director used: the clip is encoded with the audio VAE into the
model's audio stream and held there with a zero noise mask, and the video is generated around
it. The gaps between locked clips, and anything after the last, stay the model's. It works with
Refs OFF too, where the guide offers no audio references at all. Measured at 0.99 in every
run (five of five, both checkpoints), against four of six for the copy markers. A
locked clip is not an<Audio N>reference, gets no label and does not count against the
limit of three. It needs the audio VAE and says so if it is missing. - Only one
fully_copy. The marker means "the complete final audio track"; a second clip
with it is written aspartially_copyand the warnings area says so. - The right-click menu now calls the audio setting Audio use and lists
lockbeside the
guide's four markers; with Refs OFF it offersmixdown only/lock. - README: a table of what each setting does to the sound, and what was measured.
0.2.5
- The node now says when a timeline audio clip is not being sent to the model. With
References off (fl2va) the model has no audio input at all, and with the audio track
switched off in ref2va nothing is sent either; in both cases the clip is carried only by the
combined_audiooutput. That is how it was designed, but it looked exactly like a clip
that was ignored: the voice in the result was the model's own, spoken from the text, and
nothing said why. The warning names which case it is and what to do — wirecombined_audio
into CreateVideo to hear the clip itself, or use Refs ON with the audio track enabled so
the model gets it as an<Audio>reference. Even then it is a reference the voice follows,
not a copy of the waveform.
0.2.4
prepend_texton the Director ([#29]). A connection-only text input; whatever is wired
into it goes in front of the global prompt, joined by a comma. It was asked for so LoRA
trigger words can come straight from a LoRA loader. It is deliberately not put ahead of
the whole compiled prompt: the minimax format opens with the task statement and labelled
sections, and text in front of them would break the shape both guides ask for. The
Director's existingpromptoutput carries it, so a second pass can reuse the composed
text (the other half of the request, which already worked). The panel's live preview cannot
show it, because the text does not exist until the graph runs. The new socket is declared
last, so workflows saved before it keep every value where it was.
0.2.3
Three bugs reported by users, and one control that never did anything.
- Save / Save As kept only part of the timeline (#23, reported and diagnosed by
@SveSop). The Director stores its timeline from an allowlist,
and the.jsonwritten by Save carried its own, shorter copy of it.overall_soundscape,
non_diegetic_musicand the hand-written prompt override (prompt_override,
prompt_override_on) were on the first list and not the second, so they came back empty
after a Load — no error anywhere. The two lists now match, andtest_node.pycompares them
by key name so the next field added to one cannot drift from the other. - Retake Stitch could not find the base video's audio when the input folder is not the
default one (#30, reported with the fix by @Jaminblack).
The frames were fetched through the media library, which resolves the timeline's relative
filename against the input folder; the soundtrack was handed to PyAV as-is and looked for
whatdreamscost/…in the working directory. The head and tail of the result came back
silent and the log saidcould not read audio. The audio slice resolves the name the same
way now, and says plainly when the file is not in the input folder. - A base URL ending in
/v1no longer produces a 404 (#31). The Analyze request
appended/v1/chat/completionsto whatever was typed, so the address Anthropic's and LM
Studio's docs give —https://api.anthropic.com/v1/— asked for/v1/v1/chat/completions.
Both spellings work now, and the tooltip and README no longer say "no path". - Video Strength and Video Attn are gone from reference-video segments (#26). They are
LTX conditioning weights inherited from the editor this one was forked from; nothing in the
H3 planner reads them, so moving them changed no output at all. The stored values stay in
old timelines and are ignored, as before.
0.2.2
Two contributions from @Brioch — #16 and #17, closing
#20 and #19 — and a new node.
-
New node: MiniMax H3 Save Last Frame. It goes straight after
VAEDecode, writes the
last frame of the batch as a PNG the way Save Image would — same counter, same
%date:…%tokens, same embedded workflow metadata — and passes the batch on. Every H3
render ends on a frame worth keeping, since it is the one you feed back in as the next
shot's opening keyframe, and fishing it out otherwise meant a second graph with
ImageFromBatchwired to aSaveImage, rebuilt every time the length changed.Two things it deliberately does not do. It never touches the pixels: the IMAGE output is
the same tensor object that came in, so it cannot change what anything downstream decodes
or muxes. And it does not need to be bypassed —saveis a widget, because a node that
has to be disabled between runs is a node that will be left enabled by accident. -
The resolution panel covers every aspect ratio the model card lists, in both
orientations. Six presets reached 16:9, 9:16 and 1:1; 21:9, 4:3 and 3:4 are in MiniMax's
own output envelope and had to be worked out by hand — from an area cap, in multiples of
32 — and typed into Width and Height. There are 26, at two sizes:Ratio Native Fast 21:9 1344×576 1120×480 2:1 1344×672 960×480 16:9 1344×768 864×480 3:2 1152×768 736×480 4:3 1024×768 640×480 5:4 960×768 608×480 1:1 992×992 640×640 4:5 768×960 480×608 3:4 768×1024 480×640 2:3 768×1152 480×736 9:16 768×1344 480×864 1:2 672×1344 480×960 9:21 576×1344 480×1120 Native keeps H3's 768 px short edge, except at the two widest ratios where 1344 is the
long-edge cap and the short edge gives way instead. Fast is the same list at a 480 px
short edge, 1:1 aside, which stays area-matched to its tier rather than dropping to
480×480. Every edge is a multiple of 32 — H3's own step, and whatdivisible_bydefaults
to — so a preset is never quietly floored to something else on the way in.0.2.1's
1920×1088is still there, under a Past native heading of its own, since it
is the one canvas here that leaves the trained envelope and the heading is what says so.
Everything above it is inside the envelope, so the list no longer mixes the two. -
Or name a shape and a pixel budget instead of a canvas. A new Aspect / MP row
takes an aspect ratio and a figure in megapixels and fills Width and Height with the best
pair of /32 edges that holds the ratio. Holding the ratio outweighs hitting the budget
exactly, and overshooting the budget is penalised twice as hard as undershooting it, since
memory is what a budget is protecting: 16:9 at 1.03 MP lands on H3's own 1344×768 rather
than the 1376×768 that is closer to true 16:9 and 2.6% more canvas. Either box works on
its own — a budget with no ratio picked rescales the shape already in the boxes — and
typing Width and Height by hand still works, with both menus following along and reading
—for a shape the ratio list does not name. -
A timeline image no longer collapses the canvas to one pixel.
resize_image's
cover-crop sized the scaled image withint(W * ratio), and a ratio that is exact in
arithmetic comes back a hair under its integer in floating point —704 * (480 / 704)is
479.99999999999994. The cover then landed one pixel short of the canvas, the centre slice
started at −1, and a 1px-wide image came out: a 704×1408 timeline image fitted to 480×640
hit the Director's canvas guard as "the canvas came out 1x640", naming a width nothing had
asked for. Roughly one source width in nine does this at a 480 px canvas, and the crop is
the default fit, so it was reachable from any preset. Rounding rather than truncating — and
requiring a cover to be at least the size of what it covers — makes it unreachable.The same truncation was quietly costing a whole 32-block in the aspect-preserving methods,
where nothing crashed and so nobody looked: maintain aspect ratio fitted a 1920×1080
image into a 1024×1024 box at 992×544 rather than the 1024×576 the code's own docstring
promises. -
A voice reference's declaration ends on the speaker's global ID, which is what the
guide means by "reuse that speaker's global ID in the definition":subject_definitions: <Audio 1> is the voice-timbre reference for <Subject 2> (S2).The ID is the speaking order rather than the subject number, so it cannot be known when
that sentence is written — it is filled in once the numbering pass has walked the finished
body. A subject who never speaks has no ID to reuse and the sentence ends on the label,
which already says whose voice the clip is. A hand-written declaration gets the same
treatment when it names the subject, and is left alone when it writes an ID of its own. -
A spoken line stays where it was written. Dialogue is lifted out of a shot prompt to be
rendered and was then appended to the end of the shot, which only looked right when the
line already came last. A line with prose after it moved:@ref1: before mid segment [Shot 1] mid segment. a woman (S1) says, mid segment → <d>[English] before mid segment</d> a woman (S1) @ref1: after mid segment says, <d>[English] after mid segment</d>It is now put back where it sat, which is how the guide writes a shot — its own Shot 1 goes
action, the line that action motivates, then more action. The same pass decides both
orderings the guide cares about, so they can no longer disagree: which mention of a subject
is its first — and so is named in full rather than by its called name — and the order
of vocal events that hands out(Sx). A frame anchor still rides with the prose rather than
trailing the shot, since a spoken line is not something a shot "begins from".</d>no
longer picks up a full stop it never needed. -
The live preview reports a line that reads as dialogue and stayed prose. The colon is
what makes a tagged line dialogue, and@ref1 says "hello sir"— the natural thing to
type — has none, so it reached the model as narration: no speaker ID, no<d>[Language] …</d>, and nothing for an<Audio N>voice reference to reuse. The line is not
reinterpreted, because prose quotes things nobody says out loud, but it is no longer
silent:[Shot 2] `@ref1 says "hello sir"` reads as dialogue but has no colon, so it stayed narration — no speaker ID, no <d>[Language] …</d>. Dialogue is `@ref1 <how it is said>: the words`.@char1 says: hellois reported the same way: the alias resolves to a subject label
everywhere, but only@refNspeaks. -
Two required fields are reported when they are empty.
detailed_descriptionjoins
overall_soundscape, which was already checked — and unlike the soundscape it has no
N/A, so an empty one leaves the section out of the prompt entirely rather than visibly
blank. A voice reference bound to a subject who never speaks is reported too, naming the
tag that would give them a line: the declaration has no(Sx)to reuse in that case, which
is correct and reads like a bug.
0.2.1
Four reports, and one of them was right about something this pack had been saying wrongly
since 0.1.0.
-
widthandheightcan be wired in (#14). The settings panel owns
custom_width/custom_heightand hides them, and a hidden widget's input slot is
never laid out — LiteGraph left it at the node's own origin, so five invisible sockets
sat stacked under the title bar. There was no reachable way to drive the canvas from a
resolution node. There are now two connection-only inputs besidestart/end/
duration, and the five orphaned slots are dropped when nothing is wired to them (a
link saved in an older workflow keeps its socket).A wire carries no minimum where a widget does, so
0— what an upstream node hands over
when its own value was never set — is refused by name rather than passed into the VAE,
the same guarddurationgrew in 0.1.2. -
A subject description reaches the ComfyUI prompt format (#14). That format resolves
@ref1to the bare<Picture 1>and has nosubject_definitionssection, so a
description typed into a slot had nowhere to go and was simply dropped: the prompt said
"<Picture 1>steps out of the doorway" and never once said who that is. It now goes
into the flatReference notes:line, subjects before pictures, so the thing is
introduced before the frame that shows it. The MiniMax format is unchanged — it has had
the section all along, and started using the description in 0.2.0. -
An API key for a cloud vision model (#15). Nothing here ever sent an
Authorizationheader, so theCustom (OpenAI-compatible)provider could only reach a
server that did not ask for one. Both the Analyze button and the Enhance node send a
bearer token now, and a 401 says where to put the key instead of echoing the endpoint's
own body.Where the key is kept mattered more than sending it. The Analyze settings live in
timeline_data, which is serialised into the workflow JSON — a key typed there would
travel with every workflow you share. So the gear menu's field writes to ComfyUI's user
settings instead, and the Enhance node's widget takes the name of an environment
variable rather than a key, because widget values are saved with the workflow.
Failing that:MINIMAX_DIRECTOR_VLM_API_KEY, thenOPENAI_API_KEY. -
4–15 seconds is the trained range, not a limit (#12). Nothing in this pack ever
capped the length, but the README said "H3's trained range is the limit" and the console
warned of "a VRAM wall" — which nobody here had measured, and which a 45-second render on
a 5090 contradicts. Both now say what is actually true: it renders, quality leaves the
envelope the model card describes, and the clock climbs faster than the video does
because attention cost goes with the square of the sequence while memory goes with its
length. -
The
2Kresolution preset is labelledpast native(#14). The model card's 2K is
not these weights at 1920×1088 — it isH3-Regenerate-2K, a separate in-context
regeneration pass, and MiniMax says "this module is not yet open-sourced. We will release
it once it is ready." The preset still exists; it no longer claims to be something it is
not. -
New offline test file,
test_node.py— 35 checks for the parts that need ComfyUI
imported, whichtest_plan.pydeliberately cannot reach: the automation-socket guards,
API-key resolution, and a check that every schema input has a matchingexecute()
parameter.test_plan.pyis up to 270.
0.2.0
Full-reference mode, from
references/ref-en.txt.
Until now a reference image was always a character, always followed as tightly as
possible, and a timeline image was always a frame anchor. The guide describes far more
than that, and two of its sections were structurally missing from the output.
-
A reference no longer has to be a character. The guide defines
<Subject N>as
"people, animals, or objects; scenes, backgrounds, or environments; clothing, props,
interfaces, or visual effects; styles, actions, expressions, or poses". Each slot now
carries a kind that supplies the noun when no description is written, so a slot can
hold a location or a look instead of a face. The panel goes from three slots to nine,
and@ref1…@ref9address them.@char1…@char3still resolve. -
A subject no longer has to have an image, which is what made subjects unreachable on
the Refs OFF (fl2va) path: the slot's text boxes only appeared once something had
been dropped on it, and fl2va discards the drop. The one thing that path can carry was
behind the one thing it throws away.references/base-en.txt
has nosubject_definitionssection at all — with no reference files there is nothing to
declare — so a subject there lives in the prose, "established when a speaker first
appears" and referred to consistently afterwards. The slot now says both halves of that:Box Becomes describes the full identity, written where the subject first appears called what to call it at every mention after that @ref1 places a fresh loaf on the counter. @ref1 says: First batch of the morning. → [Shot 1] a middle-aged baker with a calm, slightly raspy voice places a fresh loaf on the counter. the baker (S1) says, <d>[English] First batch of the morning.</d>Tags now resolve left to right through the finished video — the global block, then each
shot in turn, its prose before its dialogue — so "first" means first on screen and not
first in whichever box is being scanned. A subject introduced by its own spoken line is
named in full there. An empty called repeats the description at every mention, which
is what every timeline written before this field did. The same treatment applies with
references on to a slot that has a description but no image: no picture, no
<Subject 1>to lean on, so the prose has to carry the identity.Images left in a slot with references off are kept — switching the toolbar back must not
cost the upload — but they are dimmed, and the prompt panel now says outright that
fl2va sends none of them. -
The fl2va prompt now stops at the fields the base guide defines. Its structure is
closed — the alignment instruction, then "Three Core Fields (Required, in this order)" —
andsummaryis not among them; it belongs to the reference guide. A filled summary box
was emitting a section H3 was never trained to read on that path, task-type prefix and
all. The box is now hidden with references off and keeps its text for when the toolbar
goes back.The other half of "required" also applies:
non_diegetic_musicis written asN/Awhen
the box is empty, which is the value both guides use for having none.
overall_soundscapedeliberately does not get filled in the same way — thereN/A
means the video was asked to be silent, which is a claim only you can make — so an empty
one is called out in the prompt panel instead. H3 generates the audio; leaving that field
out hands the whole soundtrack to a guess.The 350-500 word figure is the reference guide's, for its own
detailed_description.
The base guide gives no word count, so the fl2va path no longer cites one. The word
figure is still reported either way. -
A reference no longer has to be followed exactly. Every reference carries one of the
guide's four retention markers, written intoretention_analysisverbatim because
the guide calls them "fixed English values in the output format":Marker Meaning fully_preservedThe defined role of the referenced content is fully preserved partially_preservedStill used, some defined characteristics changed attribute_transferIts characteristics move to a different target subject weak_referenceBroad similarity in style, category, composition or atmosphere only Audio uses its own set —
fully_copy,partially_copy,reference,weak_reference—
because copying a signal and imitating one are different jobs. An off-spec value coming
from an edited timeline is clamped rather than passed through into the prompt. -
Both sentences about a reference are yours to write. The guide's lines name actual
features rather than stock phrases —fully_preserved - the Samoyed's thick white fur, pointed ears, dark nose, and curved tail are retained— and name relationships the
timeline cannot work out, like<Video 1> is the source video for the target video edit.
Every reference therefore has up to two boxes, one per section it feeds:Box Becomes describes the reference's line in subject_definitions— what it isretained the sentence after the marker in retention_analysis— what survivesSubject slots carry both in the panel; timeline images, reference videos and audio clips
carry theirs in the properties panel. Either left empty falls back to the generated
sentence, so the boxes override and never oblige. Frame and storyboard anchors are the
one exception with no describes box: their declaration states where the image sits in
the video, which the timeline already knows and should not be contradicted. -
An image only gets a
<Picture N>entry when it really is one. The guide: "If an
image is used only to define a character, scene, costume, or style, do not create a
standalone picture entry. Instead, cite the image source inside the corresponding
<Subject N>definition." A timeline image can now be a frame anchor (unchanged),
a storyboard reference, or subject-defining — the last getting no picture entry
and, because it is no longer a keyframe, no longer cropped to the output canvas either. -
subject_definitionsdeclares every label;retention_analysisscores every label.
Both sections were previously incomplete: pictures were never declared, and retention
was prose. The two sections now follow the guide's shapes, and a subject's
(appears in [Shot 1], [Shot 3])is read back off the shot text rather than assumed.Both are written one entry per line, the way the guide lays them out. They are lists of
records rather than prose, and running a dozen of them together into a paragraph made it
genuinely hard to see where one label ended and the next began.0.1.5 subject_definitions: <Subject 1> is the character shown in <Picture 1>. retention_analysis: Keep the identity, face and clothing of <Subject 1> consistent across every shot. [Shot 1] begins from <Picture 2>. 0.2.0 subject_definitions: <Subject 1> is a woman in a red coat, shown in <Picture 1>. <Picture 2> is the first frame of [Shot 1]. retention_analysis: <Subject 1> (appears in [Shot 1]): fully_preserved - the collar shape and the silver necklace are retained. <Picture 2> ([Shot 1] first frame): fully_preserved - the framing and composition of <Picture 2> are retained. -
New
summarysection with a derived[task type]prefix —keyframe completion,
reference generation,audio reuse,audio reference, combined with+in the
guide's own order. It is derived from what the references are used for, not from what
is connected: the guide warns that "the mere presence of video or audio does not
automatically create a corresponding task type", so a reference video supplying only
camera movement staysreference generation. The gear menu's Task Type field
overrides it, which is the only way to reachvideo editingandvideo continuation—
neither of which this node can produce on its own. -
Frame anchors are also named inside their shot, as the guide's section 5.3 asks:
[Shot 1] she enters. The shot begins from <Picture 2>.The phrase goes after the
shot's own text, because a later shot opensAt 00:05.000,and a capitalised clause
cannot continue out of that comma. -
The reference panel resizes, and the images grow with it. The previews were locked to
52px inside a fixed 148px slot — too small to judge a reference by, and with no room for
a second text box. The panel now has the same drag strip the prompt and global-prompt
panels have, its height is remembered per node, and the previews row is the only part
that flexes, so every pixel gained goes to the image rather than to the text. -
overall_soundscape,non_diegetic_musicand the newsummarybox sit beside the
global prompt, not on top of it. The strip was absolutely positioned over the textarea,
which was shortened by a hard-codedcalc()to compensate — so the two fought over the
same space and the strip sat on the box's own border. As a flex sibling the panel divides
itself, with no second copy of the height to keep in step. -
Analyze no longer assumes every slot is a character. Its prompt said "describe the
character's physical appearance", which produced what you would expect when the image was
a coffee shop. It now asks about the slot's actual kind — a place, a garment, a pose —
and returns the description and the retained sentence togethe...
0.1.6
- The compiled prompt can be written by hand.
EDITon the prompt panel turns it into
a textarea, prefilled with what the timeline just compiled;REVERTthrows the edit away
and compiles again. Only the text is replaced — which images, videos and audio clips get
loaded still comes from the timeline, because the tokenizer emits<Picture i>in the
order the plan decided and a rewritten sentence cannot renumber that. The edit is stored
rather than merged: discarding it when a segment moves would lose work without asking,
and keeping it silently would leave a prompt that no longer matches the screen
(#4). - A timeline picture opens its shot rather than ending the video
(#4). On a hard
cut the second image starts shot 2; 0.1.5 read the fl2va anchor roles and announced it as
what the shot "ends on".ends onis now reserved for a segment explicitly flagged as an
end frame, which is the only place that intention is stated rather than inferred from
geometry. Also from #4:Keep the identity, face and clothing of …is nowappearance,
since a subject slot holds whatever was put in it and only some of those wear anything. - The preview's playback rate is a choice, not a decision made for you.
true speed
(the default, unchanged) spreads the sampled frames across the shot's real duration, so
the preview lasts as long as the finished clip — withlatent2rgbthat caps at
preview_fps / 3.35, because there is one image per latent frame and H3 compresses time
by that much.source fpsplays them at the shot's own rate the way ComfyUI's preview
does: motion reads normally, the clip ends early. Measured on a 124-frame shot: 4.65 fps
against 24.0. - Subject slots are a number you choose, 1 to 9, still 3 on a fresh node
(#8). Three was
hardcoded in four places and came from nowhere in particular; the model card caps
reference images at nine and each slot holds two.@char4and beyond resolve now. - Images on the
ref_imageswire can be described. One line ofref_image_notesper
image, emitted in the guide's own shape (<Picture 3> is a storyboard reference for …).
Blank lines are kept as placeholders so line 3 always belongs to the third image. Before
this they were numbered and the prompt said nothing about what was in them
(#8). - An audio reference can say whose voice it is
(#10). Pick a
subject on the clip and the prompt uses the reference guide's own sentence,<Audio 1> is the voice-timbre reference for <Subject 1> (S1).With more than one subject there was
previously no way to say which voice belonged to whom. Unassigned clips keep the old
wording. unload_afterreaches llama.cpp, not just Ollama
(#9).
llama-server in router mode hasPOST /models/unload; a plain one does not, and the log
now names--sleep-idle-secondsinstead of leaving a checkbox that quietly does nothing.- A canvas too small to encode is refused by name. Under 32px per side the video latent
loses an edge and ComfyUI dies six frames deep with a barefloat division by zero.
Reachable from the widgets:custom_width=4withdivisible_by=1was enough. Not the
cause of the crash reported in #4, which is still open. - Fixed: adding a widget shifted every saved value after it, so
playbackfirst landed on
webp_qualityand blocked the node with "The value 80 is not available". New widgets go
last now, a combo whose saved value is not among its options falls back to the default
with a warning instead of blocking, and both nodes grow to their minimum height on load so
the panels below a new widget cannot end up hanging outside the node body. CONTRIBUTING.md, andtest_plan.pyis up to 123 offline checks.