Commit Graph
92 Commits
Author SHA1 Message Date
digital-garbageandClaude Opus 4.8 597f347a91 Batch Training: remove the duplicate panel from the Studio Refiner tab
It shouldn't have been added there. The node 'Batch Training' button window is the sole
batch UI now (config when idle, rating list when finished). Removes the loadBatch() panel
and its call from renderRefiner; no leftover references, JS parses clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 18:24:42 +03:00
digital-garbageandClaude Opus 4.8 a74108de1a Batch Training UX: real window + dynamic label + no auto-queue; remove sampler input
Per feedback: Batch Training is a complete UI thing driven by Studio (the hub), not a
prompt, and it must NOT start generation itself (ComfyUI's Generate does).

- Removed batch_iterations from the Chain Sampler entirely (input + param). The sampler
  now enters batch mode ONLY when Studio packs variant markers into positive; the batch
  count lives in Studio. _run_batch_training simplified to variant-entries-only.
- The node's 'Batch Training' button now opens a dedicated window (openBatchPanel) that
  shows EITHER a config view (set batch size, Arm/Disarm) when no batch is pending, OR the
  rating list (preview + per-entry rating + Submit/Forget) when a batch has finished. It
  never queues — arming just sets refiner.batch_variants; the user presses Generate.
- Dynamic button label reflects live state: '(off)', '(armed ×N)', '(Processing…)',
  '(Finished — rate)'. Driven by execution_start/success/error listeners, which also
  one-shot disarm after a batch runs so the next Generate is normal.

The older in-Refiner-tab batch panel remains functional (secondary path); the node-button
window is now the primary entry point.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 18:21:42 +03:00
digital-garbageandClaude Opus 4.8 a1ba067d9a Batch Training Phase 3b: deeper learning from batch ratings (axis + direction memory)
Submit now does more than train the value function (3a). New refiner method
_v2_learn_from_batch feeds each rated entry's conditioning through the SAME per-axis
direction-memory machinery as a normal rated run (_v2_update_conditioning_memory →
axis directions + liked/bad direction stores), and tallies axis votes across the batch:
because tokens were frozen, an axis rated missing/wrong in >= half the rated entries is a
high-confidence problem (not seed luck). Those consistent axes are written to
active_repair_axes, which the next generation's repair persists until a Perfect — so a
batch where most gens were 'Missing details' makes the next run boost details.

Wiring: batch submit collects (rating, serialized cond) per rated entry, trains the VF,
then calls _v2_learn_from_batch; the resulting insight ('consistent problem axes = ...')
is returned and shown in the Studio submit toast. List route now also returns each item's
variant index + prompt for the panel.

Batch Training is now complete: seed-only + shortcut variants + node button + VF training
+ axis/direction learning, all human-rated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 18:07:01 +03:00
digital-garbageandClaude Opus 4.8 9fe10533e4 Batch Training: variant producer (Studio) + node button — feature complete end-to-end
Producer (Studio owns conditioning, per the boundary law): refine_v2 gains batch_variants.
When >1, _v2_build_batch_variants packs N conditioning entries into the single positive wire,
each tagged 'funpack_batch_variant'. Variant 0 is the fully-processed base; variants 1..N-1
re-resolve shortcuts with seed+i (random option per entry) and get the same conditioning-memory
treatment, deduped by expansion text. No shortcut variability -> all entries resolve identical
and reuse the base cond -> the batch becomes seed-only (sampler varies the seed per entry).
Captures the pre-shortcut prompt to re-resolve. Not combined with split_by_transitions.

Trigger: a 'Batch Training' button on the Studio NODE (next to Open Studio) — prompts for N,
sets refiner.batch_variants, queues one prompt, then auto-reverts to 1 (one-shot). Studio is
the batch trigger (hub principle); no sampler input needed.

Sampler: now enters batch mode when positive carries variant markers, even if batch_iterations
is 1 (markers are the trigger; variant count wins). Each entry already saves its own cond, so
Submit trains the VF per variant — teaching which prompt variant rated better. Panel hints now
point at the button.

End-to-end: press Batch Training -> N -> Studio makes N variant conds -> sampler samples N ->
previews to temp -> rate in Studio panel -> Submit trains VF per entry -> batch cleared.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 18:00:32 +03:00
digital-garbageandClaude Opus 4.8 d423d313fe Batch Training: sampler consumes Studio variant-packed conditioning (Phase 4 contract)
Per the Studio/sampler boundary law (Studio owns conditioning; sampler only samples), the
sampler no longer encodes anything. It now auto-detects when Studio has packed N shortcut
VARIANTS into positive — each scene entry tagged with 'funpack_batch_variant' = variant
index — via _split_batch_variants: if present, it samples one chain per variant (variant
count wins); otherwise it falls back to seed-only repeats of batch_iterations. Decisions:
'sampler loops, Studio varies' + 'pack into positive + markers'.

Each entry now saves its OWN conditioning (<id>.cond.pt) — identical across a seed-only
batch, distinct per variant — and the manifest records variant index + prompt per item.
Submit (batch_training.py) trains the VF per entry from its own cond, so variant batches
teach the model which prompt variant rated better (not just seed-quality variance). Studio
panel shows the variant tag + prompt per row.

Studio-side variant PRODUCTION (resolve shortcuts N times, encode, pack markers) is the
remaining half — a Studio/refiner feature, tracked next. Sampler side is ready for it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 17:49:52 +03:00
digital-garbageandClaude Opus 4.8 b4f218b875 Batch Training (Phase 2+3): Studio rating panel, /funpack/batch routes, VF intake on submit
Phase 1 amended: the engine now also saves the frozen conditioning (cond.pt) per batch
so submit can train on (cond, rating).

Phase 2 (panel + API): new batch_training.py registers /funpack/batch/{list,submit,forget}
(follows the existing /funpack/* PromptServer pattern). Studio gains a 'Batch Training'
section under the refiner: lists the pending batch for the active refinement key with each
entry's filename + seed, a Preview button (loads the temp webp via /view?type=temp), and a
per-entry V2-rating dropdown, plus Submit and 'Forget batch'. Previews served straight from
ComfyUI temp — no custom file route needed.

Phase 3 (learning intake): Submit loads cond.pt and trains the value function on
(cond, reward) for every rated entry — same conditioning, N rewards = variance-reduction
RLHF, which directly sharpens conditioning ascent. '-Just forget it-'/unknown ratings are
skipped. Submit consumes (deletes) the batch; Forget discards it without learning. Either
way the panel clears and the sampler is ready for a new batch.

Human stays the rating oracle throughout (no auto-rating) — 'user over everything'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 17:34:06 +03:00
digital-garbageandClaude Opus 4.8 71c5afc668 Refiner V2: always train value function; value_guidance gates application only, default on
Audit finding: value_guidance defaulted OFF, and it gated value-function TRAINING — so
by default the VF never trained, conditioning ascent + the chain sampler's embed_guidance
were permanently inert, and a user who ran many gens with it off then enabled it started
from zero (no accumulated learning).

Fix decouples learning from application:
- The VF now ALWAYS trains in the background on rated gens (cheap: small MLP, 20 steps,
  no diffusion calls) whenever there's a rated previous run + refinement key. The reward
  asset accumulates regardless of the toggle.
- value_guidance now controls only APPLICATION of the learned direction (output ascent +
  search), via a new apply= param on _v2_ascend_conditioning. Default ON.
- Defaults flipped to True: refine_v2 signature, Studio settings read, JS default +
  migration. Studio toggle relabeled 'Apply value guidance' with corrected help (training
  always on; applies after 10+ ratings; off = strict prompt fidelity, learning still
  accumulates). Fixed stale '5+ ratings' text (MIN_SAMPLES is 10).

Side effect: embed_guidance (chain sampler) now has a trained VF available by default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 16:56:59 +03:00
digital-garbageandClaude Opus 4.8 963198b999 Audit fixes: velocity commit key mismatch, sparse rescue targets, redundant aspect bucket
Three issues found tracing the full Studio path with all features on:

1) BUG (silent data loss): a custom velocity_refinement_key captured trajectories
   under that key but the refiner committed the rating under the effective refinement
   key — so custom velocity keys never learned (banks stayed empty, rescue/velocity a
   permanent no-op). This undercut per-key cut-routing. Fix: Studio resolves each pass's
   velocity key (same logic as _build_one_sampler) and passes them to refine_v2, which
   now commits the verdict to the union of {effective key} + velocity keys (dedup).
   Backward compatible (callers without _velocity_keys behave as before).

2) Effectiveness: VELOCITY_BIAS_TARGETS (0.90, 0.80) matched only sigma~0.909 on the
   standard 8-step LTX schedule, so rescue fired once per gen at a near-noise step and
   never at the detail-forming sigmas. Broadened to (0.90, 0.72, 0.42) -> hits 0.909,
   0.725, 0.422. Velocity APPLY still structure-only (highest target); rescue now acts
   where runs actually go good/bad. (New detail targets fill as gens are rated.)

3) Redundant value: velocity_aspect_bucket was a manual text field never tied to actual
   resolution, and the bank key already includes the full latent shape (which encodes
   resolution) — so it was doubly redundant. Removed from the key, all sampler plumbing,
   INPUT_TYPES, Studio build, and the JS UI/defaults. Persistence loads old stores fine
   (the 'aspect' field is simply ignored; key is now (refkey, target, shape)).

Verified: both py files + JS parse clean; all refactored call signatures aligned.
Tests require the ComfyUI venv (torch) to run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 16:38:31 +03:00
digital-garbageandClaude Opus 4.8 2a22d58ff0 Studio: Variability macro + active-feature readout for Hybrid sampler
UX/variability win — collapse the expert knob-soup into one control plus a
legible summary.

- Variability macro (Chill/Spicy/Chaos presets + 0..1 slider) orchestrates the
  stochastic knobs: eta (video variability), eta_final (late-noise ramp, only at
  high chaos), quality_sharpness (detail recovery as noise rises), velocity spice
  (action injection past Spicy, source=nearest), and motion pulses. Deliberately
  keeps high_quality_pct>0 (disabling the deterministic finisher under ancestral
  noise = mess). Writes the existing hybrid fields; all still individually editable.
- 'Active features (this config)' readout: green/grey rows for ancestral noise,
  velocity spice, rescue, quality pass, motion pulses — turns the invisible stack
  legible. Notes audio is auto-held deterministic on LTXAV.

Frontend-only; no model/Python changes (all fields already plumb through).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 15:33:55 +03:00
digital-garbageandClaude Opus 4.8 77a3238c47 Unlock velocity_bias_strength for creative action injection (0.35 -> 3.0)
The real limiter wasn't the 0.35 slider cap but the internal fixed 4.5%-of-|x|
delta clamp, which saturated almost immediately — the upper slider range was a
no-op. Now the rotation cap scales with strength (0.30*strength, capped 0.95), so
the whole range is meaningful: ~0.15 subtle spice (matches old feel), 0.3-1.0 clear
action crossover, 2-3 approaches full action replacement without wiping the current
gen. Magnitude-preserving renorm still keeps |x|, so high strength rotates rather
than blows up. Raised the param/UI cap to 3.0 and updated the tooltip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 14:52:44 +03:00
digital-garbageandClaude Opus 4.8 f7acc91570 Velocity-bias anti-softening: magnitude-preserving apply, sigma-decay, quality sharpness, nearest-cluster source
Compensate the slow quality degradation from velocity-bias 'apply' (additive
mean-pull) with four guards on the Hybrid Euler 2S sampler (both eps and
rectified-flow/LTXAV paths):

- B: apply is now magnitude-preserving — rotate x toward (x+delta) and
  renormalize to |x| instead of x+delta, so no energy is injected.
- C: apply fires only at the highest (structure) velocity target and decays
  strength with the sigma ratio; detail sigmas left untouched.
- E: new quality_sharpness knob — temporal-average unsharp on the x0 prediction
  during the quality phase to restore high-frequency detail (free, no extra eval).
  Default 0.0 (off).
- D: new velocity_bias_source = mean|nearest — 'nearest' steers toward the single
  best-matching prompt cluster (one real good gen's detail) instead of the
  washed-out average. Affects both apply and rescue. Default 'mean' (off).

Plumbed through get_sampler/INPUT_TYPES, Studio _build_one_sampler, and the
Studio JS sampler panel (both presets + UI controls).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 13:45:55 +03:00
digital-garbageandClaude Opus 4.8 323945fa46 Make rescue rating-gated with separate good/bad trajectory banks
Root cause of "rescued toward an Awful gen": velocity capture was
rating-blind — it wrote every sampled trajectory straight into the one
"good" memory, so a fresh key whose only capture was an awful gen made that
awful run the sole steering target. Ratings (which live in the refiner) never
touched the bank.

Now:
- capture STAGES the current gen's trajectory (VELOCITY_BIAS_PENDING) instead
  of committing it; staging runs whenever rescue is on (no separate capture
  toggle needed).
- the refiner commits the previous gen's staged trajectory by its rating:
  like/loved/nailed -> good bank, awful -> bad bank, everything else dropped.
- rescue steers TOWARD the good bank and AWAY from the bad bank (per prompt
  cluster), firing when diverged from good OR aligned with bad beyond
  threshold; no-op when neither bank has a prompt match.
- session reset / clear_refinement_data now clears good + bad + pending.

velocity-bias "apply" now also reads the rating-gated good bank. Tooltips and
Studio note updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 19:08:22 +03:00
digital-garbageandClaude Opus 4.8 a69c914c18 Default velocity/rescue memory key to Studio's wired refinement key
The velocity_refinement_key (namespace for trajectory capture + rescue
clusters) was a separate field defaulting to "default", easy to drift out
of sync with the refinement key Studio actually uses. Now when it is blank
or left at "default", Studio resolves it to the effective refinement key
(same resolution as seed memory / refine_v2), so capture and rescue share
one bucket automatically. An explicit non-default value is still respected.
JS hint added on the velocity key field.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:13:41 +03:00
digital-garbageandClaude Opus 4.8 22b0b9c8d7 Expose reactive rescue in Studio Hybrid Euler-2S sampler config
Studio builds its sampler via FunPackHybridEuler2SSampler.get_sampler but
did not pass the new rescue params. Thread rescue_mode/threshold/strength
through _build_one_sampler, add them to the Studio JS hybrid defaults
(high+low) and the sampler config panel, with a note that rescue needs the
velocity-bias memory captured first.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 17:58:58 +03:00
digital-garbageandClaude Sonnet 4.6 776e0a6b12 Remove latent VF and motion floor — inaccessible in LTX token format
LTX packs all spatial/temporal dims into a single token [1, 1, C*T*H*W]
during sampling. Per-step latent steering requires hooking into the model
internals, not the k-diffusion callback. Removed: compress_latent(),
_load_latent_value_function(), latent VF training, motion floor callback,
latent_value_guidance toggle in Studio.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 13:24:29 +03:00
digital-garbageandClaude Sonnet 4.6 179398c58a Fix rating picker: stale onOutside listener closed re-opened picker
closePicker() didn't remove the mousedown listener, so clicking the button
to re-open the picker would immediately close it. Now stores the cleanup
in module scope and calls it from closePicker().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:41:07 +03:00
digital-garbageandClaude Sonnet 4.6 18d879d8c1 Add latent value function — VGG-Flow style per-step latent steering
Trains a second OnlineValueFunction on rated video latents (compressed via
channel mean-pool). At each denoising step, computes ∂reward/∂latent through
the lightweight MLP and applies it as an in-place drift to the noisy latent —
gradients never touch the 22B transformer. Controlled by embed_guidance_strength
alongside the existing conditioning guidance. Studio toggle: "Latent guidance".
Cleared on session reset alongside the conditioning VF.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:40:03 +03:00
digital-garbageandClaude Sonnet 4.6 9187379a38 Clarify heart modifier semantics + fix positive grid + Nailed it heart
Heart modifier now applies full axis pressure (not 50% softened) — meaning
"fix this specific issue but the quality direction was great." The quality
signal comes from boosted reward and conditioning delta, not from reducing
axis pressure. Nailed it + heart removed (that's just Perfect). Positive
grid changed to 1fr 1fr to fill width with 2 items.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:13:15 +03:00
digital-garbageandClaude Sonnet 4.6 b8fdf38a77 Remove standalone "Loved it" rating — replaced by heart modifier
The ♥ button on any rating covers the same semantic. Removed from picker
UI and V2_RATING_LABELS; profile kept in Python for backward compat.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:08:46 +03:00
digital-garbageandClaude Sonnet 4.6 f9f9b27cd4 Fix active state not updating on option change in rating picker
Active class was static (set at creation). Now all option elements are
tracked and active state is updated dynamically on each pick.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:07:46 +03:00
digital-garbageandClaude Sonnet 4.6 86ef472ed6 Disable heart for quality-degraded ratings
Missing quality, Missing details+quality, Missing action+quality, and
Wrong action+quality can't meaningfully be loved — no heart button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:05:24 +03:00
digital-garbageandClaude Sonnet 4.6 bbfe1201e2 Disable heart button for Awful rating
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:03:48 +03:00
digital-garbageandClaude Sonnet 4.6 757947fff0 Replace Loved it toggle with per-option heart button
Each rating option now has a small ♥ button on its right. Clicking the main
label applies the base rating; clicking ♥ applies label|loved. No toggle
state — simpler and more direct.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:01:12 +03:00
digital-garbageandClaude Sonnet 4.6 e9a1510db0 Add "Loved it" modifier to rating picker
Any rating can now be combined with a "Loved it" toggle. The suffix |loved
is appended to the rating string and parsed in normalize_refiner_v2_rating.

When active: reward boosted to max(base, 0.85), axis pressure softened 50%,
conditioning direction delta raised to 0.45, preferred context applied at
0.30 base_delta. Disabled for Perfect (redundant) and -Just forget it-.
Button label shows ♥ when modifier is active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 11:55:17 +03:00
digital-garbageandClaude Sonnet 4.6 d7a1400239 Close rating picker on selection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 11:44:02 +03:00
digital-garbageandClaude Sonnet 4.6 a4d1f67502 Fix rating picker clicks: use canvas button widget instead of DOM element
addDOMWidget clicks were swallowed by the canvas. Switched to addWidget
button which ComfyUI routes correctly. Picker now positions at mouse coords
from the widget callback event.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 11:42:46 +03:00
digital-garbageandClaude Sonnet 4.6 94d1b86493 Show "Waiting for rating..." on button when no rating chosen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 11:34:50 +03:00
digital-garbageandClaude Sonnet 4.6 a539bb9b9e Add rating picker popup + Wrong action + quality rating
Replaces the rating dropdown on Studio and Refiner V2 nodes with a button
that opens a categorized floating picker. Each option shows its reward value
and a one-line hint. Rating auto-resets to -Just forget it- after execution
so forgotten ratings don't silently apply to the next run.

Also adds Wrong action + quality (reward -0.40, wrong_axes action, missing
quality) and drops Wrong action reward from +0.10 to -0.10.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 11:33:41 +03:00
digital-garbageandClaude Sonnet 4.6 f1b54da9dd Add value function export/import to Studio
Two server routes (GET /funpack/value_function/export, POST /funpack/value_function/import)
serve and receive the .pt binary. Studio Session tab gains Export and Import buttons
below the value guidance toggle, keyed to the active refinement key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 11:04:10 +03:00
digital-garbageandClaude Sonnet 4.6 44e694695e Add online value function for reward-guided sampling
value_function.py: OnlineValueFunction MLP that trains incrementally on
(conditioning, reward) pairs. Uses replay buffer of 100 samples, 20
gradient steps per update. save/load to .pt file via refinement_state_path.

Studio popup: new "Value guidance" toggle. When on, trains the value function
after every rated generation (good and bad). Falls back to no-op if conditioning
deserialization fails.

chain sampler: _load_value_function reads the trained MLP if ready (5+
samples). _build_embed_guidance_wrapper uses value function gradient
(∂reward/∂conditioning) when available, fixed liked direction as fallback.
Log reports which mode is active and sample count.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 03:45:18 +03:00
digital-garbageandClaude Sonnet 4.6 f71c2c4a67 Add vision conditioning toggle to Studio popup
Reads settings.refiner.vision_conditioning (default true) and gates
source_image passed as reference_image to Gemma3 encoding. Toggle lives
in the popup UI next to Reference injection, not on the node.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 01:18:03 +03:00
digital-garbageandClaude Sonnet 4.6 f797c535d9 Fix timeline scene count: treat segments[0] as anchor, not a scene
Mirrors _v2_transition_scene_texts: the text before the first
transition is a character anchor prepended to every scene, not a scene
itself. Show it separately above the rail. scenes[] now matches what
the Scene Chain sampler actually generates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:46:32 +03:00
digital-garbageandClaude Sonnet 4.6 6f540791fe Rewrite timeline parsing to use the actual Studio splitter
Extract _v2_split_prompt_by_transitions to module-level
split_prompt_by_transitions. parse_timeline_segments now calls it
directly with placement=silent — same code path as generation.
Eliminates all reimplemented splitting logic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:44:00 +03:00
digital-garbageandClaude Sonnet 4.6 9da5be057e Fix stacking collapse for empty phantom scenes; add Timeline Refresh button
Empty string is falsy so the stacking guard was skipping the phantom
collapse when the first segment was empty. Remove the truthy check so
both empty and transition-only segments are collapsed correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:37:45 +03:00
digital-garbageandClaude Sonnet 4.6 0bfaff0d1b Fix Timeline: expand shortcuts before splitting into scenes
The pipeline is shortcuts → transitions → split. The route now runs
apply_prompt_shortcuts first, then parse_timeline_segments on the
expanded text, matching actual generation behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:25:58 +03:00
digital-garbageandClaude Sonnet 4.6 e680cc8d6a Fix Timeline tab: follow link to read connected positive_prompt node
widgetByName returns nothing when the input is connected. Traverse the
graph link to the source node and read its first widget value instead.
Also fix custom_map always being empty when refinement_key is set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:20:49 +03:00
digital-garbageandClaude Sonnet 4.6 efba52d951 Add Timeline preview tab to Studio
Read-only horizontal timeline showing detected scenes as boxes with
transition connectors between them. Backed by a new
POST /funpack/parse_timeline route and parse_timeline_segments() in
conditioning.py that reuses the existing transition phrase patterns
and custom transition map.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:11:07 +03:00
digital-garbageandClaude Sonnet 4.6 9dbd239702 Add visual transition effects to scene chain sampler
Custom transition triggers in Studio can now have a visual_effect assigned
(fade_to_black, crossfade, blur_out_in). When triggered during scene splitting,
the effect fires at that scene boundary: the sampler decodes the latent window
around the boundary, applies the pixel-space effect, and re-encodes in-place.

No new nodes needed — VAE is already connected to the scene chain sampler.
New transition_duration input controls how many pixel frames are affected.
New scene_boundaries output provides the boundary list for debugging.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 17:50:31 +03:00
digital-garbageandClaude Sonnet 4.6 f6c761746f Add Reference injection toggle to Studio, off by default
The i2v hidden state injection only produces meaningful results alongside
carry_i2v_guides in the Scene Chain Sampler. Without it the injection
has no reliable reference to anchor from (proven through testing).

New Studio Refiner setting: "Reference injection" toggle (default off).
Hint explains it should be enabled together with carry_i2v_guides.
Passing reference_latent=None to build_enhancements when disabled so
the entire injection path is skipped cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 22:59:42 +03:00
digital-garbageandClaude Sonnet 4.6 223e60e832 Add silent transition placement - split without outputting the trigger
New placement option 'silent': the transition phrase marks the scene
boundary but is stripped from the output entirely. Neither the previous
nor the next segment contains it. Available globally and as a per-entry
override on custom transitions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:38:29 +03:00
digital-garbageandClaude Sonnet 4.6 5e1aa4a6c3 Add transition placement control (start/end of segment)
- Global setting in Studio Refiner tab: "Transition placement" (start/end).
  start = transition opens the new segment (existing default behavior).
  end = transition closes the previous segment instead.
- Per-entry placement override in Transitions tab (global/start/end).
  Custom transitions can pin their placement regardless of the global setting.
- transition items gain a placement field (global/start/end, defaults to global).
- load_custom_transition_triggers returns {trigger_lower: placement|None} so
  the split function can do per-trigger lookups efficiently.
- refine_v2 and Studio.run() wired with split_transition_placement parameter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:10:13 +03:00
digital-garbageandClaude Sonnet 4.6 acdc4c41d6 Collapsible shortcut/transition rows, optional replacement, name fallback
- Shortcuts and Transitions: saved entries collapse to a summary row (name +
  on/off badge); click to expand, Collapse button to close without saving
- Transition summary also shows trigger phrase in italic next to the name
- Shortcuts: replacement is no longer required; blank/missing defaults to [""]
  which removes the matched phrase (same as explicit empty replacement)
- Shortcuts: name falls back to first activation word when left blank
- New summary row CSS: badge-on/badge-off, label, trigger styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:16:59 +03:00
digital-garbageandClaude Sonnet 4.6 889e4dc2c8 Add shortcuts empty replacement, custom transitions, and longer-phrase-wins tests
- Shortcuts: allow empty string as a valid replacement to remove matched phrases
  from prompts; post-pass cleans up orphaned commas/spaces left by removals
- Shortcuts: add cross-shortcut longer-phrase-wins test confirming ordered
  alternation handles multiple shortcuts with overlapping triggers correctly
- Transitions: new user-editable transition word list stored in transitions.json;
  custom triggers extend the built-in split pattern at runtime, keyed by name
- Transitions: Studio JS gets a dedicated Transitions tab (name, trigger, enabled)
  with Add/Refresh/Import/Export toolbar
- Transitions: four API routes mirroring shortcuts (GET, export, save/delete, import)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 17:47:55 +03:00
digital-garbage 3434d1efa2 Add global scene shortcuts 2026-05-22 16:38:33 +03:00
digital-garbage 87db442476 Fix order-only scene splitting 2026-05-21 00:14:45 +03:00
digital-garbage 9352c5f556 Add LTXAV scene chain sampler 2026-05-20 19:51:06 +03:00
digital-garbage e8f0b0f83f Remove standalone scene transition nodes 2026-05-20 19:29:33 +03:00
digital-garbageandClaude Sonnet 4.6 56f0f30b7a Remove transition_contrast - no longer needed
With split_by_transitions outputting a single conditioning, the contrastive
conditioning math has nothing to act on. Removed from Refiner V2 inputs,
refine_v2 signature, Studio JSON settings, Studio popup UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 18:52:43 +03:00
digital-garbageandClaude Sonnet 4.6 a8cda301c9 Add contrastive scene conditioning to sharpen transition cuts
For each context window, apply:
  window_i = general + contrast × (scene_i − general)

where general = the full-prompt conditioning (refined, with memory
applied). The character description cancels in the delta because it
appears in both scene_i and general; the push focuses on what is
unique to each scene (action, environment).

- contrast=1.0 → plain scene encoding (original behaviour)
- contrast=1.5 → default, 50% extra push toward scene content
- contrast=2.0 → classic contrastive (2×scene − general)

New parameter: transition_contrast (FLOAT, default 1.5, range 1.0-4.0)
on Refiner V2 and in Studio popup Refiner tab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 16:14:24 +03:00
digital-garbageandClaude Sonnet 4.6 012b2ca3c2 Fix context windows dim detection and Studio toggle
Context Transition Windows: auto-detect temporal dim by scanning
x_in's axes for a size that's > overlap and <= 4096. Search order:
dim 2 (standard [B,C,T,H,W]), dim 1, dim 0 (LTXAV packs frames at 0),
then remaining dims. Skip windowing entirely when no suitable dim is
found (packed formats where no axis maps to frame count).

Studio JS: fix 'Split by transitions' toggle showing 'undefined' -
was appending splitToggle.container which doesn't exist; corrected
to splitToggle.wrap (the actual property returned by toggleEl).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 15:28:36 +03:00