Wire Qwen Turbo toggle through Studio 2 and the runner.

Force 6/1 when Turbo is on, skip negatives, keep PE in front, and fail closed if the r128 LoRA is missing.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-26 12:42:00 -05:00
co-authored by Cursor
parent 17cbc99f8f
commit ecc4c69a8b
8 changed files with 110 additions and 31 deletions
+24 -3
View File
@@ -119,6 +119,12 @@
<label v-if="form.engine==='qwen21' && (form.mode==='generate' || form.mode==='edit')" class="inline-flex items-center gap-2 text-[var(--type-sm)] text-[var(--muted)]">
<input v-model="form.enhancePrompt" type="checkbox" class="accent-[var(--amber)]">Enhance prompt
</label>
<div v-if="form.engine==='qwen21' && (form.mode==='generate' || form.mode==='edit')" class="flex flex-col gap-1">
<label class="inline-flex items-center gap-2 text-[var(--type-sm)] text-[var(--muted)]">
<input v-model="form.turbo" type="checkbox" class="accent-[var(--amber)]">Turbo
</label>
<p v-if="form.turbo" class="text-[11px] text-[var(--muted)]">6-step Viggle distill. CFG stays 1. Enhance prompt recommended.</p>
</div>
<div>
<span class="field-label">Negative prompt</span>
@@ -379,6 +385,7 @@ import {LOAD_GENERATION_PAYLOAD_KEY} from '~/utils/queuedJob'
const NEG_STORAGE_KEY='studio2-negative-chips'
const ENHANCE_STORAGE_KEY='studio2-qwen21-enhance-prompt'
const TURBO_STORAGE_KEY='studio2-qwen21-turbo'
function readStoredNegatives(){
if(!import.meta.client)return [...defaultNegatives]
try{
@@ -400,6 +407,14 @@ function writeStoredEnhancePrompt(on:boolean){
if(!import.meta.client)return
try{localStorage.setItem(ENHANCE_STORAGE_KEY,on?'1':'0')}catch{/* ignore */}
}
function readStoredTurbo(){
if(!import.meta.client)return false
try{return localStorage.getItem(TURBO_STORAGE_KEY)==='1'}catch{return false}
}
function writeStoredTurbo(on:boolean){
if(!import.meta.client)return
try{localStorage.setItem(TURBO_STORAGE_KEY,on?'1':'0')}catch{/* ignore */}
}
const xaigen=isXaigenStudio(useRuntimeConfig().public)
const instanceName=String(useRuntimeConfig().public.instanceName || 'AIGen')
@@ -419,7 +434,7 @@ const liveMusic=ref<Record<string,any>>({})
const negativeDraft=ref('')
const filmstripEl=ref<HTMLElement|null>(null)
const tileRefs=new Map<string,HTMLElement>()
const form=reactive<any>({mode:'generate',engine:'flux',enhancePrompt:readStoredEnhancePrompt(),imageStyles:{positive:[],negative:readStoredNegatives()},lockFace:true,lockOutfit:true,hideInput:xaigen,folderId:'',identityStillId:'',imageAId:'',imageBId:'',maskId:'',startClipId:'',endStillId:'',guides:[],promptSections:sectionsFrom({}),settings:{aspect:'auto',fps:24,steps:24,cfg:4,seed:null,seedMode:'random',duration:5,turbo:true,loraStack:[]}})
const form=reactive<any>({mode:'generate',engine:'flux',enhancePrompt:readStoredEnhancePrompt(),turbo:readStoredTurbo(),imageStyles:{positive:[],negative:readStoredNegatives()},lockFace:true,lockOutfit:true,hideInput:xaigen,folderId:'',identityStillId:'',imageAId:'',imageBId:'',maskId:'',startClipId:'',endStillId:'',guides:[],promptSections:sectionsFrom({}),settings:{aspect:'auto',fps:24,steps:24,cfg:4,seed:null,seedMode:'random',duration:5,turbo:true,loraStack:[]}})
const music=reactive({tags:DEFAULT_MUSIC_TAGS,lyrics:DEFAULT_MUSIC_LYRICS,duration:60,seed:'',name:''})
const tagsPlaceholder=DEFAULT_MUSIC_TAGS,lyricsPlaceholder=DEFAULT_MUSIC_LYRICS
let loraMemory=createLoraMemory(xaigen)
@@ -456,7 +471,7 @@ watch(engineOptions,opts=>{
})
watch(()=>form.engine,(engine,prev)=>{
if(engine==='qwen21' && prev!=='qwen21'){
form.settings.steps=25
form.settings.steps=form.turbo?6:25
form.settings.cfg=1
form.lockFace=false
form.lockOutfit=false
@@ -464,9 +479,15 @@ watch(()=>form.engine,(engine,prev)=>{
}
})
watch(()=>form.enhancePrompt,on=>writeStoredEnhancePrompt(!!on))
watch(()=>form.turbo,on=>{
writeStoredTurbo(!!on)
if(form.engine!=='qwen21')return
form.settings.steps=on?6:25
form.settings.cfg=1
})
watch(()=>[form.mode,form.engine],([mode,engine])=>{
if(engine==='qwen21' && mode==='edit'){
form.settings.steps=25
form.settings.steps=form.turbo?6:25
form.settings.cfg=1
form.lockFace=false
form.lockOutfit=false
+3
View File
@@ -22,6 +22,9 @@ const rows=computed(()=>{const m=props.metadata||{},s=m.settings||{};const time=
{label:'Compiled prompt',value:m.compiledPrompt},
{label:'Prompt (raw)',value:m.promptRaw || null},
{label:'Enhance prompt',value:m.enhancePrompt==null?null:m.enhancePrompt?'On':'Off'},
{label:'Turbo',value:m.turbo==null?null:m.turbo?'On':'Off'},
{label:'Turbo LoRA',value:m.lora || null},
{label:'Turbo sigmas',value:m.sigmas || null},
{label:'Enhance wh_ratio',value:m.enhance?.wh_ratio || null},
{label:'Enhance ratio_follow',value:m.enhance?.ratio_follow || null},
{label:'Enhance parse_ok',value:m.enhance?.parse_ok==null?null:m.enhance.parse_ok?'Yes':'No'},
+2
View File
@@ -159,6 +159,8 @@
<template v-else>
<label class="m-label">Prompt<textarea v-model="ctx.form.promptSections.action" rows="5" class="m-area" placeholder="Describe the image or the shot." /></label>
<label v-if="ctx.form.engine==='qwen21' && (ctx.form.mode==='generate' || ctx.form.mode==='edit')" class="m-check"><input v-model="ctx.form.enhancePrompt" type="checkbox"> Enhance prompt</label>
<label v-if="ctx.form.engine==='qwen21' && (ctx.form.mode==='generate' || ctx.form.mode==='edit')" class="m-check"><input v-model="ctx.form.turbo" type="checkbox"> Turbo</label>
<p v-if="ctx.form.engine==='qwen21' && ctx.form.turbo" class="m-muted">6-step Viggle distill. CFG stays 1. Enhance prompt recommended.</p>
<div>
<span class="m-label">Negative prompt</span>
<div class="m-neg">