Make Studio 2 the home bench with YuE2 music, LTX, and per-preview hide.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-15 18:19:34 -05:00
co-authored by Cursor
parent a216afc4ce
commit 1db62e9187
14 changed files with 413 additions and 330 deletions
+8 -10
View File
@@ -1,9 +1,6 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import {readFileSync} from 'node:fs'
import * as Vue from 'vue'
import {compile} from '@vue/compiler-dom'
import {renderToString} from '@vue/server-renderer'
import ts from 'typescript'
import {folderAssets,reconcileSelection,activeJobs,previewHidden} from '../shared/studio2/viewer.mjs'
import {useAsHero,useAsSource,restoreAll} from '../shared/studio2/input.mjs'
@@ -24,14 +21,15 @@ test('bench includes only active execution phases and clear finished retains int
assert.equal(fn({}).cleared,1);assert.equal(rows[0].dismissed,true);assert.equal(rows[0].cleanupPending.length,1);assert.equal(rows[1].dismissed,undefined)
})
test('hidden xAIGen canvas and family render no image or video elements',async()=>{
const revealed=new Set()
assert.equal(previewHidden({id:'a',role:'input'},revealed,true),true)
assert.equal(previewHidden({id:'a',role:'input'},new Set(['a']),true),false)
assert.equal(previewHidden({id:'a'},revealed,false),false)
const src=readFileSync(new URL('../components/studio2/Bench.vue',import.meta.url),'utf8')
const stage=src.slice(src.indexOf(' <div class="flex min-h-80'),src.indexOf(' <div v-if="selected"'))
const strip=src.split('\n').find(line=>line.includes('aria-label="Current family outputs"'))
const render=new Function('Vue',compile('<section>'+stage+strip+'</section>',{mode:'function',prefixIdentifiers:true}).code)(Vue)
const state={selected:{id:'a',kind:'still'},hideOutput:true,xaigen:true,family:[{id:'a',kind:'still'}],form:{hideInput:true},previewHidden,stillUrl:id=>'/image/'+id,selectOutput(){}}
const hidden=await renderToString(Vue.createSSRApp({render,data:()=>state}));assert.doesNotMatch(hidden,/<img|<video/);assert.match(hidden,/preview hidden/)
const visible=await renderToString(Vue.createSSRApp({render,data:()=>({...state,xaigen:false})}));assert.match(visible,/<img/)
assert.equal(previewHidden({role:'input'},true,true,false),true)
assert.match(src,/aria-label="Current family outputs"/)
assert.match(src,/preview hidden/)
assert.doesNotMatch(src,/Hide input stills/)
assert.doesNotMatch(src,/Hide output preview/)
})
test('cached LoRAs survive sleeping GPU and failed explicit refresh',async()=>{
const cache={image:['Klein/portrait.safetensors'],video:['motion.safetensors']};let queried=0
+4 -3
View File
@@ -91,9 +91,10 @@ test('music workflow refuses yue and yue2 while ACE graphs still build', () => {
assert.equal(existsSync(new URL('../server/assets/workflow_yue.json', import.meta.url)), false)
})
test('musicChain routes yue2 to startYue2Job and leaves yue on YuEGP', () => {
test('musicChain is YuE2-only', () => {
const source = readFileSync(new URL('../server/utils/musicChain.ts', import.meta.url), 'utf8')
assert.match(source, /engine === 'yue'\) return startYueGpJob/)
assert.match(source, /engine === 'yue2'\) return startYue2Job/)
assert.match(source, /startYue2Job/)
assert.match(source, /from '\.\/yue2'/)
assert.doesNotMatch(source, /startYueGpJob/)
assert.doesNotMatch(source, /buildMusicWorkflow/)
})