Commit Graph
203 Commits
Author SHA1 Message Date
digital-garbageandClaude Sonnet 4.6 28ef855893 VF-driven confidence scaling and gradient-aligned phrase boosting in conditioning memory
Two new VF-driven behaviours in _v2_apply_conditioning_memory:

1. Global confidence scalar — VF predicted reward scales all conditioning memory
   modifications: confidence_scale = (vf_score+1)/2 clamped to [0.4, 1.0].
   High score → full strength (direction is good). Low score → dampened
   (be cautious, current conditioning direction looks bad). Applies regardless
   of which prompt is active — purely VF-signal driven.

2. Gradient-aligned phrase boosting — VF gradient direction (∂reward/∂conditioning)
   is computed and compared to each axis direction slot via cosine similarity.
   Boost factor [0.5, 1.5] applied to direction strength: phrases/axes pointing
   with the reward gradient are amplified, those pointing against are dampened.
   Applies to liked_dir, missing axis repair, and satisfied axis preserve.

VF score and boost factors visible in adaptation status output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 13:47:33 +03:00
digital-garbageandClaude Sonnet 4.6 59b3b5377a Add attention weight accumulation and VF-driven temperature
Attention weight accumulation:
- Capture per-token output norm at identity blocks [14,20,21,30,33] during every
  generation via the optimized_attention patch (same path as temperature)
- EMA-merge into blessed file on liked ratings (0.8 old + 0.2 new)
- Inject as V-scaling bias on future runs: important tokens get amplified V,
  pushing attention toward historically attended positions
- Temp/blessed files cleared on session reset

VF-driven temperature:
- build_enhancements accepts conditioning=None, loads value function, scores it
- _derive_temperature_map(vf_score=) continuously modulates block temperatures:
  high VF score → sharpen (0.80×), low → warm/explore (1.20×), regardless of rating
- Rating-driven temperature still applies when reward < 0.8; VF blends with it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 13:43:11 +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 f0a8fe53d4 Fix Save Refinement Latent not executing + decouple motion floor from liked_dir
OUTPUT_NODE = True forces ComfyUI to run the node even with no downstream
connection on the LATENT output. Motion floor now activates as soon as
embed_guidance is on and a refinement key is set, independent of liked_dir.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 13:03:41 +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 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 b912bdefa2 Add |loved variants to V2_RATING_LABELS for ComfyUI validation
ComfyUI rejects widget values not in the allowed list. Generate all
valid label|loved combinations at definition time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 12:04:22 +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 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 24640a02bf Add "Nailed it" rating — prompt-adherence positive, weaker than Perfect
Restores the old "Loved it" learning behavior (reward 0.75, intent delta
+0.03, preferred context 0.65, axis conditioning 0.35, LoRA 0.44/0.24)
as a distinct rating. Sits between Perfect and Loved it on the ladder:
prompt adherence is rewarded but not at full strength.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 11:19:44 +03:00
digital-garbageandClaude Sonnet 4.6 aa47dca72b Redefine "Loved it" as axis-blind quality endorsement
Previously a weaker "Perfect". Now means: output looks great, prompt
adherence is irrelevant. Skips missing_intent_phrases learning, skips
preferred context lock-in, zeroes intent phrase reinforcement. Keeps
conditioning direction delta and raises value function reward to 0.85.
Quality/style LoRAs rewarded at Perfect level (0.55x).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 11:15:25 +03:00
digital-garbageandClaude Sonnet 4.6 ba18fc5747 Fix conditioning ascent: load value function inside inference_mode(False)
torch.load under inference_mode creates inference tensors; MLP params then
can't participate in backward. Same fix as the earlier value function loader
in samplers.py.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 10:57:50 +03:00
digital-garbageandClaude Sonnet 4.6 199d4cfee0 Clear value function on session reset
reset_session now deletes the value function .pt file alongside the
enhancement files. Previously it was orphaned across resets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 10:56:40 +03:00
digital-garbageandClaude Sonnet 4.6 3d6e06fd32 Apply conditioning ascent in Refiner V2 output (single + scene split paths)
Before returning modified_positive, ascend each scene's conditioning tensor
toward higher predicted reward via the value function. Covers both the
standalone Refiner V2 node and FunPack Studio (which delegates to refine_v2).
No-op until value function reaches MIN_SAMPLES; handles transition-split
multi-scene conditioning correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 10:46:52 +03:00
digital-garbageandClaude Sonnet 4.6 b0750d5c6d Remove predefined transition phrase list
Splitting now only fires on user-defined custom triggers (from templates)
plus the generic 'scene N' numeric pattern. The 40+ predefined English
phrases were causing unwanted splits in user-authored prompts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 04:22:46 +03:00
digital-garbageandClaude Sonnet 4.6 b16a0cadf0 Fix value function: create model inside inference_mode(False) in conditioning.py
nn.Linear weights are inference tensors if instantiated under ComfyUI's
inference_mode context. Moving the entire create+train block inside
inference_mode(False) ensures model weights are normal autograd tensors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 04:00:48 +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 5b64a06615 Revert conditioning changes added after squeeze-LTX-2 session
- Remove Studio per-scene reference image conditioning
- Revert sampler vision re-encoding prompt prefix ("Continuing from this scene:")
- Keep: sampler _vision_reencoded_conditioning mechanism (was working before)
- Keep: self_consistency (ACTIVE_BELOW now 0.75)
- Keep: duplicate-scene prefix ("Returning to an earlier scene:")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 00:56:33 +03:00
digital-garbageandClaude Sonnet 4.6 8846bdbce2 Rework vision encoding prompts for proper image framing
Sampler vision re-encoding: prefix scene text with
"Continuing from this scene: {text}" so the model treats the
previous frame as temporal context, not an unrelated subject.

Studio per-scene reference conditioning: re-enable reference_image
with prefix "The character shown performs the following: {encode_text}"
so the model knows the image is a character reference, not something
to describe. Only applies when source_image is connected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 00:43:28 +03:00
digital-garbageandClaude Sonnet 4.6 bfa2bda7ab Revert per-scene reference image encoding in Studio
Vision encoding rewrites the full conditioning embedding — with a 512-token
limit, a poor generic description from the template displaces the actual
scene prompt content. Reverting until the template can be properly designed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 00:39:20 +03:00
digital-garbageandClaude Sonnet 4.6 7d1a6f7f77 Move reference image conditioning to Studio, where the image already lives
_v2_transition_scene_conditionings was encoding per-scene texts without
the reference image — only the main single-scene conditioning path passed
it through. Now passes reference_image=source_image to all per-scene
encodings so every scene conditioning includes the character reference
via Gemma3 vision.

Removes the redundant reference_conditioning option from the chain sampler
(which required a wasteful VAE decode mid-sampling to get the pixel image
that Studio already has).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 00:28:07 +03:00
digital-garbageandClaude Sonnet 4.6 1ae350fb7b Respect anchor text punctuation when joining scene segments
If the character description ends with . ! ? or , use a space separator
instead of injecting a redundant comma. Only bare text gets the ", " join.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 21:09:45 +03:00
digital-garbageandClaude Sonnet 4.6 ed30949f58 Differentiate identical scenes via duplicate prefix + per-scene vision re-encoding
Option 1 (samplers.py): Add optional clip input to FunPackLTXAVSceneChainSampler.
After each scene is sampled, decode its last frame and re-encode the next scene's
conditioning with that frame as vision context. This gives identical scene texts
different conditioning based on temporal position, so the model knows what state
it came from.

Option 2 (conditioning.py): When building scene conditionings, detect duplicate
scene texts and prepend "Returning to an earlier scene: " before encoding the
second+ occurrence. Stores original text in funpack_scene_text for logging and
the actual encode text in funpack_encode_text so the sampler uses the same prefix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:41:48 +03:00
digital-garbageandClaude Sonnet 4.6 34fb45b475 Add vision encoding success/failure log messages in Studio
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:01:30 +03:00
digital-garbageandClaude Sonnet 4.6 8a0db7f92f Remove FunPackGemmaVision node — DualCLIPLoader already loads vision weights
LTXAVTEModel.load_sd passes the full checkpoint sd to Gemma3_12B.load_state_dict,
which has vision_model and multi_modal_projector as real attributes with matching
key names. Vision weights are already present after DualCLIPLoader runs.

Drop _vision_loaded flag check; detect vision capability by attribute existence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 19:59:11 +03:00
digital-garbageandClaude Sonnet 4.6 dbe7a68641 Log vision prompting activation in Studio encode path
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 19:11:12 +03:00
digital-garbageandClaude Sonnet 4.6 3318a2df76 Add FunPackGemmaLoader, Gemma3 vision prompting, and i2v in-context conditioning
FunPackGemmaLoader: drop-in replacement for Load CLIP Model that additionally
loads the SigLIP vision tower and multi-modal projector from Google's
Gemma3-12B-IT checkpoint into the already-initialized Gemma3_12B module,
enabling reference-image vision prompting without a separate CLIP Vision model.

Vision prompting: _v2_encode_prompt accepts reference_image; when the clip
has _vision_loaded=True, tokenizes with image=reference_image and
skip_template=False so Gemma3 sees the reference frame before generating
conditioning. Cache key includes image fingerprint to avoid stale hits.
source_image from Studio/refine_v2 flows through to _v2_conditioning_source.

K/V injection revamp (Technique 5): identity blocks in i2v mode now use
in-context conditioning instead of lerp injection. Pre-hook prepends reference
hidden-state tokens to vx and extends v_pe with neutral-rotation entries
(cos=1, sin=0) so video tokens self-attend to reference tokens in attn1.
Post-hook crops the reference prefix from the block output. Strength raised
from 0.02 → 1.0 (sigma-gated: active at 0.35–0.80). _extend_v_pe helper
handles 2-D/3-D/4-D PE tensors. Anchor blocks keep the existing lerp path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 18:53:59 +03:00
digital-garbageandClaude Sonnet 4.6 15c7c6272d Fix memory leak: write sampler context to separate file, not main V2 state
update_refinement_sampler_context was loading the main V2 state file
(which contains base64-encoded conditioning tensors) during sampling.
This re-hydrated large conditioning objects in Python's heap mid-sample,
triggering Python's cyclic GC which detected internal reference cycles
in LTXAVTEModel_ and fired the "potential memory leak" warning.

Fix: write sampler context to a tiny separate file (sampler_ctx prefix,
~60 bytes). refine_v2 reads from that file instead of state["last_sampler_context"].
The main state file is never touched during sampling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 14:56:09 +03:00
digital-garbageandClaude Sonnet 4.6 f6780f777b Refiner gen_context: route sampler settings through refinement state
Chain sampler accepts optional refinement_key_input (wire from the same
key as the V2 Refiner). On each run it calls update_refinement_sampler_context
to write carry_i2v_guides, frame_overlap, and scene count into the shared
state file. The V2 Refiner reads last_sampler_context from state when it
loads, making it available for the gen_context snapshot with no latent
manipulation and no extra Refiner inputs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 14:12:09 +03:00
digital-garbageandClaude Sonnet 4.6 5bfaf68640 Refiner gen_context: read sampler settings from latent, not forced inputs
Chain sampler now embeds funpack_sampler_context into the output latent
(carry_i2v_guides, frame_overlap, transitions_enabled). V2 Refiner reads
these from its existing latent input — no new Refiner inputs needed.
Removed the three forceInput connectors added in the previous commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 14:09:04 +03:00
digital-garbageandClaude Sonnet 4.6 aa6aa371a5 Refiner V2: track generation context and surface context-aware insights
Stores a gen_context snapshot in last_run each iteration: active LoRAs
(name/type/weight), carry_i2v_guides, frame_overlap, transitions_enabled,
and source image fingerprint. On the next run, diffs previous vs. current
context and emits targeted insights in training_info — e.g. "carry_i2v_guides
is now OFF — appearance drift is likely from missing i2v guides, not the
prompt itself" when rating is Wrong appearance. Three new optional forceInput
connectors on the V2 Refiner node: carry_i2v_guides, frame_overlap,
transitions_enabled — wire from your sampler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 14:06:23 +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 8be74dd956 Fix parse_timeline_segments: add stacking fix for phantom scenes
Shortcut expansions that start with a built-in transition phrase create
a phantom segment with no real content, causing N+1 scenes. Apply the
same stacking collapse as _v2_split_prompt_by_transitions: merge the
phantom into the following segment and drop the spurious transition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:31:41 +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 0f6a6fd674 Extract reference maps from i2v latent for automatic appearance consistency
When an i2v latent is connected (noise_mask with protected first frame),
FunPack now automatically extracts hidden state maps from the reference
image at blocks 14, 19, 21, 26, 31 via a single forward pass at sigma=0.03.
These maps are injected during generation to anchor character appearance
without requiring any prior rated runs.

Priority: reference maps from i2v > blessed maps from prior rated run.
T2v latents (no noise_mask or mask=1 throughout) are detected and skipped
cleanly - no injection happens and generation is unaffected.

Reference map injection uses fixed moderate strength (anchor 22%, identity
10%) since there is no reward signal to scale against. Blessed maps continue
to scale with reward as before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 21:07:08 +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 239d5a763e Fix custom transition triggers ending with punctuation not matching
Trailing \b after a non-word character (like '.') never matches since
\b requires a word char on one side. Custom triggers ending with
punctuation now use (?=\s|$) as the end boundary instead, so
"Scene cut." correctly splits prompts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:11:57 +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 8063566aba Fix _GENERIC_SCENE_LABEL_PATTERN matching scene as noun
The [a-z][\w-]* alternative matched any word after "scene", turning
"scene proceeds", "scene features", "scene shows" etc. into false
transition split points. Removed the over-broad alternative - the
pattern now only matches numbered scenes (scene 1, scene -2) and
"scene minus <label>" forms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:00:45 +03:00
digital-garbageandClaude Sonnet 4.6 39dba21f9f Remove single-word transition markers from builtin list
Single words like "next", "suddenly", "later", "finally" etc. fire on
normal prompt text and cause spurious scene splits. Removed the entire
single-word temporal markers block. Shortest triggers are now two words
minimum. Also removes "and suddenly" and "and next" which were similarly
too vague.

Stray article-comma cleanup ("the, next" -> "the next") also applied when
building transition segments to handle commas left by the split.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:45:29 +03:00
digital-garbageandClaude Sonnet 4.6 9b8948dc77 Fix stray comma after article in merged transition segments
When the stacking fix merges a pure-transition segment into the next one,
it now uses a space instead of ", " if the segment ends with an article
(a/an/the). This prevents "the scene then cuts to the, next view" when
"next" is also a transition word and the segments get merged mid-phrase.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:43:11 +03:00
digital-garbageandClaude Sonnet 4.6 28eabefe51 Drop dangling trailing transition segments with no real content
If a prompt ends with a transition phrase plus nothing (or just a lone
article like "the"), the last segment is now dropped rather than kept
as a near-empty scene. Covers cases like "...K/DA Kai'Sa, the scene
then cuts to the" where the user did not complete the transition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:34:06 +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